packages feed

ghc 9.12.4 → 9.14.1

raw patch · 535 files changed

+94968/−73927 lines, 535 filesdep +ghc-internaldep ~basedep ~containersdep ~ghc-bootsetup-changedPVP ok

version bump matches the API change (PVP)

Dependencies added: ghc-internal

Dependency ranges changed: base, containers, ghc-boot, ghc-boot-th, ghc-boot-th-next, ghc-heap, ghci, time

API changes (from Hackage documentation)

- GHC: [ibi_tick_index] :: InternalBreakpointId -> !Int
- GHC: [ibi_tick_mod] :: InternalBreakpointId -> !Module
- GHC: [modBreaks_breakInfo] :: ModBreaks -> IntMap CgBreakInfo
- GHC: [modBreaks_flags] :: ModBreaks -> ForeignRef BreakArray
- GHC: [ms_ghc_prim_import] :: ModSummary -> !Bool
- GHC: type BreakIndex = Int
- GHC.Builtin.Names: ioPortPrimTyConKey :: Unique
- GHC.Builtin.Names: mkBignumModule :: FastString -> Module
- GHC.Builtin.Names: mkPrimModule :: FastString -> Module
- GHC.Builtin.PrimOps: NewIOPortOp :: PrimOp
- GHC.Builtin.PrimOps: ReadIOPortOp :: PrimOp
- GHC.Builtin.PrimOps: WriteIOPortOp :: PrimOp
- GHC.Builtin.PrimOps: instance GHC.Classes.Eq GHC.Builtin.PrimOps.PrimOp
- GHC.Builtin.PrimOps: instance GHC.Classes.Eq GHC.Builtin.PrimOps.PrimOpEffect
- GHC.Builtin.PrimOps: instance GHC.Classes.Ord GHC.Builtin.PrimOps.PrimOp
- GHC.Builtin.PrimOps: instance GHC.Classes.Ord GHC.Builtin.PrimOps.PrimOpEffect
- GHC.Builtin.Types: cTupleTyConNameArity_maybe :: Name -> Maybe Arity
- GHC.Builtin.Types: filterCTuple :: RdrName -> RdrName
- GHC.Builtin.Types: isPunOcc_maybe :: Module -> OccName -> Maybe Name
- GHC.Builtin.Types: isSumTyOcc_maybe :: Module -> OccName -> Maybe Name
- GHC.Builtin.Types: isTupleTyOcc_maybe :: Module -> OccName -> Maybe Name
- GHC.Builtin.Types.Prim: ioPortPrimTyCon :: TyCon
- GHC.Builtin.Types.Prim: mkIOPortPrimTy :: Type -> Type -> Type
- GHC.ByteCode.Asm: assembleOneBCO :: Interp -> Profile -> ProtoBCO Name -> IO UnlinkedBCO
- GHC.ByteCode.Asm: instance GHC.Internal.Base.Applicative GHC.ByteCode.Asm.Assembler
- GHC.ByteCode.Asm: instance GHC.Internal.Base.Functor GHC.ByteCode.Asm.Assembler
- GHC.ByteCode.Asm: instance GHC.Internal.Base.Monad GHC.ByteCode.Asm.Assembler
- GHC.ByteCode.Instr: [protoBCOFFIs] :: ProtoBCO a -> [FFIInfo]
- GHC.ByteCode.Instr: instance GHC.Classes.Eq GHC.ByteCode.Instr.LocalLabel
- GHC.ByteCode.Instr: instance GHC.Classes.Ord GHC.ByteCode.Instr.LocalLabel
- GHC.ByteCode.Linker: nameToCLabel :: Name -> String -> FastString
- GHC.ByteCode.Types: [bc_ffis] :: CompiledByteCode -> [FFIInfo]
- GHC.ByteCode.Types: [modBreaks_breakInfo] :: ModBreaks -> IntMap CgBreakInfo
- GHC.ByteCode.Types: [modBreaks_flags] :: ModBreaks -> ForeignRef BreakArray
- GHC.ByteCode.Types: data CCostCentre
- GHC.ByteCode.Types: emptyModBreaks :: ModBreaks
- GHC.ByteCode.Types: fromSizedSeq :: SizedSeq a -> FlatBag a
- GHC.ByteCode.Types: instance Control.DeepSeq.NFData GHC.ByteCode.Types.FFIInfo
- GHC.ByteCode.Types: instance GHC.Classes.Eq GHC.ByteCode.Types.ByteOff
- GHC.ByteCode.Types: instance GHC.Classes.Eq GHC.ByteCode.Types.HalfWord
- GHC.ByteCode.Types: instance GHC.Classes.Eq GHC.ByteCode.Types.NativeCallType
- GHC.ByteCode.Types: instance GHC.Classes.Eq GHC.ByteCode.Types.RegBitmap
- GHC.ByteCode.Types: instance GHC.Classes.Eq GHC.ByteCode.Types.WordOff
- GHC.ByteCode.Types: instance GHC.Classes.Ord GHC.ByteCode.Types.ByteOff
- GHC.ByteCode.Types: instance GHC.Classes.Ord GHC.ByteCode.Types.HalfWord
- GHC.ByteCode.Types: instance GHC.Classes.Ord GHC.ByteCode.Types.RegBitmap
- GHC.ByteCode.Types: instance GHC.Classes.Ord GHC.ByteCode.Types.WordOff
- GHC.ByteCode.Types: instance GHC.Utils.Outputable.Outputable GHC.ByteCode.Types.CgBreakInfo
- GHC.ByteCode.Types: newtype FFIInfo
- GHC.ByteCode.Types: type BreakIndex = Int
- GHC.Cmm: instance GHC.Classes.Eq GHC.Cmm.CmmInfoTable
- GHC.Cmm: instance GHC.Classes.Eq GHC.Cmm.ProfilingInfo
- GHC.Cmm: instance GHC.Classes.Eq GHC.Cmm.SectionProtection
- GHC.Cmm: instance GHC.Classes.Ord GHC.Cmm.CmmInfoTable
- GHC.Cmm: instance GHC.Classes.Ord GHC.Cmm.ProfilingInfo
- GHC.Cmm.CLabel: instance GHC.Classes.Eq GHC.Cmm.CLabel.CLabel
- GHC.Cmm.CLabel: instance GHC.Classes.Eq GHC.Cmm.CLabel.CmmLabelInfo
- GHC.Cmm.CLabel: instance GHC.Classes.Eq GHC.Cmm.CLabel.ConInfoTableLocation
- GHC.Cmm.CLabel: instance GHC.Classes.Eq GHC.Cmm.CLabel.DynamicLinkerLabelInfo
- GHC.Cmm.CLabel: instance GHC.Classes.Eq GHC.Cmm.CLabel.ForeignLabelSource
- GHC.Cmm.CLabel: instance GHC.Classes.Eq GHC.Cmm.CLabel.IdLabelInfo
- GHC.Cmm.CLabel: instance GHC.Classes.Eq GHC.Cmm.CLabel.InfoProvEnt
- GHC.Cmm.CLabel: instance GHC.Classes.Eq GHC.Cmm.CLabel.ModuleLabelKind
- GHC.Cmm.CLabel: instance GHC.Classes.Eq GHC.Cmm.CLabel.NeedExternDecl
- GHC.Cmm.CLabel: instance GHC.Classes.Eq GHC.Cmm.CLabel.RtsLabelInfo
- GHC.Cmm.CLabel: instance GHC.Classes.Eq GHC.Cmm.CLabel.TickyIdInfo
- GHC.Cmm.CLabel: instance GHC.Classes.Ord GHC.Cmm.CLabel.CLabel
- GHC.Cmm.CLabel: instance GHC.Classes.Ord GHC.Cmm.CLabel.CmmLabelInfo
- GHC.Cmm.CLabel: instance GHC.Classes.Ord GHC.Cmm.CLabel.ConInfoTableLocation
- GHC.Cmm.CLabel: instance GHC.Classes.Ord GHC.Cmm.CLabel.DynamicLinkerLabelInfo
- GHC.Cmm.CLabel: instance GHC.Classes.Ord GHC.Cmm.CLabel.ForeignLabelSource
- GHC.Cmm.CLabel: instance GHC.Classes.Ord GHC.Cmm.CLabel.IdLabelInfo
- GHC.Cmm.CLabel: instance GHC.Classes.Ord GHC.Cmm.CLabel.InfoProvEnt
- GHC.Cmm.CLabel: instance GHC.Classes.Ord GHC.Cmm.CLabel.ModuleLabelKind
- GHC.Cmm.CLabel: instance GHC.Classes.Ord GHC.Cmm.CLabel.NeedExternDecl
- GHC.Cmm.CLabel: instance GHC.Classes.Ord GHC.Cmm.CLabel.RtsLabelInfo
- GHC.Cmm.CLabel: instance GHC.Classes.Ord GHC.Cmm.CLabel.TickyIdInfo
- GHC.Cmm.Dataflow.Label: instance GHC.Classes.Eq GHC.Cmm.Dataflow.Label.Label
- GHC.Cmm.Dataflow.Label: instance GHC.Classes.Eq GHC.Cmm.Dataflow.Label.LabelSet
- GHC.Cmm.Dataflow.Label: instance GHC.Classes.Eq v => GHC.Classes.Eq (GHC.Cmm.Dataflow.Label.LabelMap v)
- GHC.Cmm.Dataflow.Label: instance GHC.Classes.Ord GHC.Cmm.Dataflow.Label.Label
- GHC.Cmm.Dataflow.Label: instance GHC.Classes.Ord GHC.Cmm.Dataflow.Label.LabelSet
- GHC.Cmm.Dataflow.Label: instance GHC.Classes.Ord v => GHC.Classes.Ord (GHC.Cmm.Dataflow.Label.LabelMap v)
- GHC.Cmm.DebugBlock: instance GHC.Classes.Eq GHC.Cmm.DebugBlock.UnwindExpr
- GHC.Cmm.Dominators: instance GHC.Classes.Eq GHC.Cmm.Dominators.DominatorSet
- GHC.Cmm.Dominators: instance GHC.Classes.Eq GHC.Cmm.Dominators.RPNum
- GHC.Cmm.Dominators: instance GHC.Classes.Ord GHC.Cmm.Dominators.RPNum
- GHC.Cmm.Expr: instance (GHC.Classes.Ord r, GHC.Cmm.Expr.UserOfRegs r GHC.Cmm.Reg.CmmReg) => GHC.Cmm.Expr.UserOfRegs r GHC.Cmm.Expr.CmmExpr
- GHC.Cmm.Expr: instance GHC.Classes.Eq GHC.Cmm.Expr.AlignmentSpec
- GHC.Cmm.Expr: instance GHC.Classes.Eq GHC.Cmm.Expr.Area
- GHC.Cmm.Expr: instance GHC.Classes.Eq GHC.Cmm.Expr.CmmExpr
- GHC.Cmm.Expr: instance GHC.Classes.Eq GHC.Cmm.Expr.CmmLit
- GHC.Cmm.Expr: instance GHC.Classes.Ord GHC.Cmm.Expr.AlignmentSpec
- GHC.Cmm.Expr: instance GHC.Classes.Ord GHC.Cmm.Expr.Area
- GHC.Cmm.Expr: instance GHC.Classes.Ord r => GHC.Cmm.Expr.DefinerOfRegs r r
- GHC.Cmm.Expr: instance GHC.Classes.Ord r => GHC.Cmm.Expr.UserOfRegs r r
- GHC.Cmm.Graph: instance GHC.Classes.Eq GHC.Cmm.Graph.Transfer
- GHC.Cmm.Info.Build: instance GHC.Classes.Eq GHC.Cmm.Info.Build.CAFfyLabel
- GHC.Cmm.Info.Build: instance GHC.Classes.Eq GHC.Cmm.Info.Build.SRTEntry
- GHC.Cmm.Info.Build: instance GHC.Classes.Eq GHC.Cmm.Info.Build.SomeLabel
- GHC.Cmm.Info.Build: instance GHC.Classes.Ord GHC.Cmm.Info.Build.CAFfyLabel
- GHC.Cmm.Info.Build: instance GHC.Classes.Ord GHC.Cmm.Info.Build.SRTEntry
- GHC.Cmm.Info.Build: instance GHC.Classes.Ord GHC.Cmm.Info.Build.SomeLabel
- GHC.Cmm.InitFini: isInitOrFiniSection :: SectionType -> Maybe InitOrFini
- GHC.Cmm.MachOp: instance GHC.Classes.Eq GHC.Cmm.MachOp.AtomicMachOp
- GHC.Cmm.MachOp: instance GHC.Classes.Eq GHC.Cmm.MachOp.CallishMachOp
- GHC.Cmm.MachOp: instance GHC.Classes.Eq GHC.Cmm.MachOp.FMASign
- GHC.Cmm.MachOp: instance GHC.Classes.Eq GHC.Cmm.MachOp.MachOp
- GHC.Cmm.MachOp: instance GHC.Classes.Eq GHC.Cmm.MachOp.MemoryOrdering
- GHC.Cmm.MachOp: instance GHC.Classes.Ord GHC.Cmm.MachOp.MemoryOrdering
- GHC.Cmm.Node: instance (GHC.Classes.Ord r, GHC.Cmm.Expr.UserOfRegs r GHC.Cmm.Reg.CmmReg) => GHC.Cmm.Expr.UserOfRegs r GHC.Cmm.Node.ForeignTarget
- GHC.Cmm.Node: instance GHC.Classes.Eq (GHC.Cmm.Node.CmmNode e x)
- GHC.Cmm.Node: instance GHC.Classes.Eq GHC.Cmm.Node.CmmReturnInfo
- GHC.Cmm.Node: instance GHC.Classes.Eq GHC.Cmm.Node.CmmTickScope
- GHC.Cmm.Node: instance GHC.Classes.Eq GHC.Cmm.Node.Convention
- GHC.Cmm.Node: instance GHC.Classes.Eq GHC.Cmm.Node.ForeignConvention
- GHC.Cmm.Node: instance GHC.Classes.Eq GHC.Cmm.Node.ForeignTarget
- GHC.Cmm.Node: instance GHC.Classes.Ord GHC.Cmm.Node.CmmTickScope
- GHC.Cmm.Reducibility: instance GHC.Classes.Eq GHC.Cmm.Reducibility.Reducibility
- GHC.Cmm.Reg: instance GHC.Classes.Eq GHC.Cmm.Reg.CmmReg
- GHC.Cmm.Reg: instance GHC.Classes.Eq GHC.Cmm.Reg.GlobalArgRegs
- GHC.Cmm.Reg: instance GHC.Classes.Eq GHC.Cmm.Reg.GlobalReg
- GHC.Cmm.Reg: instance GHC.Classes.Eq GHC.Cmm.Reg.GlobalRegUse
- GHC.Cmm.Reg: instance GHC.Classes.Eq GHC.Cmm.Reg.LocalReg
- GHC.Cmm.Reg: instance GHC.Classes.Ord GHC.Cmm.Reg.CmmReg
- GHC.Cmm.Reg: instance GHC.Classes.Ord GHC.Cmm.Reg.GlobalArgRegs
- GHC.Cmm.Reg: instance GHC.Classes.Ord GHC.Cmm.Reg.GlobalReg
- GHC.Cmm.Reg: instance GHC.Classes.Ord GHC.Cmm.Reg.GlobalRegUse
- GHC.Cmm.Reg: instance GHC.Classes.Ord GHC.Cmm.Reg.LocalReg
- GHC.Cmm.Switch: instance GHC.Classes.Eq GHC.Cmm.Switch.SwitchTargets
- GHC.Cmm.Type: instance GHC.Classes.Eq GHC.Cmm.Type.CmmCat
- GHC.Cmm.Type: instance GHC.Classes.Eq GHC.Cmm.Type.ForeignHint
- GHC.Cmm.Type: instance GHC.Classes.Eq GHC.Cmm.Type.Width
- GHC.Cmm.Type: instance GHC.Classes.Ord GHC.Cmm.Type.Width
- GHC.CmmToAsm.AArch64.Cond: instance GHC.Classes.Eq GHC.CmmToAsm.AArch64.Cond.Cond
- GHC.CmmToAsm.AArch64.Instr: instance GHC.Classes.Eq GHC.CmmToAsm.AArch64.Instr.DMBISHFlags
- GHC.CmmToAsm.AArch64.Instr: instance GHC.Classes.Eq GHC.CmmToAsm.AArch64.Instr.ExtMode
- GHC.CmmToAsm.AArch64.Instr: instance GHC.Classes.Eq GHC.CmmToAsm.AArch64.Instr.Operand
- GHC.CmmToAsm.AArch64.Instr: instance GHC.Classes.Eq GHC.CmmToAsm.AArch64.Instr.ShiftMode
- GHC.CmmToAsm.AArch64.Instr: instance GHC.Classes.Eq GHC.CmmToAsm.AArch64.Instr.Target
- GHC.CmmToAsm.AArch64.Instr: instance GHC.Classes.Ord GHC.CmmToAsm.AArch64.Instr.Target
- GHC.CmmToAsm.AArch64.Regs: instance GHC.Classes.Eq GHC.CmmToAsm.AArch64.Regs.AddrMode
- GHC.CmmToAsm.AArch64.Regs: instance GHC.Classes.Eq GHC.CmmToAsm.AArch64.Regs.Imm
- GHC.CmmToAsm.BlockLayout: instance GHC.Classes.Eq GHC.CmmToAsm.BlockLayout.BlockChain
- GHC.CmmToAsm.BlockLayout: instance GHC.Classes.Ord GHC.CmmToAsm.BlockLayout.BlockChain
- GHC.CmmToAsm.CFG: instance GHC.Classes.Eq GHC.CmmToAsm.CFG.BranchInfo
- GHC.CmmToAsm.CFG: instance GHC.Classes.Eq GHC.CmmToAsm.CFG.CfgEdge
- GHC.CmmToAsm.CFG: instance GHC.Classes.Eq GHC.CmmToAsm.CFG.EdgeInfo
- GHC.CmmToAsm.CFG: instance GHC.Classes.Eq GHC.CmmToAsm.CFG.EdgeWeight
- GHC.CmmToAsm.CFG: instance GHC.Classes.Eq GHC.CmmToAsm.CFG.TransitionSource
- GHC.CmmToAsm.CFG: instance GHC.Classes.Ord GHC.CmmToAsm.CFG.CfgEdge
- GHC.CmmToAsm.CFG: instance GHC.Classes.Ord GHC.CmmToAsm.CFG.EdgeWeight
- GHC.CmmToAsm.Dwarf.Types: instance GHC.Classes.Eq GHC.CmmToAsm.Dwarf.Types.DwarfAbbrev
- GHC.CmmToAsm.Format: instance GHC.Classes.Eq GHC.CmmToAsm.Format.Format
- GHC.CmmToAsm.Format: instance GHC.Classes.Eq GHC.CmmToAsm.Format.ScalarFormat
- GHC.CmmToAsm.Format: instance GHC.Classes.Ord GHC.CmmToAsm.Format.Format
- GHC.CmmToAsm.Format: instance GHC.Classes.Ord GHC.CmmToAsm.Format.ScalarFormat
- GHC.CmmToAsm.PIC: instance GHC.Classes.Eq GHC.CmmToAsm.PIC.ReferenceKind
- GHC.CmmToAsm.PPC.Cond: instance GHC.Classes.Eq GHC.CmmToAsm.PPC.Cond.Cond
- GHC.CmmToAsm.Ppr: pprCOFFComdatKey :: IsLine doc => Platform -> CLabel -> doc
- GHC.CmmToAsm.RV64.Cond: instance GHC.Classes.Eq GHC.CmmToAsm.RV64.Cond.Cond
- GHC.CmmToAsm.RV64.Instr: instance GHC.Classes.Eq GHC.CmmToAsm.RV64.Instr.Operand
- GHC.CmmToAsm.RV64.Regs: instance GHC.Classes.Eq GHC.CmmToAsm.RV64.Regs.AddrMode
- GHC.CmmToAsm.RV64.Regs: instance GHC.Classes.Eq GHC.CmmToAsm.RV64.Regs.Imm
- GHC.CmmToAsm.Reg.Graph.Base: instance GHC.Classes.Eq GHC.CmmToAsm.Reg.Graph.Base.Reg
- GHC.CmmToAsm.Reg.Graph.Base: instance GHC.Classes.Eq GHC.CmmToAsm.Reg.Graph.Base.RegClass
- GHC.CmmToAsm.Reg.Graph.Base: instance GHC.Classes.Eq GHC.CmmToAsm.Reg.Graph.Base.RegSub
- GHC.CmmToAsm.Reg.Graph.Base: instance GHC.Classes.Ord GHC.CmmToAsm.Reg.Graph.Base.RegSub
- GHC.CmmToAsm.Reg.Linear.Base: IgnoreFormat :: a -> IgnoreFormat a
- GHC.CmmToAsm.Reg.Linear.Base: Loc :: {-# UNPACK #-} !VLoc -> Format -> Loc
- GHC.CmmToAsm.Reg.Linear.Base: [locWithFormat_format] :: Loc -> Format
- GHC.CmmToAsm.Reg.Linear.Base: [locWithFormat_loc] :: Loc -> {-# UNPACK #-} !VLoc
- GHC.CmmToAsm.Reg.Linear.Base: data VLoc
- GHC.CmmToAsm.Reg.Linear.Base: instance GHC.Classes.Eq (GHC.CmmToAsm.Reg.Linear.Base.IgnoreFormat GHC.CmmToAsm.Reg.Linear.Base.Loc)
- GHC.CmmToAsm.Reg.Linear.Base: instance GHC.Classes.Eq GHC.CmmToAsm.Reg.Linear.Base.ReadingOrWriting
- GHC.CmmToAsm.Reg.Linear.Base: instance GHC.Classes.Eq GHC.CmmToAsm.Reg.Linear.Base.VLoc
- GHC.CmmToAsm.Reg.Linear.Base: instance GHC.Classes.Ord (GHC.CmmToAsm.Reg.Linear.Base.IgnoreFormat GHC.CmmToAsm.Reg.Linear.Base.Loc)
- GHC.CmmToAsm.Reg.Linear.Base: instance GHC.Classes.Ord GHC.CmmToAsm.Reg.Linear.Base.ReadingOrWriting
- GHC.CmmToAsm.Reg.Linear.Base: instance GHC.Classes.Ord GHC.CmmToAsm.Reg.Linear.Base.VLoc
- GHC.CmmToAsm.Reg.Linear.Base: instance GHC.Internal.Show.Show GHC.CmmToAsm.Reg.Linear.Base.VLoc
- GHC.CmmToAsm.Reg.Linear.Base: instance GHC.Utils.Outputable.Outputable GHC.CmmToAsm.Reg.Linear.Base.VLoc
- GHC.CmmToAsm.Reg.Linear.Base: newtype IgnoreFormat a
- GHC.CmmToAsm.Reg.Regs: Regs :: UniqSet RegWithFormat -> Regs
- GHC.CmmToAsm.Reg.Regs: [getRegs] :: Regs -> UniqSet RegWithFormat
- GHC.CmmToAsm.Reg.Regs: addRegMaxFmt :: Regs -> RegWithFormat -> Regs
- GHC.CmmToAsm.Reg.Regs: addRegsMaxFmt :: Regs -> [RegWithFormat] -> Regs
- GHC.CmmToAsm.Reg.Regs: elemRegs :: Reg -> Regs -> Bool
- GHC.CmmToAsm.Reg.Regs: instance GHC.Classes.Eq GHC.CmmToAsm.Reg.Regs.Regs
- GHC.CmmToAsm.Reg.Regs: instance GHC.Utils.Outputable.Outputable GHC.CmmToAsm.Reg.Regs.Regs
- GHC.CmmToAsm.Reg.Regs: intersectRegsMaxFmt :: Regs -> Regs -> Regs
- GHC.CmmToAsm.Reg.Regs: lookupReg :: Reg -> Regs -> Maybe Format
- GHC.CmmToAsm.Reg.Regs: mapRegs :: (Reg -> Reg) -> Regs -> Regs
- GHC.CmmToAsm.Reg.Regs: minusCoveredRegs :: Regs -> Regs -> Regs
- GHC.CmmToAsm.Reg.Regs: minusRegs :: Regs -> Regs -> Regs
- GHC.CmmToAsm.Reg.Regs: mkRegsMaxFmt :: [RegWithFormat] -> Regs
- GHC.CmmToAsm.Reg.Regs: newtype Regs
- GHC.CmmToAsm.Reg.Regs: noRegs :: Regs
- GHC.CmmToAsm.Reg.Regs: shrinkingRegs :: Regs -> Regs -> Regs
- GHC.CmmToAsm.Reg.Regs: unionManyRegsMaxFmt :: [Regs] -> Regs
- GHC.CmmToAsm.Reg.Regs: unionRegsMaxFmt :: Regs -> Regs -> Regs
- GHC.CmmToAsm.Wasm.Types: instance GHC.Classes.Eq GHC.CmmToAsm.Wasm.Types.SomeWasmType
- GHC.CmmToAsm.Wasm.Types: instance GHC.Classes.Eq GHC.CmmToAsm.Wasm.Types.SymKind
- GHC.CmmToAsm.Wasm.Types: instance GHC.Classes.Eq GHC.CmmToAsm.Wasm.Types.SymName
- GHC.CmmToAsm.Wasm.Types: instance GHC.Classes.Ord GHC.CmmToAsm.Wasm.Types.SymName
- GHC.CmmToAsm.X86.CodeGen: instance GHC.Classes.Eq GHC.CmmToAsm.X86.CodeGen.Padding
- GHC.CmmToAsm.X86.CodeGen: instance GHC.Classes.Eq GHC.CmmToAsm.X86.CodeGen.StackRef
- GHC.CmmToAsm.X86.CodeGen: instance GHC.Classes.Ord GHC.CmmToAsm.X86.CodeGen.Padding
- GHC.CmmToAsm.X86.CodeGen: instance GHC.Classes.Ord GHC.CmmToAsm.X86.CodeGen.StackRef
- GHC.CmmToAsm.X86.Cond: instance GHC.Classes.Eq GHC.CmmToAsm.X86.Cond.Cond
- GHC.CmmToAsm.X86.Instr: instance GHC.Classes.Eq GHC.CmmToAsm.X86.Instr.MinMaxType
- GHC.CmmToAsm.X86.Instr: instance GHC.Classes.Eq GHC.CmmToAsm.X86.Instr.MinOrMax
- GHC.CmmToC: instance GHC.Classes.Eq GHC.CmmToC.Fixity
- GHC.CmmToLlvm.CodeGen: instance GHC.Classes.Eq GHC.CmmToLlvm.CodeGen.Signage
- GHC.CmmToLlvm.Version.Type: instance GHC.Classes.Eq GHC.CmmToLlvm.Version.Type.LlvmVersion
- GHC.CmmToLlvm.Version.Type: instance GHC.Classes.Ord GHC.CmmToLlvm.Version.Type.LlvmVersion
- GHC.Core: instance GHC.Classes.Eq GHC.Core.AltCon
- GHC.Core: instance GHC.Classes.Eq GHC.Core.UnfoldingCache
- GHC.Core: instance GHC.Classes.Eq GHC.Core.UnfoldingGuidance
- GHC.Core: instance GHC.Classes.Ord GHC.Core.AltCon
- GHC.Core: unfoldingTemplate :: Unfolding -> CoreExpr
- GHC.Core.Class: instance GHC.Classes.Eq GHC.Core.Class.Class
- GHC.Core.Coercion: [ch_hetero_kind] :: CoercionHole -> Bool
- GHC.Core.Coercion: hasCoercionHoleCo :: Coercion -> Bool
- GHC.Core.Coercion: hasCoercionHoleTy :: Type -> Bool
- GHC.Core.Coercion: hasThisCoercionHoleTy :: Type -> CoercionHole -> Bool
- GHC.Core.Coercion: mkNomPrimEqPred :: Kind -> Type -> Type -> Type
- GHC.Core.Coercion: mkPrimEqPred :: Type -> Type -> Type
- GHC.Core.Coercion: mkPrimEqPredRole :: Role -> Type -> Type -> PredType
- GHC.Core.Coercion: mkReprPrimEqPred :: Type -> Type -> Type
- GHC.Core.Coercion: substForAllCoBndrUsingLC :: SwapFlag -> (Coercion -> Coercion) -> LiftingContext -> TyCoVar -> Coercion -> (LiftingContext, TyCoVar, Coercion)
- GHC.Core.Coercion.Axiom: instance GHC.Classes.Eq (GHC.Core.Coercion.Axiom.CoAxiom br)
- GHC.Core.Coercion.Axiom: instance GHC.Classes.Eq GHC.Core.Coercion.Axiom.CoAxiomRule
- GHC.Core.ConLike: conLikesWithFields :: [ConLike] -> [FieldLabelString] -> ([ConLike], [ConLike])
- GHC.Core.ConLike: instance GHC.Classes.Eq GHC.Core.ConLike.ConLike
- GHC.Core.DataCon: HsBang :: SrcUnpackedness -> SrcStrictness -> HsBang
- GHC.Core.DataCon: [dcr_bangs] :: DataConRep -> [HsImplBang]
- GHC.Core.DataCon: [dcr_stricts] :: DataConRep -> [StrictnessMark]
- GHC.Core.DataCon: data HsBang
- GHC.Core.DataCon: dataConUserTyVarsNeedWrapper :: DataCon -> Bool
- GHC.Core.DataCon: instance GHC.Classes.Eq GHC.Core.DataCon.DataCon
- GHC.Core.DataCon: instance GHC.Classes.Eq GHC.Core.DataCon.StrictnessMark
- GHC.Core.DataCon: instance GHC.Utils.Outputable.Outputable Language.Haskell.Syntax.Basic.HsBang
- GHC.Core.DataCon: mkHsSrcBang :: SourceText -> SrcUnpackedness -> SrcStrictness -> HsSrcBang
- GHC.Core.Lint: instance GHC.Classes.Eq GHC.Core.Lint.StaticPtrCheck
- GHC.Core.Map.Expr: instance GHC.Classes.Eq (GHC.Core.Map.Type.DeBruijn GHC.Core.CoreAlt)
- GHC.Core.Map.Expr: instance GHC.Classes.Eq (GHC.Core.Map.Type.DeBruijn GHC.Core.CoreExpr)
- GHC.Core.Map.Type: instance GHC.Classes.Eq (GHC.Core.Map.Type.DeBruijn GHC.Core.TyCo.Rep.Coercion)
- GHC.Core.Map.Type: instance GHC.Classes.Eq (GHC.Core.Map.Type.DeBruijn GHC.Core.TyCo.Rep.Type)
- GHC.Core.Map.Type: instance GHC.Classes.Eq (GHC.Core.Map.Type.DeBruijn GHC.Types.Var.Var)
- GHC.Core.Map.Type: instance GHC.Classes.Eq (GHC.Core.Map.Type.DeBruijn a) => GHC.Classes.Eq (GHC.Core.Map.Type.DeBruijn (GHC.Internal.Maybe.Maybe a))
- GHC.Core.Map.Type: instance GHC.Classes.Eq (GHC.Core.Map.Type.DeBruijn a) => GHC.Classes.Eq (GHC.Core.Map.Type.DeBruijn [a])
- GHC.Core.Multiplicity: instance GHC.Classes.Eq GHC.Core.Multiplicity.IsSubmult
- GHC.Core.Opt.Arity: instance GHC.Classes.Eq GHC.Core.Opt.Arity.ArityType
- GHC.Core.Opt.Arity: instance GHC.Classes.Eq GHC.Core.Opt.Arity.Cost
- GHC.Core.Opt.SetLevels: instance GHC.Classes.Eq GHC.Core.Opt.SetLevels.Level
- GHC.Core.Opt.Simplify.Env: getSubst :: SimplEnv -> Subst
- GHC.Core.Opt.Simplify.Env: sePedanticBottoms :: SimplEnv -> Bool
- GHC.Core.Opt.Simplify.Env: smPedanticBottoms :: SimplMode -> Bool
- GHC.Core.Opt.Simplify.Utils: CastBy :: OutCoercion -> ArgSpec
- GHC.Core.Opt.Simplify.Utils: TryInlining :: RewriteCall
- GHC.Core.Opt.Simplify.Utils: TryNothing :: RewriteCall
- GHC.Core.Opt.Simplify.Utils: TryRules :: FullArgCount -> [CoreRule] -> RewriteCall
- GHC.Core.Opt.Simplify.Utils: [ai_rewrite] :: ArgInfo -> RewriteCall
- GHC.Core.Opt.Simplify.Utils: addCastTo :: ArgInfo -> OutCoercion -> ArgInfo
- GHC.Core.Opt.Simplify.Utils: argInfoAppArgs :: [ArgSpec] -> [OutExpr]
- GHC.Core.Opt.Simplify.Utils: data RewriteCall
- GHC.Core.Opt.Simplify.Utils: pushSimplifiedRevArgs :: SimplEnv -> [ArgSpec] -> SimplCont -> SimplCont
- GHC.Core.Opt.Stats: instance GHC.Classes.Eq GHC.Core.Opt.Stats.Tick
- GHC.Core.Opt.Stats: instance GHC.Classes.Ord GHC.Core.Opt.Stats.Tick
- GHC.Core.Opt.WorkWrap.Utils: instance GHC.Classes.Eq GHC.Core.Opt.WorkWrap.Utils.IsRecDataConResult
- GHC.Core.PatSyn: instance GHC.Classes.Eq GHC.Core.PatSyn.PatSyn
- GHC.Core.Predicate: instance GHC.Classes.Eq GHC.Core.Predicate.EqRel
- GHC.Core.Predicate: instance GHC.Classes.Ord GHC.Core.Predicate.EqRel
- GHC.Core.Predicate: isEqPrimPred :: PredType -> Bool
- GHC.Core.Predicate: isEvVar :: Var -> Bool
- GHC.Core.Predicate: isEvVarType :: Type -> Bool
- GHC.Core.Predicate: isIPLikePred :: Type -> Bool
- GHC.Core.Predicate: isNomEqPred :: PredType -> Bool
- GHC.Core.Predicate: isReprEqPrimPred :: PredType -> Bool
- GHC.Core.Predicate: mentionsIP :: (Type -> Bool) -> (Type -> Bool) -> Class -> [Type] -> Bool
- GHC.Core.Predicate: mkNomPrimEqPred :: Kind -> Type -> Type -> Type
- GHC.Core.Predicate: mkPrimEqPred :: Type -> Type -> Type
- GHC.Core.Predicate: mkPrimEqPredRole :: Role -> Type -> Type -> PredType
- GHC.Core.Predicate: mkReprPrimEqPred :: Type -> Type -> Type
- GHC.Core.Subst: getSubstInScope :: Subst -> InScopeSet
- GHC.Core.TyCo.Compare: instance GHC.Classes.Eq GHC.Core.TyCo.Compare.TypeOrdering
- GHC.Core.TyCo.Compare: instance GHC.Classes.Ord GHC.Core.TyCo.Compare.TypeOrdering
- GHC.Core.TyCo.FVs: scopedSort :: [TyCoVar] -> [TyCoVar]
- GHC.Core.TyCo.FVs: tyCoVarsOfTypeWellScoped :: Type -> [TyVar]
- GHC.Core.TyCo.FVs: tyCoVarsOfTypesWellScoped :: [Type] -> [TyVar]
- GHC.Core.TyCo.Rep: [ch_hetero_kind] :: CoercionHole -> Bool
- GHC.Core.TyCo.Rep: instance GHC.Classes.Eq GHC.Core.TyCo.Rep.CoSel
- GHC.Core.TyCo.Rep: instance GHC.Classes.Eq GHC.Core.TyCo.Rep.FunSel
- GHC.Core.TyCo.Rep: instance GHC.Classes.Eq GHC.Core.TyCo.Rep.TyLit
- GHC.Core.TyCo.Rep: instance GHC.Classes.Eq GHC.Core.TyCo.Rep.UnivCoProvenance
- GHC.Core.TyCo.Rep: instance GHC.Classes.Ord GHC.Core.TyCo.Rep.CoSel
- GHC.Core.TyCo.Rep: instance GHC.Classes.Ord GHC.Core.TyCo.Rep.FunSel
- GHC.Core.TyCo.Rep: instance GHC.Classes.Ord GHC.Core.TyCo.Rep.UnivCoProvenance
- GHC.Core.TyCo.Rep: isHeteroKindCoHole :: CoercionHole -> Bool
- GHC.Core.TyCo.Subst: getSubstInScope :: Subst -> InScopeSet
- GHC.Core.TyCon: instance GHC.Classes.Eq GHC.Core.TyCon.Injectivity
- GHC.Core.TyCon: instance GHC.Classes.Eq GHC.Core.TyCon.PrimElemRep
- GHC.Core.TyCon: instance GHC.Classes.Eq GHC.Core.TyCon.PrimOrVoidRep
- GHC.Core.TyCon: instance GHC.Classes.Eq GHC.Core.TyCon.PrimRep
- GHC.Core.TyCon: instance GHC.Classes.Eq GHC.Core.TyCon.TyCon
- GHC.Core.TyCon: instance GHC.Classes.Ord GHC.Core.TyCon.PrimElemRep
- GHC.Core.TyCon: instance GHC.Classes.Ord GHC.Core.TyCon.PrimOrVoidRep
- GHC.Core.TyCon: instance GHC.Classes.Ord GHC.Core.TyCon.PrimRep
- GHC.Core.TyCon: isDataTyCon :: TyCon -> Bool
- GHC.Core.TyCon: isGenInjAlgRhs :: AlgTyConRhs -> Bool
- GHC.Core.TyCon: tyConAlgDataCons_maybe :: TyCon -> Maybe [DataCon]
- GHC.Core.TyCon: tyConSingleAlgDataCon_maybe :: TyCon -> Maybe DataCon
- GHC.Core.Type: getSubstInScope :: Subst -> InScopeSet
- GHC.Core.Type: invisibleTyBndrCount :: Type -> Int
- GHC.Core.Type: isDataFamilyAppType :: Type -> Bool
- GHC.Core.Type: isPredTy :: HasDebugCallStack => Type -> Bool
- GHC.Core.Type: scopedSort :: [TyCoVar] -> [TyCoVar]
- GHC.Core.Type: tidyForAllTyBinder :: TidyEnv -> VarBndr TyCoVar vis -> (TidyEnv, VarBndr TyCoVar vis)
- GHC.Core.Type: tidyForAllTyBinders :: TidyEnv -> [VarBndr TyCoVar vis] -> (TidyEnv, [VarBndr TyCoVar vis])
- GHC.Core.Type: tidyFreeTyCoVarX :: TidyEnv -> TyCoVar -> (TidyEnv, TyCoVar)
- GHC.Core.Type: tidyFreeTyCoVars :: TidyEnv -> [TyCoVar] -> TidyEnv
- GHC.Core.Type: tidyFreeTyCoVarsX :: TidyEnv -> [TyCoVar] -> (TidyEnv, [TyCoVar])
- GHC.Core.Type: tidyOpenType :: TidyEnv -> Type -> Type
- GHC.Core.Type: tidyOpenTypeX :: TidyEnv -> Type -> (TidyEnv, Type)
- GHC.Core.Type: tidyOpenTypes :: TidyEnv -> [Type] -> [Type]
- GHC.Core.Type: tidyOpenTypesX :: TidyEnv -> [Type] -> (TidyEnv, [Type])
- GHC.Core.Type: tidyTopType :: Type -> Type
- GHC.Core.Type: tidyTyCoVarOcc :: TidyEnv -> TyCoVar -> TyCoVar
- GHC.Core.Type: tidyType :: TidyEnv -> Type -> Type
- GHC.Core.Type: tidyTypes :: TidyEnv -> [Type] -> [Type]
- GHC.Core.Type: tidyVarBndr :: TidyEnv -> TyCoVar -> (TidyEnv, TyCoVar)
- GHC.Core.Type: tidyVarBndrs :: TidyEnv -> [TyCoVar] -> (TidyEnv, [TyCoVar])
- GHC.Core.Type: tyCoVarsOfTypeWellScoped :: Type -> [TyVar]
- GHC.Core.Type: tyCoVarsOfTypesWellScoped :: [Type] -> [TyVar]
- GHC.Core.Unify: Apart :: BindFlag
- GHC.Core.Unify: alwaysBindFun :: BindFun
- GHC.Core.Unify: flattenTys :: InScopeSet -> [Type] -> [Type]
- GHC.Core.Unify: flattenTysX :: InScopeSet -> [Type] -> ([Type], TyVarEnv (TyCon, [Type]))
- GHC.Core.Unify: instance GHC.Classes.Eq GHC.Core.Unify.BindFlag
- GHC.Core.Unify: matchBindFun :: TyCoVarSet -> BindFun
- GHC.Core.Unify: tcUnifyTyKi :: Type -> Type -> Maybe Subst
- GHC.Core.Unify: tcUnifyTyKis :: BindFun -> [Type] -> [Type] -> Maybe Subst
- GHC.Core.Unify: tcUnifyTyWithTFs :: Bool -> InScopeSet -> Type -> Type -> Maybe Subst
- GHC.Core.Unify: type BindFun = TyCoVar -> Type -> BindFlag
- GHC.CoreToIface: dehydrateCgBreakInfo :: [TyVar] -> [Maybe (Id, Word)] -> Type -> CgBreakInfo
- GHC.CoreToStg: instance GHC.Classes.Eq GHC.CoreToStg.HowBound
- GHC.CoreToStg: instance GHC.Classes.Eq GHC.CoreToStg.LetInfo
- GHC.CoreToStg.Prep: instance GHC.Classes.Eq GHC.CoreToStg.Prep.BindInfo
- GHC.CoreToStg.Prep: instance GHC.Classes.Eq GHC.CoreToStg.Prep.FloatInfo
- GHC.Data.Bag: foldBag :: (r -> r -> r) -> (a -> r) -> r -> Bag a -> r
- GHC.Data.Bool: instance GHC.Classes.Eq GHC.Data.Bool.OverridingBool
- GHC.Data.Bool: instance GHC.Classes.Ord GHC.Data.Bool.OverridingBool
- GHC.Data.BooleanFormula: And :: [LBooleanFormula a] -> BooleanFormula a
- GHC.Data.BooleanFormula: Or :: [LBooleanFormula a] -> BooleanFormula a
- GHC.Data.BooleanFormula: Parens :: LBooleanFormula a -> BooleanFormula a
- GHC.Data.BooleanFormula: Var :: a -> BooleanFormula a
- GHC.Data.BooleanFormula: data BooleanFormula a
- GHC.Data.BooleanFormula: instance GHC.Classes.Eq a => GHC.Classes.Eq (GHC.Data.BooleanFormula.BooleanFormula a)
- GHC.Data.BooleanFormula: instance GHC.Internal.Base.Functor GHC.Data.BooleanFormula.BooleanFormula
- GHC.Data.BooleanFormula: instance GHC.Internal.Data.Data.Data a => GHC.Internal.Data.Data.Data (GHC.Data.BooleanFormula.BooleanFormula a)
- GHC.Data.BooleanFormula: instance GHC.Internal.Data.Foldable.Foldable GHC.Data.BooleanFormula.BooleanFormula
- GHC.Data.BooleanFormula: instance GHC.Internal.Data.Traversable.Traversable GHC.Data.BooleanFormula.BooleanFormula
- GHC.Data.BooleanFormula: instance GHC.Utils.Outputable.OutputableBndr a => GHC.Utils.Outputable.Outputable (GHC.Data.BooleanFormula.BooleanFormula a)
- GHC.Data.BooleanFormula: mkAnd :: Eq a => [LBooleanFormula a] -> BooleanFormula a
- GHC.Data.BooleanFormula: mkFalse :: BooleanFormula a
- GHC.Data.BooleanFormula: mkOr :: Eq a => [LBooleanFormula a] -> BooleanFormula a
- GHC.Data.BooleanFormula: mkTrue :: BooleanFormula a
- GHC.Data.BooleanFormula: mkVar :: a -> BooleanFormula a
- GHC.Data.BooleanFormula: type LBooleanFormula a = LocatedL BooleanFormula a
- GHC.Data.FastString: instance GHC.Classes.Eq GHC.Data.FastString.FastString
- GHC.Data.FastString: instance GHC.Classes.Eq GHC.Data.FastString.LexicalFastString
- GHC.Data.FastString: instance GHC.Classes.Eq GHC.Data.FastString.NonDetFastString
- GHC.Data.FastString: instance GHC.Classes.Ord GHC.Data.FastString.LexicalFastString
- GHC.Data.FastString: instance GHC.Classes.Ord GHC.Data.FastString.NonDetFastString
- GHC.Data.FlatBag: fromSizedSeq :: SizedSeq a -> FlatBag a
- GHC.Data.Graph.Directed: allReachable :: Ord key => Graph node -> (node -> key) -> Map key (Set key)
- GHC.Data.Graph.Directed: allReachableCyclic :: Ord key => Graph node -> (node -> key) -> Map key (Set key)
- GHC.Data.Graph.Directed: instance GHC.Classes.Eq GHC.Data.Graph.Directed.EdgeType
- GHC.Data.Graph.Directed: instance GHC.Classes.Eq GHC.Data.Graph.Directed.Time
- GHC.Data.Graph.Directed: instance GHC.Classes.Ord GHC.Data.Graph.Directed.EdgeType
- GHC.Data.Graph.Directed: instance GHC.Classes.Ord GHC.Data.Graph.Directed.Time
- GHC.Data.Graph.Directed: instance GHC.Utils.Outputable.Outputable node => GHC.Utils.Outputable.Outputable (GHC.Data.Graph.Directed.Edge node)
- GHC.Data.Graph.Directed: instance GHC.Utils.Outputable.Outputable node => GHC.Utils.Outputable.Outputable (GHC.Data.Graph.Directed.Graph node)
- GHC.Data.Graph.Directed: reachableG :: Graph node -> node -> [node]
- GHC.Data.Graph.Inductive.Graph: instance (GHC.Data.Graph.Inductive.Graph.Graph gr, GHC.Classes.Ord a, GHC.Classes.Ord b) => GHC.Classes.Eq (GHC.Data.Graph.Inductive.Graph.OrdGr gr a b)
- GHC.Data.Graph.Inductive.Graph: instance (GHC.Data.Graph.Inductive.Graph.Graph gr, GHC.Classes.Ord a, GHC.Classes.Ord b) => GHC.Classes.Ord (GHC.Data.Graph.Inductive.Graph.OrdGr gr a b)
- GHC.Data.Graph.Inductive.Graph: instance GHC.Classes.Eq a => GHC.Classes.Eq (GHC.Data.Graph.Inductive.Graph.LPath a)
- GHC.Data.Graph.Inductive.Graph: instance GHC.Classes.Eq b => GHC.Classes.Eq (GHC.Data.Graph.Inductive.Graph.GroupEdges b)
- GHC.Data.Graph.Inductive.Graph: instance GHC.Classes.Ord a => GHC.Classes.Ord (GHC.Data.Graph.Inductive.Graph.LPath a)
- GHC.Data.Graph.Inductive.PatriciaTree: instance (GHC.Classes.Eq a, GHC.Classes.Ord b) => GHC.Classes.Eq (GHC.Data.Graph.Inductive.PatriciaTree.Gr a b)
- GHC.Data.Graph.Inductive.PatriciaTree: instance GHC.Classes.Eq a => GHC.Classes.Eq (GHC.Data.Graph.Inductive.PatriciaTree.FromListCounting a)
- GHC.Data.Graph.UnVar: instance GHC.Classes.Eq GHC.Data.Graph.UnVar.UnVarSet
- GHC.Data.Strict: instance (GHC.Classes.Eq a, GHC.Classes.Eq b) => GHC.Classes.Eq (GHC.Data.Strict.Pair a b)
- GHC.Data.Strict: instance (GHC.Classes.Ord a, GHC.Classes.Ord b) => GHC.Classes.Ord (GHC.Data.Strict.Pair a b)
- GHC.Data.Strict: instance GHC.Classes.Eq a => GHC.Classes.Eq (GHC.Data.Strict.Maybe a)
- GHC.Data.Strict: instance GHC.Classes.Ord a => GHC.Classes.Ord (GHC.Data.Strict.Maybe a)
- GHC.Data.TrieMap: instance (GHC.Classes.Eq (GHC.Data.TrieMap.Key m), GHC.Data.TrieMap.TrieMap m) => GHC.Data.TrieMap.TrieMap (GHC.Data.TrieMap.GenMap m)
- GHC.Data.TrieMap: instance (GHC.Classes.Eq (GHC.Data.TrieMap.Key m), GHC.Data.TrieMap.TrieMap m) => GHC.Internal.Data.Foldable.Foldable (GHC.Data.TrieMap.GenMap m)
- GHC.Data.TrieMap: instance GHC.Classes.Ord k => GHC.Data.TrieMap.TrieMap (Data.Map.Internal.Map k)
- GHC.Data.UnionFind: instance GHC.Classes.Eq (GHC.Data.UnionFind.Point s a)
- GHC.Data.Word64Map.Internal: instance GHC.Classes.Eq a => GHC.Classes.Eq (GHC.Data.Word64Map.Internal.Word64Map a)
- GHC.Data.Word64Map.Internal: instance GHC.Classes.Ord a => GHC.Classes.Ord (GHC.Data.Word64Map.Internal.Word64Map a)
- GHC.Data.Word64Set.Internal: instance GHC.Classes.Eq GHC.Data.Word64Set.Internal.Word64Set
- GHC.Data.Word64Set.Internal: instance GHC.Classes.Ord GHC.Data.Word64Set.Internal.Word64Set
- GHC.Driver.Backend.Internal: instance GHC.Classes.Eq GHC.Driver.Backend.Internal.BackendName
- GHC.Driver.Backpack: instance GHC.Classes.Eq GHC.Driver.Backpack.SessionType
- GHC.Driver.DynFlags: Opt_WarnBadlyStagedTypes :: WarningFlag
- GHC.Driver.DynFlags: Opt_WarnDeprecatedTypeAbstractions :: WarningFlag
- GHC.Driver.DynFlags: instance GHC.Classes.Eq GHC.Driver.DynFlags.DynLibLoader
- GHC.Driver.DynFlags: instance GHC.Classes.Eq GHC.Driver.DynFlags.DynamicTooState
- GHC.Driver.DynFlags: instance GHC.Classes.Eq GHC.Driver.DynFlags.GhcLink
- GHC.Driver.DynFlags: instance GHC.Classes.Eq GHC.Driver.DynFlags.GhcMode
- GHC.Driver.DynFlags: instance GHC.Classes.Eq GHC.Driver.DynFlags.IgnorePackageFlag
- GHC.Driver.DynFlags: instance GHC.Classes.Eq GHC.Driver.DynFlags.ModRenaming
- GHC.Driver.DynFlags: instance GHC.Classes.Eq GHC.Driver.DynFlags.PackageArg
- GHC.Driver.DynFlags: instance GHC.Classes.Eq GHC.Driver.DynFlags.PackageDBFlag
- GHC.Driver.DynFlags: instance GHC.Classes.Eq GHC.Driver.DynFlags.PackageFlag
- GHC.Driver.DynFlags: instance GHC.Classes.Eq GHC.Driver.DynFlags.PkgDbRef
- GHC.Driver.DynFlags: instance GHC.Classes.Eq GHC.Driver.DynFlags.TrustFlag
- GHC.Driver.DynFlags: instance GHC.Classes.Eq a => GHC.Classes.Eq (GHC.Driver.DynFlags.OnOff a)
- GHC.Driver.DynFlags: instance GHC.Classes.Ord GHC.Driver.DynFlags.DynamicTooState
- GHC.Driver.DynFlags: instance GHC.Internal.Show.Show GHC.Driver.DynFlags.IncludeSpecs
- GHC.Driver.DynFlags: instance GHC.Internal.Show.Show a => GHC.Internal.Show.Show (GHC.Driver.DynFlags.OnOff a)
- GHC.Driver.DynFlags: instance GHC.Utils.Outputable.Outputable a => GHC.Utils.Outputable.Outputable (GHC.Driver.DynFlags.OnOff a)
- GHC.Driver.Env: [hsc_mod_graph] :: HscEnv -> ModuleGraph
- GHC.Driver.Env: hptAllInstances :: HscEnv -> (InstEnv, [FamInst])
- GHC.Driver.Env: hptAllThings :: (HomeModInfo -> [a]) -> HscEnv -> [a]
- GHC.Driver.Env: hptAnns :: HscEnv -> Maybe (UnitId, ModuleNameWithIsBoot) -> [Annotation]
- GHC.Driver.Env: hptCompleteSigs :: HscEnv -> CompleteMatches
- GHC.Driver.Env: hptInstancesBelow :: HscEnv -> UnitId -> ModuleNameWithIsBoot -> (InstEnv, [FamInst])
- GHC.Driver.Env: hptRules :: HscEnv -> UnitId -> ModuleNameWithIsBoot -> [CoreRule]
- GHC.Driver.Env: hptSomeThingsBelowUs :: (HomeModInfo -> [a]) -> Bool -> HscEnv -> UnitId -> ModuleNameWithIsBoot -> [a]
- GHC.Driver.Env: hscUpdateHPT_lazy :: (HomePackageTable -> HomePackageTable) -> HscEnv -> HscEnv
- GHC.Driver.Env.Types: [hsc_mod_graph] :: HscEnv -> ModuleGraph
- GHC.Driver.Flags: Opt_WarnBadlyStagedTypes :: WarningFlag
- GHC.Driver.Flags: Opt_WarnDeprecatedTypeAbstractions :: WarningFlag
- GHC.Driver.Flags: instance GHC.Classes.Eq GHC.Driver.Flags.Deprecation
- GHC.Driver.Flags: instance GHC.Classes.Eq GHC.Driver.Flags.DumpFlag
- GHC.Driver.Flags: instance GHC.Classes.Eq GHC.Driver.Flags.ExtensionDeprecation
- GHC.Driver.Flags: instance GHC.Classes.Eq GHC.Driver.Flags.GeneralFlag
- GHC.Driver.Flags: instance GHC.Classes.Eq GHC.Driver.Flags.Language
- GHC.Driver.Flags: instance GHC.Classes.Eq GHC.Driver.Flags.WarningFlag
- GHC.Driver.Flags: instance GHC.Classes.Eq GHC.Driver.Flags.WarningGroup
- GHC.Driver.Flags: instance GHC.Classes.Ord GHC.Driver.Flags.Deprecation
- GHC.Driver.Flags: instance GHC.Classes.Ord GHC.Driver.Flags.WarningFlag
- GHC.Driver.Main: hscDecls :: HscEnv -> String -> IO ([TyThing], InteractiveContext)
- GHC.Driver.Main: hscDeclsWithLocation :: HscEnv -> String -> String -> Int -> IO ([TyThing], InteractiveContext)
- GHC.Driver.Make: instance GHC.Classes.Eq GHC.Driver.Make.CodeGenEnable
- GHC.Driver.Make: instance GHC.Classes.Eq GHC.Driver.Make.WorkerLimit
- GHC.Driver.Make: instance GHC.Classes.Ord GHC.Driver.Make.CodeGenEnable
- GHC.Driver.Make: instance GHC.Internal.Show.Show GHC.Driver.Make.CodeGenEnable
- GHC.Driver.Make: instance GHC.Utils.Outputable.Outputable GHC.Driver.Make.CodeGenEnable
- GHC.Driver.Phases: instance GHC.Classes.Eq GHC.Driver.Phases.Phase
- GHC.Driver.Session: Opt_WarnBadlyStagedTypes :: WarningFlag
- GHC.Driver.Session: Opt_WarnDeprecatedTypeAbstractions :: WarningFlag
- GHC.Hs: instance GHC.Classes.Eq GHC.Hs.AnnsModule
- GHC.Hs.Binds: instance GHC.Classes.Eq GHC.Hs.Binds.ActivationAnn
- GHC.Hs.Binds: instance GHC.Classes.Eq GHC.Hs.Binds.NamespaceSpecifier
- GHC.Hs.Binds: instance GHC.Internal.Data.Data.Data GHC.Hs.Binds.TcSpecPrag
- GHC.Hs.Binds: instance GHC.Internal.Data.Data.Data GHC.Hs.Binds.TcSpecPrags
- GHC.Hs.Binds: instance GHC.Utils.Outputable.Outputable (Language.Haskell.Syntax.Extension.XRec pass (Language.Haskell.Syntax.Extension.IdP pass)) => GHC.Utils.Outputable.Outputable (Language.Haskell.Syntax.Binds.RecordPatSynField pass)
- GHC.Hs.Binds: pprHsMultAnn :: forall (id :: Pass). OutputableBndrId id => HsMultAnn (GhcPass id) -> SDoc
- GHC.Hs.Decls: ActivationAnn :: EpToken "[" -> EpToken "]" -> Maybe (EpToken "~") -> Maybe EpaLocation -> ActivationAnn
- GHC.Hs.Decls: [aa_closec] :: ActivationAnn -> EpToken "]"
- GHC.Hs.Decls: [aa_openc] :: ActivationAnn -> EpToken "["
- GHC.Hs.Decls: [aa_tilde] :: ActivationAnn -> Maybe (EpToken "~")
- GHC.Hs.Decls: [aa_val] :: ActivationAnn -> Maybe EpaLocation
- GHC.Hs.Decls: [con_bndrs] :: ConDecl pass -> XRec pass (HsOuterSigTyVarBndrs pass)
- GHC.Hs.Decls: [rd_tmvs] :: RuleDecl pass -> [LRuleBndr pass]
- GHC.Hs.Decls: [rd_tyvs] :: RuleDecl pass -> Maybe [LHsTyVarBndr () (NoGhcTc pass)]
- GHC.Hs.Decls: data ActivationAnn
- GHC.Hs.Decls: instance GHC.Classes.Eq GHC.Hs.Decls.HsRuleAnn
- GHC.Hs.Decls: instance GHC.Hs.Extension.OutputableBndrId p => GHC.Utils.Outputable.Outputable (Language.Haskell.Syntax.Decls.RuleBndr (GHC.Hs.Extension.GhcPass p))
- GHC.Hs.Decls: instance GHC.Utils.Outputable.Outputable Language.Haskell.Syntax.Decls.NewOrData
- GHC.Hs.Decls: pprTyClDeclFlavour :: forall (p :: Pass). TyClDecl (GhcPass p) -> SDoc
- GHC.Hs.Doc: instance (GHC.Classes.Eq (Language.Haskell.Syntax.Extension.IdP pass), GHC.Classes.Eq a) => GHC.Classes.Eq (GHC.Hs.Doc.WithHsDocIdentifiers a pass)
- GHC.Hs.DocString: instance GHC.Classes.Eq GHC.Hs.DocString.HsDocString
- GHC.Hs.DocString: instance GHC.Classes.Eq GHC.Hs.DocString.HsDocStringChunk
- GHC.Hs.DocString: instance GHC.Classes.Eq GHC.Hs.DocString.HsDocStringDecorator
- GHC.Hs.DocString: instance GHC.Classes.Ord GHC.Hs.DocString.HsDocStringChunk
- GHC.Hs.DocString: instance GHC.Classes.Ord GHC.Hs.DocString.HsDocStringDecorator
- GHC.Hs.Dump: instance GHC.Classes.Eq GHC.Hs.Dump.BlankEpAnnotations
- GHC.Hs.Dump: instance GHC.Classes.Eq GHC.Hs.Dump.BlankSrcSpan
- GHC.Hs.Expr: EpAnnUnboundVar :: (EpToken "`", EpToken "`") -> EpToken "_" -> EpAnnUnboundVar
- GHC.Hs.Expr: [hsUnboundBackquotes] :: EpAnnUnboundVar -> (EpToken "`", EpToken "`")
- GHC.Hs.Expr: [hsUnboundHole] :: EpAnnUnboundVar -> EpToken "_"
- GHC.Hs.Expr: arrowToHsExpr :: HsArrowOf (LocatedA (HsExpr GhcRn)) GhcRn -> LocatedA (HsExpr GhcRn)
- GHC.Hs.Expr: data EpAnnUnboundVar
- GHC.Hs.Expr: instance (GHC.Hs.Extension.OutputableBndrId pl, GHC.Hs.Extension.OutputableBndrId pr, Language.Haskell.Syntax.Extension.Anno (Language.Haskell.Syntax.Expr.StmtLR (GHC.Hs.Extension.GhcPass pl) (GHC.Hs.Extension.GhcPass pr) body) GHC.Types.~ GHC.Parser.Annotation.SrcSpanAnnA, GHC.Utils.Outputable.Outputable body) => GHC.Utils.Outputable.Outputable (Language.Haskell.Syntax.Expr.StmtLR (GHC.Hs.Extension.GhcPass pl) (GHC.Hs.Extension.GhcPass pr) body)
- GHC.Hs.Expr: instance GHC.Internal.Data.Data.Data GHC.Hs.Expr.EpAnnUnboundVar
- GHC.Hs.Expr: mkRnSyntaxExpr :: Name -> SyntaxExprRn
- GHC.Hs.Expr: pprPendingSplice :: forall (p :: Pass). OutputableBndrId p => SplicePointName -> LHsExpr (GhcPass p) -> SDoc
- GHC.Hs.ImpExp: importDeclQualifiedStyle :: Maybe (EpToken "qualified") -> Maybe (EpToken "qualified") -> (Maybe (EpToken "qualified"), ImportDeclQualifiedStyle)
- GHC.Hs.ImpExp: instance GHC.Classes.Eq (Language.Haskell.Syntax.ImpExp.IEWrappedName GHC.Hs.Extension.GhcPs)
- GHC.Hs.ImpExp: instance GHC.Classes.Eq (Language.Haskell.Syntax.ImpExp.IEWrappedName GHC.Hs.Extension.GhcRn)
- GHC.Hs.ImpExp: instance GHC.Classes.Eq (Language.Haskell.Syntax.ImpExp.IEWrappedName GHC.Hs.Extension.GhcTc)
- GHC.Hs.Instances: instance GHC.Classes.Eq (Language.Haskell.Syntax.ImpExp.IE GHC.Hs.Extension.GhcPs)
- GHC.Hs.Instances: instance GHC.Classes.Eq (Language.Haskell.Syntax.ImpExp.IE GHC.Hs.Extension.GhcRn)
- GHC.Hs.Instances: instance GHC.Classes.Eq (Language.Haskell.Syntax.ImpExp.IE GHC.Hs.Extension.GhcTc)
- GHC.Hs.Instances: instance GHC.Internal.Data.Data.Data (Language.Haskell.Syntax.Binds.HsMultAnn GHC.Hs.Extension.GhcPs)
- GHC.Hs.Instances: instance GHC.Internal.Data.Data.Data (Language.Haskell.Syntax.Binds.HsMultAnn GHC.Hs.Extension.GhcRn)
- GHC.Hs.Instances: instance GHC.Internal.Data.Data.Data (Language.Haskell.Syntax.Binds.HsMultAnn GHC.Hs.Extension.GhcTc)
- GHC.Hs.Instances: instance GHC.Internal.Data.Data.Data (Language.Haskell.Syntax.Decls.RuleBndr GHC.Hs.Extension.GhcPs)
- GHC.Hs.Instances: instance GHC.Internal.Data.Data.Data (Language.Haskell.Syntax.Decls.RuleBndr GHC.Hs.Extension.GhcRn)
- GHC.Hs.Instances: instance GHC.Internal.Data.Data.Data (Language.Haskell.Syntax.Decls.RuleBndr GHC.Hs.Extension.GhcTc)
- GHC.Hs.Instances: instance GHC.Internal.Data.Data.Data (Language.Haskell.Syntax.Pat.HsConPatTyArg GHC.Hs.Extension.GhcPs)
- GHC.Hs.Instances: instance GHC.Internal.Data.Data.Data (Language.Haskell.Syntax.Pat.HsConPatTyArg GHC.Hs.Extension.GhcRn)
- GHC.Hs.Instances: instance GHC.Internal.Data.Data.Data (Language.Haskell.Syntax.Pat.HsConPatTyArg GHC.Hs.Extension.GhcTc)
- GHC.Hs.Instances: instance GHC.Internal.Data.Data.Data (Language.Haskell.Syntax.Type.ConDeclField GHC.Hs.Extension.GhcPs)
- GHC.Hs.Instances: instance GHC.Internal.Data.Data.Data (Language.Haskell.Syntax.Type.ConDeclField GHC.Hs.Extension.GhcRn)
- GHC.Hs.Instances: instance GHC.Internal.Data.Data.Data (Language.Haskell.Syntax.Type.ConDeclField GHC.Hs.Extension.GhcTc)
- GHC.Hs.Instances: instance GHC.Internal.Data.Data.Data (Language.Haskell.Syntax.Type.HsArrowOf (GHC.Parser.Annotation.LocatedA (Language.Haskell.Syntax.Expr.HsExpr GHC.Hs.Extension.GhcPs)) GHC.Hs.Extension.GhcPs)
- GHC.Hs.Instances: instance GHC.Internal.Data.Data.Data (Language.Haskell.Syntax.Type.HsArrowOf (GHC.Parser.Annotation.LocatedA (Language.Haskell.Syntax.Expr.HsExpr GHC.Hs.Extension.GhcRn)) GHC.Hs.Extension.GhcRn)
- GHC.Hs.Instances: instance GHC.Internal.Data.Data.Data (Language.Haskell.Syntax.Type.HsArrowOf (GHC.Parser.Annotation.LocatedA (Language.Haskell.Syntax.Expr.HsExpr GHC.Hs.Extension.GhcTc)) GHC.Hs.Extension.GhcTc)
- GHC.Hs.Instances: instance GHC.Internal.Data.Data.Data (Language.Haskell.Syntax.Type.HsArrowOf (GHC.Parser.Annotation.LocatedA (Language.Haskell.Syntax.Type.HsType GHC.Hs.Extension.GhcPs)) GHC.Hs.Extension.GhcPs)
- GHC.Hs.Instances: instance GHC.Internal.Data.Data.Data (Language.Haskell.Syntax.Type.HsArrowOf (GHC.Parser.Annotation.LocatedA (Language.Haskell.Syntax.Type.HsType GHC.Hs.Extension.GhcRn)) GHC.Hs.Extension.GhcRn)
- GHC.Hs.Instances: instance GHC.Internal.Data.Data.Data (Language.Haskell.Syntax.Type.HsArrowOf (GHC.Parser.Annotation.LocatedA (Language.Haskell.Syntax.Type.HsType GHC.Hs.Extension.GhcTc)) GHC.Hs.Extension.GhcTc)
- GHC.Hs.Instances: instance GHC.Internal.Data.Data.Data thing => GHC.Internal.Data.Data.Data (Language.Haskell.Syntax.Type.HsScaled GHC.Hs.Extension.GhcPs thing)
- GHC.Hs.Instances: instance GHC.Internal.Data.Data.Data thing => GHC.Internal.Data.Data.Data (Language.Haskell.Syntax.Type.HsScaled GHC.Hs.Extension.GhcRn thing)
- GHC.Hs.Instances: instance GHC.Internal.Data.Data.Data thing => GHC.Internal.Data.Data.Data (Language.Haskell.Syntax.Type.HsScaled GHC.Hs.Extension.GhcTc thing)
- GHC.Hs.Lit: instance GHC.Classes.Eq (Language.Haskell.Syntax.Extension.XXOverLit p) => GHC.Classes.Eq (Language.Haskell.Syntax.Lit.HsOverLit p)
- GHC.Hs.Lit: instance GHC.Classes.Ord (Language.Haskell.Syntax.Extension.XXOverLit p) => GHC.Classes.Ord (Language.Haskell.Syntax.Lit.HsOverLit p)
- GHC.Hs.Lit: instance GHC.Utils.Outputable.Outputable (Language.Haskell.Syntax.Lit.HsLit (GHC.Hs.Extension.GhcPass p))
- GHC.Hs.Pat: HsConPatTyArg :: !XConPatTyArg p -> HsTyPat p -> HsConPatTyArg p
- GHC.Hs.Pat: data HsConPatTyArg p
- GHC.Hs.Pat: hsConPatTyArgs :: HsConPatDetails p -> [HsConPatTyArg (NoGhcTc p)]
- GHC.Hs.Pat: instance (GHC.Utils.Outputable.Outputable arg, GHC.Utils.Outputable.Outputable (Language.Haskell.Syntax.Extension.XRec p (Language.Haskell.Syntax.Pat.HsRecField p arg)), Language.Haskell.Syntax.Extension.XRec p Language.Haskell.Syntax.Pat.RecFieldsDotDot GHC.Types.~ GHC.Parser.Annotation.LocatedE Language.Haskell.Syntax.Pat.RecFieldsDotDot) => GHC.Utils.Outputable.Outputable (Language.Haskell.Syntax.Pat.HsRecFields p arg)
- GHC.Hs.Pat: instance GHC.Utils.Outputable.Outputable (Language.Haskell.Syntax.Type.HsTyPat p) => GHC.Utils.Outputable.Outputable (Language.Haskell.Syntax.Pat.HsConPatTyArg p)
- GHC.Hs.Type: ConDeclField :: XConDeclField pass -> [LFieldOcc pass] -> LBangType pass -> Maybe (LHsDoc pass) -> ConDeclField pass
- GHC.Hs.Type: HsLinearArrow :: !XLinearArrow mult pass -> HsArrowOf mult pass
- GHC.Hs.Type: HsScaled :: HsArrow pass -> a -> HsScaled pass a
- GHC.Hs.Type: HsUnrestrictedArrow :: !XUnrestrictedArrow mult pass -> HsArrowOf mult pass
- GHC.Hs.Type: XArrow :: !XXArrow mult pass -> HsArrowOf mult pass
- GHC.Hs.Type: XConDeclField :: !XXConDeclField pass -> ConDeclField pass
- GHC.Hs.Type: [cd_fld_doc] :: ConDeclField pass -> Maybe (LHsDoc pass)
- GHC.Hs.Type: [cd_fld_ext] :: ConDeclField pass -> XConDeclField pass
- GHC.Hs.Type: [cd_fld_names] :: ConDeclField pass -> [LFieldOcc pass]
- GHC.Hs.Type: [cd_fld_type] :: ConDeclField pass -> LBangType pass
- GHC.Hs.Type: arrowToHsType :: HsArrow GhcRn -> LHsType GhcRn
- GHC.Hs.Type: data ConDeclField pass
- GHC.Hs.Type: data EpLinearArrow
- GHC.Hs.Type: data HsArrowOf mult pass
- GHC.Hs.Type: data HsScaled pass a
- GHC.Hs.Type: expandHsArrow :: (LocatedN Name -> t GhcRn) -> HsArrowOf (LocatedA (t GhcRn)) GhcRn -> LocatedA (t GhcRn)
- GHC.Hs.Type: getBangStrictness :: forall (p :: Pass). LHsType (GhcPass p) -> HsSrcBang
- GHC.Hs.Type: getBangType :: forall (p :: Pass). LHsType (GhcPass p) -> LHsType (GhcPass p)
- GHC.Hs.Type: hsLinear :: forall (p :: Pass) a. IsPass p => a -> HsScaled (GhcPass p) a
- GHC.Hs.Type: hsMult :: HsScaled pass a -> HsArrow pass
- GHC.Hs.Type: hsScaledThing :: HsScaled pass a -> a
- GHC.Hs.Type: hsUnrestricted :: forall (p :: Pass) a. IsPass p => a -> HsScaled (GhcPass p) a
- GHC.Hs.Type: instance (GHC.Utils.Outputable.Outputable mult, GHC.Hs.Extension.OutputableBndrId pass) => GHC.Utils.Outputable.Outputable (Language.Haskell.Syntax.Type.HsArrowOf mult (GHC.Hs.Extension.GhcPass pass))
- GHC.Hs.Type: instance (GHC.Utils.Outputable.Outputable tyarg, GHC.Utils.Outputable.Outputable arg, GHC.Utils.Outputable.Outputable rec) => GHC.Utils.Outputable.Outputable (Language.Haskell.Syntax.Type.HsConDetails tyarg arg rec)
- GHC.Hs.Type: instance GHC.Hs.Extension.OutputableBndrId p => GHC.Utils.Outputable.Outputable (Language.Haskell.Syntax.Type.ConDeclField (GHC.Hs.Extension.GhcPass p))
- GHC.Hs.Type: instance GHC.Internal.Data.Data.Data GHC.Hs.Type.EpLinearArrow
- GHC.Hs.Type: instance GHC.Parser.Annotation.NoAnn GHC.Hs.Type.EpLinearArrow
- GHC.Hs.Type: instance GHC.Utils.Outputable.Outputable (Language.Haskell.Syntax.Extension.XRec pass (Language.Haskell.Syntax.Extension.IdP pass)) => GHC.Utils.Outputable.Outputable (Language.Haskell.Syntax.Type.FieldOcc pass)
- GHC.Hs.Type: isUnrestricted :: HsArrow GhcRn -> Bool
- GHC.Hs.Type: noTypeArgs :: [Void]
- GHC.Hs.Type: pprConDeclFields :: forall (p :: Pass). OutputableBndrId p => [LConDeclField (GhcPass p)] -> SDoc
- GHC.Hs.Type: type BangType pass = HsType pass
- GHC.Hs.Type: type HsArrow pass = HsArrowOf LHsType pass pass
- GHC.Hs.Type: type LBangType pass = XRec pass BangType pass
- GHC.Hs.Type: type LConDeclField pass = XRec pass ConDeclField pass
- GHC.Hs.Utils: nl_HsVar :: forall (p :: Pass) a. IsSrcSpanAnn p a => IdP (GhcPass p) -> HsExpr (GhcPass p)
- GHC.HsToCore.Binds: dsSpec :: Maybe CoreExpr -> Located TcSpecPrag -> DsM (Maybe (OrdList (Id, CoreExpr), CoreRule))
- GHC.HsToCore.Errors.Types: DsMultiplicityCoercionsNotSupported :: DsMessage
- GHC.HsToCore.Errors.Types: DsUselessSpecialiseForClassMethodSelector :: !Id -> DsMessage
- GHC.HsToCore.Errors.Types: DsUselessSpecialiseForNoInlineFunction :: !Id -> DsMessage
- GHC.HsToCore.Foreign.Wasm: instance GHC.Classes.Eq GHC.HsToCore.Foreign.Wasm.Synchronicity
- GHC.HsToCore.Match.Literal: warnAboutIdentities :: DynFlags -> Id -> Type -> DsM ()
- GHC.HsToCore.Monad: addMessagesDs :: Messages DsMessage -> DsM ()
- GHC.HsToCore.Monad: captureMessagesDs :: DsM a -> DsM (Messages DsMessage, a)
- GHC.HsToCore.Pmc: instance GHC.Classes.Eq (GHC.HsToCore.Pmc.FormatReportWarningsMode ann)
- GHC.HsToCore.Pmc.Solver: instance GHC.Classes.Eq GHC.HsToCore.Pmc.Solver.GenerateInhabitingPatternsMode
- GHC.HsToCore.Pmc.Solver.Types: instance GHC.Classes.Eq GHC.HsToCore.Pmc.Solver.Types.BotInfo
- GHC.HsToCore.Pmc.Solver.Types: instance GHC.Classes.Eq GHC.HsToCore.Pmc.Solver.Types.PmAltCon
- GHC.HsToCore.Pmc.Solver.Types: instance GHC.Classes.Eq GHC.HsToCore.Pmc.Solver.Types.PmEquality
- GHC.HsToCore.Pmc.Solver.Types: instance GHC.Classes.Eq GHC.HsToCore.Pmc.Solver.Types.PmLit
- GHC.HsToCore.Pmc.Types: instance GHC.Classes.Eq GHC.HsToCore.Pmc.Types.Precision
- GHC.HsToCore.Ticks: instance GHC.Classes.Eq GHC.HsToCore.Ticks.TickDensity
- GHC.HsToCore.Ticks: instance GHC.Classes.Eq GHC.HsToCore.Ticks.TickishType
- GHC.HsToCore.Utils: checkMultiplicityCoercions :: MultiplicityCheckCoercions -> DsM ()
- GHC.HsToCore.Utils: mkCoreAppDs :: SDoc -> CoreExpr -> CoreExpr -> CoreExpr
- GHC.HsToCore.Utils: mkCoreAppsDs :: SDoc -> CoreExpr -> [CoreExpr] -> CoreExpr
- GHC.Iface.Binary: instance GHC.Classes.Eq GHC.Iface.Binary.CheckHiWay
- GHC.Iface.Binary: instance GHC.Classes.Eq GHC.Iface.Binary.CompressionIFace
- GHC.Iface.Binary: instance GHC.Classes.Ord GHC.Iface.Binary.CompressionIFace
- GHC.Iface.Decl: toIfaceBooleanFormula :: BooleanFormula IfLclName -> IfaceBooleanFormula
- GHC.Iface.Errors.Types: instance GHC.Classes.Eq GHC.Iface.Errors.Types.BuildingCabalPackage
- GHC.Iface.Ext.Ast: instance (GHC.Iface.Ext.Ast.ToHie tyarg, GHC.Iface.Ext.Ast.ToHie arg, GHC.Iface.Ext.Ast.ToHie rec) => GHC.Iface.Ext.Ast.ToHie (Language.Haskell.Syntax.Type.HsConDetails tyarg arg rec)
- GHC.Iface.Ext.Ast: instance GHC.Iface.Ext.Ast.ToHie (GHC.Data.BooleanFormula.LBooleanFormula (GHC.Parser.Annotation.LocatedN GHC.Types.Name.Name))
- GHC.Iface.Ext.Ast: instance GHC.Iface.Ext.Ast.ToHie (GHC.Iface.Ext.Ast.RScoped (GHC.Parser.Annotation.LocatedAn GHC.Parser.Annotation.NoEpAnns (Language.Haskell.Syntax.Decls.RuleBndr GHC.Hs.Extension.GhcRn)))
- GHC.Iface.Ext.Ast: instance GHC.Iface.Ext.Ast.ToHie (GHC.Parser.Annotation.LocatedA (Language.Haskell.Syntax.Type.ConDeclField GHC.Hs.Extension.GhcRn))
- GHC.Iface.Ext.Ast: instance GHC.Iface.Ext.Ast.ToHie (GHC.Parser.Annotation.LocatedL [GHC.Parser.Annotation.LocatedA (Language.Haskell.Syntax.Type.ConDeclField GHC.Hs.Extension.GhcRn)])
- GHC.Iface.Ext.Ast: instance GHC.Iface.Ext.Ast.ToHie a => GHC.Iface.Ext.Ast.ToHie (Language.Haskell.Syntax.Type.HsScaled GHC.Hs.Extension.GhcRn a)
- GHC.Iface.Ext.Types: instance GHC.Classes.Eq GHC.Iface.Ext.Types.BindType
- GHC.Iface.Ext.Types: instance GHC.Classes.Eq GHC.Iface.Ext.Types.ContextInfo
- GHC.Iface.Ext.Types: instance GHC.Classes.Eq GHC.Iface.Ext.Types.DeclType
- GHC.Iface.Ext.Types: instance GHC.Classes.Eq GHC.Iface.Ext.Types.EntityInfo
- GHC.Iface.Ext.Types: instance GHC.Classes.Eq GHC.Iface.Ext.Types.EvBindDeps
- GHC.Iface.Ext.Types: instance GHC.Classes.Eq GHC.Iface.Ext.Types.EvVarSource
- GHC.Iface.Ext.Types: instance GHC.Classes.Eq GHC.Iface.Ext.Types.HieName
- GHC.Iface.Ext.Types: instance GHC.Classes.Eq GHC.Iface.Ext.Types.HieTypeFix
- GHC.Iface.Ext.Types: instance GHC.Classes.Eq GHC.Iface.Ext.Types.IEType
- GHC.Iface.Ext.Types: instance GHC.Classes.Eq GHC.Iface.Ext.Types.NodeAnnotation
- GHC.Iface.Ext.Types: instance GHC.Classes.Eq GHC.Iface.Ext.Types.NodeOrigin
- GHC.Iface.Ext.Types: instance GHC.Classes.Eq GHC.Iface.Ext.Types.RecFieldContext
- GHC.Iface.Ext.Types: instance GHC.Classes.Eq GHC.Iface.Ext.Types.Scope
- GHC.Iface.Ext.Types: instance GHC.Classes.Eq GHC.Iface.Ext.Types.TyVarScope
- GHC.Iface.Ext.Types: instance GHC.Classes.Eq a => GHC.Classes.Eq (GHC.Iface.Ext.Types.HieArgs a)
- GHC.Iface.Ext.Types: instance GHC.Classes.Eq a => GHC.Classes.Eq (GHC.Iface.Ext.Types.HieType a)
- GHC.Iface.Ext.Types: instance GHC.Classes.Eq a => GHC.Classes.Eq (GHC.Iface.Ext.Types.IdentifierDetails a)
- GHC.Iface.Ext.Types: instance GHC.Classes.Ord GHC.Iface.Ext.Types.BindType
- GHC.Iface.Ext.Types: instance GHC.Classes.Ord GHC.Iface.Ext.Types.ContextInfo
- GHC.Iface.Ext.Types: instance GHC.Classes.Ord GHC.Iface.Ext.Types.DeclType
- GHC.Iface.Ext.Types: instance GHC.Classes.Ord GHC.Iface.Ext.Types.EntityInfo
- GHC.Iface.Ext.Types: instance GHC.Classes.Ord GHC.Iface.Ext.Types.EvBindDeps
- GHC.Iface.Ext.Types: instance GHC.Classes.Ord GHC.Iface.Ext.Types.EvVarSource
- GHC.Iface.Ext.Types: instance GHC.Classes.Ord GHC.Iface.Ext.Types.HieName
- GHC.Iface.Ext.Types: instance GHC.Classes.Ord GHC.Iface.Ext.Types.IEType
- GHC.Iface.Ext.Types: instance GHC.Classes.Ord GHC.Iface.Ext.Types.NodeAnnotation
- GHC.Iface.Ext.Types: instance GHC.Classes.Ord GHC.Iface.Ext.Types.NodeOrigin
- GHC.Iface.Ext.Types: instance GHC.Classes.Ord GHC.Iface.Ext.Types.RecFieldContext
- GHC.Iface.Ext.Types: instance GHC.Classes.Ord GHC.Iface.Ext.Types.Scope
- GHC.Iface.Ext.Types: instance GHC.Classes.Ord GHC.Iface.Ext.Types.TyVarScope
- GHC.Iface.Ext.Utils: instance GHC.Classes.Eq a => GHC.Classes.Eq (GHC.Iface.Ext.Utils.EvidenceInfo a)
- GHC.Iface.Ext.Utils: instance GHC.Classes.Ord a => GHC.Classes.Ord (GHC.Iface.Ext.Utils.EvidenceInfo a)
- GHC.Iface.Recomp: instance GHC.Classes.Eq GHC.Iface.Recomp.CompileReason
- GHC.Iface.Recomp: instance GHC.Classes.Eq GHC.Iface.Recomp.RecompReason
- GHC.Iface.Recomp: instance GHC.Classes.Eq GHC.Iface.Recomp.RecompileRequired
- GHC.Iface.Syntax: fromIfaceBooleanFormula :: IfaceBooleanFormula -> BooleanFormula IfLclName
- GHC.Iface.Syntax: instance (GHC.Classes.Eq b, GHC.Classes.Eq r) => GHC.Classes.Eq (GHC.Iface.Syntax.IfaceBindingX r b)
- GHC.Iface.Syntax: instance (GHC.Classes.Ord b, GHC.Classes.Ord r) => GHC.Classes.Ord (GHC.Iface.Syntax.IfaceBindingX r b)
- GHC.Iface.Tidy: instance GHC.Classes.Eq GHC.Iface.Tidy.UnfoldingExposure
- GHC.Iface.Tidy: instance GHC.Classes.Ord GHC.Iface.Tidy.UnfoldingExposure
- GHC.Iface.Type: instance GHC.Classes.Eq GHC.Iface.Type.IfLclName
- GHC.Iface.Type: instance GHC.Classes.Eq GHC.Iface.Type.IfaceAppArgs
- GHC.Iface.Type: instance GHC.Classes.Eq GHC.Iface.Type.IfaceAxiomRule
- GHC.Iface.Type: instance GHC.Classes.Eq GHC.Iface.Type.IfaceBndr
- GHC.Iface.Type: instance GHC.Classes.Eq GHC.Iface.Type.IfaceCoercion
- GHC.Iface.Type: instance GHC.Classes.Eq GHC.Iface.Type.IfaceMCoercion
- GHC.Iface.Type: instance GHC.Classes.Eq GHC.Iface.Type.IfaceTyCon
- GHC.Iface.Type: instance GHC.Classes.Eq GHC.Iface.Type.IfaceTyConInfo
- GHC.Iface.Type: instance GHC.Classes.Eq GHC.Iface.Type.IfaceTyConSort
- GHC.Iface.Type: instance GHC.Classes.Eq GHC.Iface.Type.IfaceTyLit
- GHC.Iface.Type: instance GHC.Classes.Eq GHC.Iface.Type.IfaceType
- GHC.Iface.Type: instance GHC.Classes.Eq GHC.Iface.Type.TupleOrSum
- GHC.Iface.Type: instance GHC.Classes.Ord GHC.Iface.Type.IfLclName
- GHC.Iface.Type: instance GHC.Classes.Ord GHC.Iface.Type.IfaceAppArgs
- GHC.Iface.Type: instance GHC.Classes.Ord GHC.Iface.Type.IfaceAxiomRule
- GHC.Iface.Type: instance GHC.Classes.Ord GHC.Iface.Type.IfaceBndr
- GHC.Iface.Type: instance GHC.Classes.Ord GHC.Iface.Type.IfaceCoercion
- GHC.Iface.Type: instance GHC.Classes.Ord GHC.Iface.Type.IfaceMCoercion
- GHC.Iface.Type: instance GHC.Classes.Ord GHC.Iface.Type.IfaceTyCon
- GHC.Iface.Type: instance GHC.Classes.Ord GHC.Iface.Type.IfaceTyConInfo
- GHC.Iface.Type: instance GHC.Classes.Ord GHC.Iface.Type.IfaceTyConSort
- GHC.Iface.Type: instance GHC.Classes.Ord GHC.Iface.Type.IfaceTyLit
- GHC.Iface.Type: instance GHC.Classes.Ord GHC.Iface.Type.IfaceType
- GHC.JS.Ident: instance GHC.Classes.Eq GHC.JS.Ident.Ident
- GHC.JS.JStg.Syntax: instance GHC.Classes.Eq GHC.JS.JStg.Syntax.AOp
- GHC.JS.JStg.Syntax: instance GHC.Classes.Eq GHC.JS.JStg.Syntax.JStgExpr
- GHC.JS.JStg.Syntax: instance GHC.Classes.Eq GHC.JS.JStg.Syntax.JStgStat
- GHC.JS.JStg.Syntax: instance GHC.Classes.Eq GHC.JS.JStg.Syntax.JVal
- GHC.JS.JStg.Syntax: instance GHC.Classes.Eq GHC.JS.JStg.Syntax.Op
- GHC.JS.JStg.Syntax: instance GHC.Classes.Eq GHC.JS.JStg.Syntax.UOp
- GHC.JS.JStg.Syntax: instance GHC.Classes.Ord GHC.JS.JStg.Syntax.AOp
- GHC.JS.JStg.Syntax: instance GHC.Classes.Ord GHC.JS.JStg.Syntax.Op
- GHC.JS.JStg.Syntax: instance GHC.Classes.Ord GHC.JS.JStg.Syntax.UOp
- GHC.JS.Make: instance (GHC.JS.Make.JVarMagic a, GHC.JS.Make.ToJExpr a) => GHC.JS.Make.JSArgument (GHC.Tuple.Solo a)
- GHC.JS.Make: instance GHC.JS.Make.ToJExpr GHC.Num.Integer.Integer
- GHC.JS.Make: instance GHC.JS.Make.ToJExpr GHC.Types.Bool
- GHC.JS.Make: instance GHC.JS.Make.ToJExpr GHC.Types.Char
- GHC.JS.Make: instance GHC.JS.Make.ToJExpr GHC.Types.Double
- GHC.JS.Make: instance GHC.JS.Make.ToJExpr GHC.Types.Int
- GHC.JS.Opt.Simple: instance GHC.Classes.Eq GHC.JS.Opt.Simple.Multiplicity
- GHC.JS.Opt.Simple: instance GHC.Classes.Eq GHC.JS.Opt.Simple.VarDecl
- GHC.JS.Opt.Simple: instance GHC.Classes.Ord GHC.JS.Opt.Simple.Multiplicity
- GHC.JS.Opt.Simple: instance GHC.Classes.Ord GHC.JS.Opt.Simple.VarDecl
- GHC.JS.Syntax: instance GHC.Classes.Eq GHC.JS.Syntax.AOp
- GHC.JS.Syntax: instance GHC.Classes.Eq GHC.JS.Syntax.JExpr
- GHC.JS.Syntax: instance GHC.Classes.Eq GHC.JS.Syntax.JStat
- GHC.JS.Syntax: instance GHC.Classes.Eq GHC.JS.Syntax.JVal
- GHC.JS.Syntax: instance GHC.Classes.Eq GHC.JS.Syntax.Op
- GHC.JS.Syntax: instance GHC.Classes.Eq GHC.JS.Syntax.UOp
- GHC.JS.Syntax: instance GHC.Classes.Ord GHC.JS.Syntax.AOp
- GHC.JS.Syntax: instance GHC.Classes.Ord GHC.JS.Syntax.Op
- GHC.JS.Syntax: instance GHC.Classes.Ord GHC.JS.Syntax.UOp
- GHC.Linker.Deps: [ldLoadIface] :: LinkDepsOpts -> !SDoc -> Module -> IO (MaybeErr MissingInterfaceError ModIface)
- GHC.Linker.Deps: [ldModuleGraph] :: LinkDepsOpts -> !ModuleGraph
- GHC.Linker.Deps: [ldOneShotMode] :: LinkDepsOpts -> !Bool
- GHC.Linker.Loader: loadExpr :: Interp -> HscEnv -> SrcSpan -> UnlinkedBCO -> IO ForeignHValue
- GHC.Llvm.MetaData: instance GHC.Classes.Eq GHC.Llvm.MetaData.MetaAnnot
- GHC.Llvm.MetaData: instance GHC.Classes.Eq GHC.Llvm.MetaData.MetaExpr
- GHC.Llvm.MetaData: instance GHC.Classes.Eq GHC.Llvm.MetaData.MetaId
- GHC.Llvm.MetaData: instance GHC.Classes.Ord GHC.Llvm.MetaData.MetaId
- GHC.Llvm.Syntax: instance GHC.Classes.Eq GHC.Llvm.Syntax.LlvmAtomicOp
- GHC.Llvm.Syntax: instance GHC.Classes.Eq GHC.Llvm.Syntax.LlvmExpression
- GHC.Llvm.Syntax: instance GHC.Classes.Eq GHC.Llvm.Syntax.LlvmStatement
- GHC.Llvm.Syntax: instance GHC.Classes.Eq GHC.Llvm.Syntax.LlvmSyncOrdering
- GHC.Llvm.Types: instance GHC.Classes.Eq GHC.Llvm.Types.LMConst
- GHC.Llvm.Types: instance GHC.Classes.Eq GHC.Llvm.Types.LlvmCallConvention
- GHC.Llvm.Types: instance GHC.Classes.Eq GHC.Llvm.Types.LlvmCallType
- GHC.Llvm.Types: instance GHC.Classes.Eq GHC.Llvm.Types.LlvmCastOp
- GHC.Llvm.Types: instance GHC.Classes.Eq GHC.Llvm.Types.LlvmCmpOp
- GHC.Llvm.Types: instance GHC.Classes.Eq GHC.Llvm.Types.LlvmFuncAttr
- GHC.Llvm.Types: instance GHC.Classes.Eq GHC.Llvm.Types.LlvmFunctionDecl
- GHC.Llvm.Types: instance GHC.Classes.Eq GHC.Llvm.Types.LlvmLinkageType
- GHC.Llvm.Types: instance GHC.Classes.Eq GHC.Llvm.Types.LlvmLit
- GHC.Llvm.Types: instance GHC.Classes.Eq GHC.Llvm.Types.LlvmMachOp
- GHC.Llvm.Types: instance GHC.Classes.Eq GHC.Llvm.Types.LlvmParamAttr
- GHC.Llvm.Types: instance GHC.Classes.Eq GHC.Llvm.Types.LlvmParameterListType
- GHC.Llvm.Types: instance GHC.Classes.Eq GHC.Llvm.Types.LlvmType
- GHC.Llvm.Types: instance GHC.Classes.Eq GHC.Llvm.Types.LlvmVar
- GHC.Parser.Annotation: NoTokenLoc :: TokenLocation
- GHC.Parser.Annotation: TokenLoc :: !EpaLocation -> TokenLocation
- GHC.Parser.Annotation: commentsOnlyA :: NoAnn ann => EpAnn ann -> EpAnn ann
- GHC.Parser.Annotation: data TokenLocation
- GHC.Parser.Annotation: instance GHC.Classes.Eq (GHC.Parser.Annotation.EpToken tok)
- GHC.Parser.Annotation: instance GHC.Classes.Eq (GHC.Parser.Annotation.EpUniToken tok utok)
- GHC.Parser.Annotation: instance GHC.Classes.Eq GHC.Parser.Annotation.AnnListBrackets
- GHC.Parser.Annotation: instance GHC.Classes.Eq GHC.Parser.Annotation.AnnListItem
- GHC.Parser.Annotation: instance GHC.Classes.Eq GHC.Parser.Annotation.AnnPragma
- GHC.Parser.Annotation: instance GHC.Classes.Eq GHC.Parser.Annotation.BindTag
- GHC.Parser.Annotation: instance GHC.Classes.Eq GHC.Parser.Annotation.DeclTag
- GHC.Parser.Annotation: instance GHC.Classes.Eq GHC.Parser.Annotation.EpAnnComments
- GHC.Parser.Annotation: instance GHC.Classes.Eq GHC.Parser.Annotation.EpaComment
- GHC.Parser.Annotation: instance GHC.Classes.Eq GHC.Parser.Annotation.EpaCommentTok
- GHC.Parser.Annotation: instance GHC.Classes.Eq GHC.Parser.Annotation.HasE
- GHC.Parser.Annotation: instance GHC.Classes.Eq GHC.Parser.Annotation.IsUnicodeSyntax
- GHC.Parser.Annotation: instance GHC.Classes.Eq GHC.Parser.Annotation.NameAdornment
- GHC.Parser.Annotation: instance GHC.Classes.Eq GHC.Parser.Annotation.NameAnn
- GHC.Parser.Annotation: instance GHC.Classes.Eq GHC.Parser.Annotation.NoEpAnns
- GHC.Parser.Annotation: instance GHC.Classes.Eq GHC.Parser.Annotation.TokenLocation
- GHC.Parser.Annotation: instance GHC.Classes.Eq GHC.Parser.Annotation.TrailingAnn
- GHC.Parser.Annotation: instance GHC.Classes.Eq a => GHC.Classes.Eq (GHC.Parser.Annotation.AnnList a)
- GHC.Parser.Annotation: instance GHC.Classes.Eq ann => GHC.Classes.Eq (GHC.Parser.Annotation.EpAnn ann)
- GHC.Parser.Annotation: instance GHC.Classes.Eq tag => GHC.Classes.Eq (GHC.Parser.Annotation.AnnSortKey tag)
- GHC.Parser.Annotation: instance GHC.Classes.Ord GHC.Parser.Annotation.BindTag
- GHC.Parser.Annotation: instance GHC.Classes.Ord GHC.Parser.Annotation.DeclTag
- GHC.Parser.Annotation: instance GHC.Classes.Ord GHC.Parser.Annotation.HasE
- GHC.Parser.Annotation: instance GHC.Classes.Ord GHC.Parser.Annotation.IsUnicodeSyntax
- GHC.Parser.Annotation: instance GHC.Classes.Ord GHC.Parser.Annotation.NoEpAnns
- GHC.Parser.Annotation: instance GHC.Internal.Data.Data.Data GHC.Parser.Annotation.TokenLocation
- GHC.Parser.Annotation: instance GHC.Parser.Annotation.NoAnn GHC.Types.Bool
- GHC.Parser.Annotation: instance GHC.Utils.Outputable.Outputable a => GHC.Utils.Outputable.Outputable (GHC.Types.SrcLoc.GenLocated GHC.Parser.Annotation.TokenLocation a)
- GHC.Parser.Annotation: reAnnC :: AnnContext -> EpAnnComments -> Located a -> LocatedC a
- GHC.Parser.Annotation: reAnnL :: ann -> EpAnnComments -> Located e -> GenLocated (EpAnn ann) e
- GHC.Parser.Annotation: removeCommentsA :: EpAnn ann -> EpAnn ann
- GHC.Parser.Errors.Types: PEIP_TypeArgs :: [HsConPatTyArg GhcPs] -> PsErrInPatDetails
- GHC.Parser.Errors.Types: instance GHC.Classes.Eq GHC.Parser.Errors.Types.LexErr
- GHC.Parser.Errors.Types: instance GHC.Classes.Eq GHC.Parser.Errors.Types.LexErrKind
- GHC.Parser.Errors.Types: instance GHC.Classes.Eq GHC.Parser.Errors.Types.NumUnderscoreReason
- GHC.Parser.Errors.Types: instance GHC.Classes.Eq GHC.Parser.Errors.Types.ParseContext
- GHC.Parser.Errors.Types: instance GHC.Classes.Eq GHC.Parser.Errors.Types.PatIncompleteDoBlock
- GHC.Parser.Errors.Types: instance GHC.Classes.Ord GHC.Parser.Errors.Types.LexErr
- GHC.Parser.Errors.Types: instance GHC.Classes.Ord GHC.Parser.Errors.Types.LexErrKind
- GHC.Parser.Errors.Types: instance GHC.Classes.Ord GHC.Parser.Errors.Types.NumUnderscoreReason
- GHC.Parser.Lexer: [pSupportedExts] :: ParserOpts -> [String]
- GHC.Parser.PostProcess: ImpExpQcType :: EpToken "type" -> LocatedN RdrName -> ImpExpQcSpec
- GHC.Parser.PostProcess: hsHoleExpr :: Maybe EpAnnUnboundVar -> HsExpr GhcPs
- GHC.Parser.PostProcess: instance GHC.Utils.Outputable.Outputable (GHC.Parser.PostProcess.ArgPatBuilder GHC.Hs.Extension.GhcPs)
- GHC.Parser.PostProcess: mkMultTy :: EpToken "%" -> LHsType GhcPs -> TokRarrow -> HsArrow GhcPs
- GHC.Parser.PostProcess: mkRuleTyVarBndrs :: [LRuleTyTmVar] -> [LHsTyVarBndr () GhcPs]
- GHC.Parser.PostProcess: mkTokenLocation :: SrcSpan -> TokenLocation
- GHC.Parser.PostProcess.Haddock: instance GHC.Parser.PostProcess.Haddock.HasHaddock a => GHC.Parser.PostProcess.Haddock.HasHaddock (Language.Haskell.Syntax.Type.HsScaled GHC.Hs.Extension.GhcPs a)
- GHC.Parser.String: instance GHC.Classes.Eq GHC.Parser.String.StringLexError
- GHC.Parser.String: instance GHC.Parser.String.HasChar (GHC.Types.Char, x)
- GHC.Parser.String: instance GHC.Parser.String.HasChar GHC.Types.Char
- GHC.Platform: instance GHC.Classes.Eq GHC.Platform.BmiVersion
- GHC.Platform: instance GHC.Classes.Eq GHC.Platform.Platform
- GHC.Platform: instance GHC.Classes.Eq GHC.Platform.PlatformWordSize
- GHC.Platform: instance GHC.Classes.Eq GHC.Platform.SseVersion
- GHC.Platform: instance GHC.Classes.Ord GHC.Platform.BmiVersion
- GHC.Platform: instance GHC.Classes.Ord GHC.Platform.Platform
- GHC.Platform: instance GHC.Classes.Ord GHC.Platform.PlatformWordSize
- GHC.Platform: instance GHC.Classes.Ord GHC.Platform.SseVersion
- GHC.Platform.Constants: instance GHC.Classes.Eq GHC.Platform.Constants.PlatformConstants
- GHC.Platform.Constants: instance GHC.Classes.Ord GHC.Platform.Constants.PlatformConstants
- GHC.Platform.LoongArch64: activeStgRegs :: [GlobalReg]
- GHC.Platform.LoongArch64: callerSaves :: GlobalReg -> Bool
- GHC.Platform.LoongArch64: freeReg :: RegNo -> Bool
- GHC.Platform.LoongArch64: globalRegMaybe :: GlobalReg -> Maybe RealReg
- GHC.Platform.LoongArch64: haveRegBase :: Bool
- GHC.Platform.Profile: instance GHC.Classes.Eq GHC.Platform.Profile.Profile
- GHC.Platform.Profile: instance GHC.Classes.Ord GHC.Platform.Profile.Profile
- GHC.Platform.Reg: instance GHC.Classes.Eq GHC.Platform.Reg.RealReg
- GHC.Platform.Reg: instance GHC.Classes.Eq GHC.Platform.Reg.Reg
- GHC.Platform.Reg: instance GHC.Classes.Eq GHC.Platform.Reg.VirtualReg
- GHC.Platform.Reg: instance GHC.Classes.Ord GHC.Platform.Reg.RealReg
- GHC.Platform.Reg: instance GHC.Classes.Ord GHC.Platform.Reg.Reg
- GHC.Platform.Reg: instance GHC.Classes.Ord GHC.Platform.Reg.VirtualReg
- GHC.Platform.Reg.Class: instance GHC.Classes.Eq GHC.Platform.Reg.Class.RegArch
- GHC.Platform.Reg.Class: instance GHC.Classes.Eq GHC.Platform.Reg.Class.RegClass
- GHC.Platform.Reg.Class: instance GHC.Classes.Ord GHC.Platform.Reg.Class.RegArch
- GHC.Platform.Reg.Class: instance GHC.Classes.Ord GHC.Platform.Reg.Class.RegClass
- GHC.Platform.Ways: instance GHC.Classes.Eq GHC.Platform.Ways.Way
- GHC.Platform.Ways: instance GHC.Classes.Ord GHC.Platform.Ways.Way
- GHC.Plugins: [ch_hetero_kind] :: CoercionHole -> Bool
- GHC.Plugins: getSubstInScope :: Subst -> InScopeSet
- GHC.Plugins: hasCoercionHoleCo :: Coercion -> Bool
- GHC.Plugins: hasCoercionHoleTy :: Type -> Bool
- GHC.Plugins: hasThisCoercionHoleTy :: Type -> CoercionHole -> Bool
- GHC.Plugins: invisibleTyBndrCount :: Type -> Int
- GHC.Plugins: isDataFamilyAppType :: Type -> Bool
- GHC.Plugins: isPredTy :: HasDebugCallStack => Type -> Bool
- GHC.Plugins: mkNomPrimEqPred :: Kind -> Type -> Type -> Type
- GHC.Plugins: mkPrimEqPred :: Type -> Type -> Type
- GHC.Plugins: mkPrimEqPredRole :: Role -> Type -> Type -> PredType
- GHC.Plugins: mkReprPrimEqPred :: Type -> Type -> Type
- GHC.Plugins: scopedSort :: [TyCoVar] -> [TyCoVar]
- GHC.Plugins: substForAllCoBndrUsingLC :: SwapFlag -> (Coercion -> Coercion) -> LiftingContext -> TyCoVar -> Coercion -> (LiftingContext, TyCoVar, Coercion)
- GHC.Plugins: tidyForAllTyBinder :: TidyEnv -> VarBndr TyCoVar vis -> (TidyEnv, VarBndr TyCoVar vis)
- GHC.Plugins: tidyForAllTyBinders :: TidyEnv -> [VarBndr TyCoVar vis] -> (TidyEnv, [VarBndr TyCoVar vis])
- GHC.Plugins: tidyFreeTyCoVarX :: TidyEnv -> TyCoVar -> (TidyEnv, TyCoVar)
- GHC.Plugins: tidyFreeTyCoVars :: TidyEnv -> [TyCoVar] -> TidyEnv
- GHC.Plugins: tidyFreeTyCoVarsX :: TidyEnv -> [TyCoVar] -> (TidyEnv, [TyCoVar])
- GHC.Plugins: tidyOpenType :: TidyEnv -> Type -> Type
- GHC.Plugins: tidyOpenTypeX :: TidyEnv -> Type -> (TidyEnv, Type)
- GHC.Plugins: tidyOpenTypes :: TidyEnv -> [Type] -> [Type]
- GHC.Plugins: tidyOpenTypesX :: TidyEnv -> [Type] -> (TidyEnv, [Type])
- GHC.Plugins: tidyTopType :: Type -> Type
- GHC.Plugins: tidyTyCoVarOcc :: TidyEnv -> TyCoVar -> TyCoVar
- GHC.Plugins: tidyType :: TidyEnv -> Type -> Type
- GHC.Plugins: tidyTypes :: TidyEnv -> [Type] -> [Type]
- GHC.Plugins: tidyVarBndr :: TidyEnv -> TyCoVar -> (TidyEnv, TyCoVar)
- GHC.Plugins: tidyVarBndrs :: TidyEnv -> [TyCoVar] -> (TidyEnv, [TyCoVar])
- GHC.Plugins: tyCoVarsOfTypeWellScoped :: Type -> [TyVar]
- GHC.Plugins: tyCoVarsOfTypesWellScoped :: [Type] -> [TyVar]
- GHC.Rename.Env: lookupGlobalOccRn :: RdrName -> RnM Name
- GHC.Rename.Env: lookupLocatedTopBndrRn :: Located RdrName -> RnM (Located Name)
- GHC.Rename.Env: lookupLocatedTopConstructorRn :: Located RdrName -> RnM (Located Name)
- GHC.Rename.Env: lookupLocatedTopConstructorRnN :: LocatedN RdrName -> RnM (LocatedN Name)
- GHC.Rename.Env: lookupQualifiedDoExpr :: HsStmtContext fn -> Name -> RnM (HsExpr GhcRn, FreeVars)
- GHC.Rename.Env: lookupSigOccRnN :: HsSigCtxt -> Sig GhcPs -> LocatedN RdrName -> RnM (LocatedN Name)
- GHC.Rename.HsType: rnConDeclFields :: HsDocContext -> [FieldLabel] -> [LConDeclField GhcPs] -> RnM ([LConDeclField GhcRn], FreeVars)
- GHC.Rename.HsType: rnHsArrowWith :: (LocatedA (mult GhcPs) -> RnM (LocatedA (mult GhcRn), FreeVars)) -> HsArrowOf (LocatedA (mult GhcPs)) GhcPs -> RnM (HsArrowOf (LocatedA (mult GhcRn)) GhcRn, FreeVars)
- GHC.Rename.HsType: rnScaledLHsType :: HsDocContext -> HsScaled GhcPs (LHsType GhcPs) -> RnM (HsScaled GhcRn (LHsType GhcRn), FreeVars)
- GHC.Rename.Unbound: instance GHC.Classes.Eq GHC.Rename.Unbound.WhatLooking
- GHC.Rename.Unbound: nameSpacesRelated :: DynFlags -> WhatLooking -> NameSpace -> NameSpace -> Bool
- GHC.Rename.Unbound: reportUnboundName' :: WhatLooking -> RdrName -> RnM Name
- GHC.Runtime.Eval.Types: isStep :: SingleStep -> Bool
- GHC.Runtime.Heap.Layout: instance GHC.Classes.Eq GHC.Runtime.Heap.Layout.ArgDescr
- GHC.Runtime.Heap.Layout: instance GHC.Classes.Eq GHC.Runtime.Heap.Layout.ClosureTypeInfo
- GHC.Runtime.Heap.Layout: instance GHC.Classes.Eq GHC.Runtime.Heap.Layout.SMRep
- GHC.Runtime.Heap.Layout: instance GHC.Classes.Eq GHC.Runtime.Heap.Layout.StgHalfWord
- GHC.Runtime.Heap.Layout: instance GHC.Classes.Eq GHC.Runtime.Heap.Layout.StgWord
- GHC.Runtime.Heap.Layout: instance GHC.Classes.Ord GHC.Runtime.Heap.Layout.ArgDescr
- GHC.Runtime.Heap.Layout: instance GHC.Classes.Ord GHC.Runtime.Heap.Layout.ClosureTypeInfo
- GHC.Runtime.Heap.Layout: instance GHC.Classes.Ord GHC.Runtime.Heap.Layout.SMRep
- GHC.Runtime.Interpreter: [NewBreakModule] :: String -> Message (RemotePtr BreakModule)
- GHC.Runtime.Interpreter: interpreterDynamic :: Interp -> Bool
- GHC.Runtime.Interpreter: interpreterProfiled :: Interp -> Bool
- GHC.Runtime.Interpreter: newModuleName :: Interp -> ModuleName -> IO (RemotePtr ModuleName)
- GHC.Runtime.Interpreter.Process: [NewBreakModule] :: String -> Message (RemotePtr BreakModule)
- GHC.Runtime.Interpreter.Types: [interpLookupSymbolCache] :: Interp -> !MVar (UniqFM FastString (Ptr ()))
- GHC.Stg.InferTags: inferTags :: StgPprOpts -> Bool -> Logger -> Module -> [CgStgTopBinding] -> IO ([TgStgTopBinding], NameEnv TagSig)
- GHC.Stg.InferTags.Rewrite: instance GHC.Internal.Base.Applicative GHC.Stg.InferTags.Rewrite.RM
- GHC.Stg.InferTags.Rewrite: instance GHC.Internal.Base.Functor GHC.Stg.InferTags.Rewrite.RM
- GHC.Stg.InferTags.Rewrite: instance GHC.Internal.Base.Monad GHC.Stg.InferTags.Rewrite.RM
- GHC.Stg.InferTags.Rewrite: instance GHC.Types.Unique.Supply.MonadUnique GHC.Stg.InferTags.Rewrite.RM
- GHC.Stg.InferTags.Rewrite: rewriteOpApp :: InferStgExpr -> RM TgStgExpr
- GHC.Stg.InferTags.Rewrite: rewriteTopBinds :: Module -> UniqSupply -> [GenStgTopBinding 'InferTaggedBinders] -> [TgStgTopBinding]
- GHC.Stg.InferTags.TagSig: TagDunno :: TagInfo
- GHC.Stg.InferTags.TagSig: TagProper :: TagInfo
- GHC.Stg.InferTags.TagSig: TagSig :: TagInfo -> TagSig
- GHC.Stg.InferTags.TagSig: TagTagged :: TagInfo
- GHC.Stg.InferTags.TagSig: TagTuple :: [TagInfo] -> TagInfo
- GHC.Stg.InferTags.TagSig: data TagInfo
- GHC.Stg.InferTags.TagSig: instance GHC.Classes.Eq GHC.Stg.InferTags.TagSig.TagInfo
- GHC.Stg.InferTags.TagSig: instance GHC.Classes.Eq GHC.Stg.InferTags.TagSig.TagSig
- GHC.Stg.InferTags.TagSig: instance GHC.Utils.Binary.Binary GHC.Stg.InferTags.TagSig.TagInfo
- GHC.Stg.InferTags.TagSig: instance GHC.Utils.Binary.Binary GHC.Stg.InferTags.TagSig.TagSig
- GHC.Stg.InferTags.TagSig: instance GHC.Utils.Outputable.Outputable GHC.Stg.InferTags.TagSig.TagInfo
- GHC.Stg.InferTags.TagSig: instance GHC.Utils.Outputable.Outputable GHC.Stg.InferTags.TagSig.TagSig
- GHC.Stg.InferTags.TagSig: instance GHC.Utils.Outputable.OutputableBndr (GHC.Types.Var.Id, GHC.Stg.InferTags.TagSig.TagSig)
- GHC.Stg.InferTags.TagSig: isTaggedSig :: TagSig -> Bool
- GHC.Stg.InferTags.TagSig: newtype TagSig
- GHC.Stg.InferTags.TagSig: seqTagInfo :: TagInfo -> ()
- GHC.Stg.InferTags.TagSig: seqTagSig :: TagSig -> ()
- GHC.Stg.InferTags.TagSig: type StgCgInfos = NameEnv TagSig
- GHC.Stg.InferTags.Types: TE :: TagSigEnv -> (BinderP p -> Id) -> !Bool -> TagEnv (p :: StgPass)
- GHC.Stg.InferTags.Types: [te_bytecode] :: TagEnv (p :: StgPass) -> !Bool
- GHC.Stg.InferTags.Types: [te_env] :: TagEnv (p :: StgPass) -> TagSigEnv
- GHC.Stg.InferTags.Types: [te_get] :: TagEnv (p :: StgPass) -> BinderP p -> Id
- GHC.Stg.InferTags.Types: combineAltInfo :: TagInfo -> TagInfo -> TagInfo
- GHC.Stg.InferTags.Types: data TagEnv (p :: StgPass)
- GHC.Stg.InferTags.Types: extendSigEnv :: forall (p :: StgPass). TagEnv p -> [(Id, TagSig)] -> TagEnv p
- GHC.Stg.InferTags.Types: getBinderId :: forall (p :: StgPass). TagEnv p -> BinderP p -> Id
- GHC.Stg.InferTags.Types: initEnv :: Bool -> TagEnv 'CodeGen
- GHC.Stg.InferTags.Types: instance GHC.Utils.Outputable.Outputable (GHC.Stg.InferTags.Types.TagEnv p)
- GHC.Stg.InferTags.Types: isDunnoSig :: TagSig -> Bool
- GHC.Stg.InferTags.Types: isTaggedInfo :: TagInfo -> Bool
- GHC.Stg.InferTags.Types: lookupInfo :: forall (p :: StgPass). TagEnv p -> StgArg -> TagInfo
- GHC.Stg.InferTags.Types: lookupSig :: forall (p :: StgPass). TagEnv p -> Id -> Maybe TagSig
- GHC.Stg.InferTags.Types: makeTagged :: forall (p :: StgPass). TagEnv p -> TagEnv 'InferTaggedBinders
- GHC.Stg.InferTags.Types: noSig :: forall (p :: StgPass). TagEnv p -> BinderP p -> (Id, TagSig)
- GHC.Stg.InferTags.Types: type InferStgAlt = GenStgAlt 'InferTaggedBinders
- GHC.Stg.InferTags.Types: type InferStgBinding = GenStgBinding 'InferTaggedBinders
- GHC.Stg.InferTags.Types: type InferStgExpr = GenStgExpr 'InferTaggedBinders
- GHC.Stg.InferTags.Types: type InferStgRhs = GenStgRhs 'InferTaggedBinders
- GHC.Stg.InferTags.Types: type InferStgTopBinding = GenStgTopBinding 'InferTaggedBinders
- GHC.Stg.InferTags.Types: type TagSigEnv = IdEnv TagSig
- GHC.Stg.Lift.Config: instance GHC.Classes.Eq GHC.Stg.Lift.Config.StgLiftConfig
- GHC.Stg.Lift.Config: instance GHC.Classes.Ord GHC.Stg.Lift.Config.StgLiftConfig
- GHC.Stg.Pipeline: instance GHC.Classes.Eq GHC.Stg.Pipeline.StgToDo
- GHC.Stg.Pipeline: instance GHC.Classes.Ord GHC.Stg.Pipeline.StgToDo
- GHC.Stg.Stats: instance GHC.Classes.Eq GHC.Stg.Stats.CounterType
- GHC.Stg.Stats: instance GHC.Classes.Ord GHC.Stg.Stats.CounterType
- GHC.Stg.Syntax: instance GHC.Classes.Eq GHC.Stg.Syntax.NoExtFieldSilent
- GHC.Stg.Syntax: instance GHC.Classes.Eq GHC.Stg.Syntax.UpdateFlag
- GHC.Stg.Syntax: instance GHC.Classes.Ord GHC.Stg.Syntax.NoExtFieldSilent
- GHC.StgToByteCode: instance GHC.Classes.Eq GHC.StgToByteCode.Discr
- GHC.StgToByteCode: instance GHC.Classes.Ord GHC.StgToByteCode.Discr
- GHC.StgToCmm.ArgRep: instance GHC.Classes.Eq GHC.StgToCmm.ArgRep.ArgRep
- GHC.StgToCmm.ArgRep: instance GHC.Classes.Ord GHC.StgToCmm.ArgRep.ArgRep
- GHC.StgToCmm.Closure: instance GHC.Classes.Eq a => GHC.Classes.Eq (GHC.StgToCmm.Closure.NonVoid a)
- GHC.StgToCmm.Types: instance GHC.Classes.Eq GHC.StgToCmm.Types.StandardFormInfo
- GHC.StgToJS.Apply: instance GHC.Classes.Eq GHC.StgToJS.Apply.ApplyConv
- GHC.StgToJS.Apply: instance GHC.Classes.Eq GHC.StgToJS.Apply.ApplySpec
- GHC.StgToJS.Apply: instance GHC.Classes.Ord GHC.StgToJS.Apply.ApplyConv
- GHC.StgToJS.Apply: instance GHC.Classes.Ord GHC.StgToJS.Apply.ApplySpec
- GHC.StgToJS.Arg: allocUnboxedConStatic :: DataCon -> [StaticArg] -> StaticArg
- GHC.StgToJS.Arg: allocateStaticList :: [StgArg] -> StgArg -> G StaticVal
- GHC.StgToJS.Arg: jsStaticArg :: StaticArg -> JStgExpr
- GHC.StgToJS.Expr: instance GHC.Classes.Eq a => GHC.Classes.Eq (GHC.StgToJS.Expr.Branch a)
- GHC.StgToJS.Linker.Linker: staticDeclStat :: StaticInfo -> JStat
- GHC.StgToJS.Linker.Linker: staticInitStat :: StaticInfo -> JStat
- GHC.StgToJS.Monad: [global_ident] :: GlobalOcc -> !Ident
- GHC.StgToJS.Object: instance GHC.Classes.Eq GHC.StgToJS.Object.BlockRef
- GHC.StgToJS.Object: instance GHC.Classes.Eq GHC.StgToJS.Object.ExportedFun
- GHC.StgToJS.Object: instance GHC.Classes.Eq GHC.StgToJS.Object.JSOptions
- GHC.StgToJS.Object: instance GHC.Classes.Eq GHC.StgToJS.Object.ObjectKind
- GHC.StgToJS.Object: instance GHC.Classes.Ord GHC.StgToJS.Object.BlockRef
- GHC.StgToJS.Object: instance GHC.Classes.Ord GHC.StgToJS.Object.ExportedFun
- GHC.StgToJS.Object: instance GHC.Classes.Ord GHC.StgToJS.Object.JSOptions
- GHC.StgToJS.Object: instance GHC.Classes.Ord GHC.StgToJS.Object.ObjectKind
- GHC.StgToJS.Regs: instance GHC.Classes.Eq GHC.StgToJS.Regs.Special
- GHC.StgToJS.Regs: instance GHC.Classes.Eq GHC.StgToJS.Regs.StgReg
- GHC.StgToJS.Regs: instance GHC.Classes.Eq GHC.StgToJS.Regs.StgRet
- GHC.StgToJS.Regs: instance GHC.Classes.Ord GHC.StgToJS.Regs.StgReg
- GHC.StgToJS.Regs: instance GHC.Classes.Ord GHC.StgToJS.Regs.StgRet
- GHC.StgToJS.Sinker: sinkPgm :: Module -> [CgStgTopBinding] -> (UniqFM Id CgStgExpr, [CgStgTopBinding])
- GHC.StgToJS.Symbols: hdRawStr :: FastString
- GHC.StgToJS.Symbols: hdStrStr :: FastString
- GHC.StgToJS.Types: StaticData :: !FastString -> [StaticArg] -> StaticVal
- GHC.StgToJS.Types: StaticFun :: !FastString -> [StaticArg] -> StaticVal
- GHC.StgToJS.Types: StaticThunk :: !Maybe (FastString, [StaticArg]) -> StaticVal
- GHC.StgToJS.Types: instance GHC.Classes.Eq GHC.StgToJS.Types.CILayout
- GHC.StgToJS.Types: instance GHC.Classes.Eq GHC.StgToJS.Types.CIRegs
- GHC.StgToJS.Types: instance GHC.Classes.Eq GHC.StgToJS.Types.CIStatic
- GHC.StgToJS.Types: instance GHC.Classes.Eq GHC.StgToJS.Types.CIType
- GHC.StgToJS.Types: instance GHC.Classes.Eq GHC.StgToJS.Types.ClosureInfo
- GHC.StgToJS.Types: instance GHC.Classes.Eq GHC.StgToJS.Types.ClosureType
- GHC.StgToJS.Types: instance GHC.Classes.Eq GHC.StgToJS.Types.ExpFun
- GHC.StgToJS.Types: instance GHC.Classes.Eq GHC.StgToJS.Types.ExprResult
- GHC.StgToJS.Types: instance GHC.Classes.Eq GHC.StgToJS.Types.ExprValData
- GHC.StgToJS.Types: instance GHC.Classes.Eq GHC.StgToJS.Types.IdKey
- GHC.StgToJS.Types: instance GHC.Classes.Eq GHC.StgToJS.Types.IdType
- GHC.StgToJS.Types: instance GHC.Classes.Eq GHC.StgToJS.Types.JSFFIType
- GHC.StgToJS.Types: instance GHC.Classes.Eq GHC.StgToJS.Types.JSRep
- GHC.StgToJS.Types: instance GHC.Classes.Eq GHC.StgToJS.Types.OtherSymb
- GHC.StgToJS.Types: instance GHC.Classes.Eq GHC.StgToJS.Types.StackSlot
- GHC.StgToJS.Types: instance GHC.Classes.Eq GHC.StgToJS.Types.StaticArg
- GHC.StgToJS.Types: instance GHC.Classes.Eq GHC.StgToJS.Types.StaticInfo
- GHC.StgToJS.Types: instance GHC.Classes.Eq GHC.StgToJS.Types.StaticLit
- GHC.StgToJS.Types: instance GHC.Classes.Eq GHC.StgToJS.Types.StaticUnboxed
- GHC.StgToJS.Types: instance GHC.Classes.Eq GHC.StgToJS.Types.StaticVal
- GHC.StgToJS.Types: instance GHC.Classes.Eq GHC.StgToJS.Types.ThreadStatus
- GHC.StgToJS.Types: instance GHC.Classes.Ord GHC.StgToJS.Types.CILayout
- GHC.StgToJS.Types: instance GHC.Classes.Ord GHC.StgToJS.Types.CIRegs
- GHC.StgToJS.Types: instance GHC.Classes.Ord GHC.StgToJS.Types.CIType
- GHC.StgToJS.Types: instance GHC.Classes.Ord GHC.StgToJS.Types.ClosureType
- GHC.StgToJS.Types: instance GHC.Classes.Ord GHC.StgToJS.Types.ExpFun
- GHC.StgToJS.Types: instance GHC.Classes.Ord GHC.StgToJS.Types.IdKey
- GHC.StgToJS.Types: instance GHC.Classes.Ord GHC.StgToJS.Types.IdType
- GHC.StgToJS.Types: instance GHC.Classes.Ord GHC.StgToJS.Types.JSFFIType
- GHC.StgToJS.Types: instance GHC.Classes.Ord GHC.StgToJS.Types.JSRep
- GHC.StgToJS.Types: instance GHC.Classes.Ord GHC.StgToJS.Types.OtherSymb
- GHC.StgToJS.Types: instance GHC.Classes.Ord GHC.StgToJS.Types.StackSlot
- GHC.StgToJS.Types: instance GHC.Classes.Ord GHC.StgToJS.Types.StaticUnboxed
- GHC.StgToJS.Types: instance GHC.Classes.Ord GHC.StgToJS.Types.ThreadStatus
- GHC.StgToJS.Utils: instance GHC.Classes.Eq GHC.StgToJS.Utils.SlotCount
- GHC.StgToJS.Utils: instance GHC.Classes.Ord GHC.StgToJS.Utils.SlotCount
- GHC.SysTools.Ar: instance GHC.Classes.Eq GHC.SysTools.Ar.Archive
- GHC.SysTools.Ar: instance GHC.Classes.Eq GHC.SysTools.Ar.ArchiveEntry
- GHC.SysTools.Process: BuildError :: !SrcLoc -> !SDoc -> BuildMessage
- GHC.SysTools.Process: BuildMsg :: !SDoc -> BuildMessage
- GHC.SysTools.Process: EOF :: BuildMessage
- GHC.SysTools.Process: breakColon :: String -> Maybe (String, String)
- GHC.SysTools.Process: breakIntColon :: String -> Maybe (Int, String)
- GHC.SysTools.Process: builderMainLoop :: Logger -> (String -> String) -> FilePath -> [String] -> Maybe FilePath -> Maybe [(String, String)] -> IO ExitCode
- GHC.SysTools.Process: c_locale_env :: (String, String)
- GHC.SysTools.Process: data BuildMessage
- GHC.SysTools.Process: enableProcessJobs :: CreateProcess -> CreateProcess
- GHC.SysTools.Process: handleProc :: String -> String -> IO (ExitCode, r) -> IO r
- GHC.SysTools.Process: linesPlatform :: String -> [String]
- GHC.SysTools.Process: parseError :: String -> Maybe (String, Int, Int, String)
- GHC.SysTools.Process: readProcessEnvWithExitCode :: String -> [String] -> (String, String) -> IO (ExitCode, String, String)
- GHC.SysTools.Process: readerProc :: Chan BuildMessage -> Handle -> (String -> String) -> IO ()
- GHC.SysTools.Process: replaceVar :: (String, String) -> [(String, String)] -> [(String, String)]
- GHC.SysTools.Tasks: augmentImports :: DynFlags -> [FilePath] -> [FilePath]
- GHC.SysTools.Tasks: cc_filter :: String -> String
- GHC.SysTools.Tasks: instance GHC.Classes.Eq GHC.SysTools.Tasks.SourceCodePreprocessor
- GHC.SysTools.Tasks: isContainedIn :: String -> String -> Bool
- GHC.Tc.Errors.Hole: instance GHC.Classes.Eq GHC.Tc.Errors.Hole.HoleFitSortingAlg
- GHC.Tc.Errors.Hole: instance GHC.Classes.Ord GHC.Tc.Errors.Hole.HoleFitSortingAlg
- GHC.Tc.Errors.Hole: pprHoleFit :: HoleFitDispConfig -> HoleFit -> SDoc
- GHC.Tc.Errors.Hole.FitTypes: instance GHC.Classes.Eq GHC.Tc.Errors.Hole.FitTypes.HoleFit
- GHC.Tc.Errors.Hole.FitTypes: instance GHC.Classes.Eq GHC.Tc.Errors.Hole.FitTypes.HoleFitCandidate
- GHC.Tc.Errors.Hole.FitTypes: instance GHC.Classes.Ord GHC.Tc.Errors.Hole.FitTypes.HoleFit
- GHC.Tc.Errors.Hole.FitTypes: instance GHC.Classes.Ord GHC.Tc.Errors.Hole.FitTypes.HoleFitCandidate
- GHC.Tc.Errors.Types: BlockedEquality :: ErrorItem -> TcSolverReportMsg
- GHC.Tc.Errors.Types: InstHeadNonClass :: !Maybe TyCon -> IllegalInstanceHeadReason
- GHC.Tc.Errors.Types: KindMismatch :: TypedThing -> Type -> Type -> MismatchMsg
- GHC.Tc.Errors.Types: QuotedNameWrongStage :: !HsQuote GhcPs -> THNameError
- GHC.Tc.Errors.Types: StageCheckInstance :: !InstanceWhat -> !PredType -> StageCheckReason
- GHC.Tc.Errors.Types: StageCheckSplice :: !Name -> StageCheckReason
- GHC.Tc.Errors.Types: TypeApplication :: !HsType GhcPs -> !TypeOrKind -> TypeApplication
- GHC.Tc.Errors.Types: TypeApplicationInPattern :: !HsConPatTyArg GhcPs -> TypeApplication
- GHC.Tc.Errors.Types: [BackpackUnpackAbstractType] :: BadFieldAnnotationReason
- GHC.Tc.Errors.Types: [TcRnBadlyStagedType] :: !Name -> !Int -> !Int -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnBadlyStaged] :: !StageCheckReason -> !Int -> !Int -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnDeprecatedInvisTyArgInConPat] :: TcRnMessage
- GHC.Tc.Errors.Types: [TcRnInvisPatWithNoForAll] :: HsTyPat GhcRn -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnMisplacedInvisPat] :: HsTyPat GhcPs -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnStageRestriction] :: !StageCheckReason -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnTooManyTyArgsInConPattern] :: !ConLike -> !Int -> !Int -> TcRnMessage
- GHC.Tc.Errors.Types: [cannotResolve_importErrors] :: TcSolverReportMsg -> [ImportError]
- GHC.Tc.Errors.Types: [cannotResolve_relevant_bindings] :: TcSolverReportMsg -> RelevantBindings
- GHC.Tc.Errors.Types: [cannotResolve_suggestions] :: TcSolverReportMsg -> [GhcHint]
- GHC.Tc.Errors.Types: [kmismatch_actual] :: MismatchMsg -> Type
- GHC.Tc.Errors.Types: [kmismatch_expected] :: MismatchMsg -> Type
- GHC.Tc.Errors.Types: [kmismatch_what] :: MismatchMsg -> TypedThing
- GHC.Tc.Errors.Types: data SolverReportSupplementary
- GHC.Tc.Errors.Types: data StageCheckReason
- GHC.Tc.Errors.Types: data TypeApplication
- GHC.Tc.Errors.Types: instance GHC.Classes.Eq GHC.Tc.Errors.Types.AssociatedTyLastVarInKind
- GHC.Tc.Errors.Types: instance GHC.Classes.Eq GHC.Tc.Errors.Types.AssociatedTyNotParamOverLastTyVar
- GHC.Tc.Errors.Types: instance GHC.Classes.Eq GHC.Tc.Errors.Types.DeriveAnyClassEnabled
- GHC.Tc.Errors.Types: instance GHC.Classes.Eq GHC.Tc.Errors.Types.Exported
- GHC.Tc.Errors.Types: instance GHC.Classes.Eq GHC.Tc.Errors.Types.HasAssociatedDataFamInsts
- GHC.Tc.Errors.Types: instance GHC.Classes.Eq GHC.Tc.Errors.Types.HasKinds
- GHC.Tc.Errors.Types: instance GHC.Classes.Eq GHC.Tc.Errors.Types.HasWildcard
- GHC.Tc.Errors.Types: instance GHC.Classes.Eq GHC.Tc.Errors.Types.SuggestPartialTypeSignatures
- GHC.Tc.Errors.Types: instance GHC.Classes.Eq GHC.Tc.Errors.Types.SuggestUndecidableInstances
- GHC.Tc.Errors.Types: instance GHC.Classes.Eq GHC.Tc.Errors.Types.UnsupportedCallConvention
- GHC.Tc.Errors.Types: instance GHC.Classes.Eq GHC.Tc.Errors.Types.UsingGeneralizedNewtypeDeriving
- GHC.Tc.Errors.Types: instance GHC.Internal.Generics.Generic GHC.Tc.Errors.Types.TypeApplication
- GHC.Tc.Errors.Types: mkTcRnNotInScope :: RdrName -> NotInScopeError -> TcRnMessage
- GHC.Tc.Gen.Annotation: annCtxt :: forall (p :: Pass). OutputableBndrId p => AnnDecl (GhcPass p) -> SDoc
- GHC.Tc.Gen.App: tcInferSigma :: Bool -> LHsExpr GhcRn -> TcM TcSigmaType
- GHC.Tc.Gen.Default: tcDefaults :: [LDefaultDecl GhcRn] -> TcM DefaultEnv
- GHC.Tc.Gen.Head: fieldNotInType :: RecSelParent -> RdrName -> TcRnMessage
- GHC.Tc.Gen.HsType: RuleSigCtxt :: FastString -> Name -> UserTypeCtxt
- GHC.Tc.Gen.HsType: addTyConFlavCtxt :: Name -> TyConFlavour tc -> TcM a -> TcM a
- GHC.Tc.Gen.HsType: funAppCtxt :: (Outputable fun, Outputable arg) => fun -> arg -> Int -> SDoc
- GHC.Tc.Gen.Match: tcGRHSList :: AnnoBody body => HsMatchContextRn -> TcMatchAltChecker body -> [LGRHS GhcRn (LocatedA (body GhcRn))] -> ExpRhoType -> TcM [LGRHS GhcTc (LocatedA (body GhcTc))]
- GHC.Tc.Gen.Rule: tcRules :: [LRuleDecls GhcRn] -> TcM [LRuleDecls GhcTc]
- GHC.Tc.Instance.Family: tcInstNewTyCon_maybe :: TyCon -> [TcType] -> Maybe (TcType, TcCoercion)
- GHC.Tc.Solver: instance GHC.Utils.Outputable.Outputable GHC.Tc.Solver.Proposal
- GHC.Tc.Solver: instance GHC.Utils.Outputable.Outputable GHC.Tc.Solver.ProposalSequence
- GHC.Tc.Solver: solveWanteds :: WantedConstraints -> TcS WantedConstraints
- GHC.Tc.Solver.InertSet: [inert_insts] :: InertCans -> [QCInst]
- GHC.Tc.Solver.InertSet: [wl_implics] :: WorkList -> Bag Implication
- GHC.Tc.Solver.InertSet: emptyInert :: InertSet
- GHC.Tc.Solver.InertSet: extendWorkListEqs :: RewriterSet -> Bag Ct -> WorkList -> WorkList
- GHC.Tc.Solver.InertSet: extendWorkListImplic :: Implication -> WorkList -> WorkList
- GHC.Tc.Solver.InertSet: instance GHC.Classes.Eq GHC.Tc.Solver.InertSet.WhereToLook
- GHC.Tc.Solver.InertSet: mightEqualLater :: InertSet -> TcPredType -> CtLoc -> TcPredType -> CtLoc -> Maybe Subst
- GHC.Tc.Solver.InertSet: noMatchableGivenDicts :: InertSet -> CtLoc -> Class -> [TcType] -> Bool
- GHC.Tc.Solver.InertSet: selectWorkItem :: WorkList -> Maybe (Ct, WorkList)
- GHC.Tc.Solver.Monad: [qci_pred] :: QCInst -> TcPredType
- GHC.Tc.Solver.Monad: addInertForAll :: QCInst -> TcS ()
- GHC.Tc.Solver.Monad: addInertSafehask :: InertCans -> DictCt -> InertCans
- GHC.Tc.Solver.Monad: checkTouchableTyVarEq :: CtEvidence -> TcTyVar -> TcType -> TcS (PuResult () Reduction)
- GHC.Tc.Solver.Monad: checkWellStagedDFun :: CtLoc -> InstanceWhat -> PredType -> TcS ()
- GHC.Tc.Solver.Monad: data TcS a
- GHC.Tc.Solver.Monad: emitImplicationTcS :: TcLevel -> SkolemInfoAnon -> [TcTyVar] -> [EvVar] -> Cts -> TcS TcEvBinds
- GHC.Tc.Solver.Monad: emitTvImplicationTcS :: TcLevel -> SkolemInfoAnon -> [TcTyVar] -> Cts -> TcS ()
- GHC.Tc.Solver.Monad: updInertSafehask :: (DictMap DictCt -> DictMap DictCt) -> TcS ()
- GHC.Tc.TyCl: tcAddTyFamInstCtxt :: TyFamInstDecl GhcRn -> TcM a -> TcM a
- GHC.Tc.Types: RnPendingUntyped :: TcRef [PendingRnSplice] -> PendingStuff
- GHC.Tc.Types: [tcg_hpc] :: TcGblEnv -> !AnyHpcUsage
- GHC.Tc.Types: [tcg_th_splice_used] :: TcGblEnv -> TcRef Bool
- GHC.Tc.Types: data ThStage
- GHC.Tc.Types: impLevel :: ThLevel
- GHC.Tc.Types: instance GHC.Classes.Eq GHC.Tc.Types.DocLoc
- GHC.Tc.Types: instance GHC.Classes.Ord GHC.Tc.Types.DocLoc
- GHC.Tc.Types: outerLevel :: ThLevel
- GHC.Tc.Types: thLevel :: ThStage -> ThLevel
- GHC.Tc.Types: topAnnStage :: ThStage
- GHC.Tc.Types: topSpliceStage :: ThStage
- GHC.Tc.Types: topStage :: ThStage
- GHC.Tc.Types: type ThLevel = Int
- GHC.Tc.Types.Constraint: ContainsCast :: TcType -> TcCoercionN -> NotConcreteReason
- GHC.Tc.Types.Constraint: ContainsCoercionTy :: TcCoercion -> NotConcreteReason
- GHC.Tc.Types.Constraint: ContainsForall :: ForAllTyBinder -> TcType -> NotConcreteReason
- GHC.Tc.Types.Constraint: NonConcreteTyCon :: TyCon -> [TcType] -> NotConcreteReason
- GHC.Tc.Types.Constraint: NonConcretisableTyVar :: TyVar -> NotConcreteReason
- GHC.Tc.Types.Constraint: [ic_need_inner] :: Implication -> VarSet
- GHC.Tc.Types.Constraint: [ic_need_outer] :: Implication -> VarSet
- GHC.Tc.Types.Constraint: [nce_reasons] :: NotConcreteError -> NonEmpty NotConcreteReason
- GHC.Tc.Types.Constraint: [qci_pred] :: QCInst -> TcPredType
- GHC.Tc.Types.Constraint: cteCoercionHole :: CheckTyEqProblem
- GHC.Tc.Types.Constraint: data NotConcreteReason
- GHC.Tc.Types.Constraint: instance GHC.Classes.Eq GHC.Tc.Types.Constraint.CheckTyEqProblem
- GHC.Tc.Types.Constraint: instance GHC.Classes.Eq GHC.Tc.Types.Constraint.CtFlavour
- GHC.Tc.Types.Constraint: instance GHC.Classes.Eq GHC.Tc.Types.Constraint.HasGivenEqs
- GHC.Tc.Types.Constraint: instance GHC.Utils.Outputable.Outputable GHC.Tc.Types.Constraint.CanEqLHS
- GHC.Tc.Types.CtLoc: instance GHC.Classes.Eq GHC.Tc.Types.CtLoc.SubGoalDepth
- GHC.Tc.Types.CtLoc: instance GHC.Classes.Ord GHC.Tc.Types.CtLoc.SubGoalDepth
- GHC.Tc.Types.EvTerm: evCallStack :: (MonadThings m, HasModule m, HasDynFlags m) => EvCallStack -> m EvExpr
- GHC.Tc.Types.EvTerm: evDelayedError :: Type -> String -> EvTerm
- GHC.Tc.Types.Evidence: WpMultCoercion :: Coercion -> HsWrapper
- GHC.Tc.Types.Evidence: evDataConApp :: DataCon -> [Type] -> [EvExpr] -> EvTerm
- GHC.Tc.Types.Evidence: evVarsOfTerm :: EvTerm -> VarSet
- GHC.Tc.Types.Evidence: findNeededEvVars :: EvBindMap -> VarSet -> VarSet
- GHC.Tc.Types.Evidence: type MultiplicityCheckCoercions = [TcCoercion]
- GHC.Tc.Types.Evidence: unwrapIP :: Type -> CoercionR
- GHC.Tc.Types.Evidence: wrapIP :: Type -> CoercionR
- GHC.Tc.Types.LclEnv: getLclEnvThStage :: TcLclEnv -> ThStage
- GHC.Tc.Types.LclEnv: setLclEnvThStage :: ThStage -> TcLclEnv -> TcLclEnv
- GHC.Tc.Types.Origin: DerivClauseOrigin :: CtOrigin
- GHC.Tc.Types.Origin: HasFieldOrigin :: FastString -> CtOrigin
- GHC.Tc.Types.Origin: RuleSigCtxt :: FastString -> Name -> UserTypeCtxt
- GHC.Tc.Types.Origin: StandAloneDerivOrigin :: CtOrigin
- GHC.Tc.Types.Origin: callStackOriginFS :: CtOrigin -> FastString
- GHC.Tc.Types.Origin: instance GHC.Classes.Eq GHC.Tc.Types.Origin.ReportRedundantConstraints
- GHC.Tc.Types.Origin: instance GHC.Classes.Eq GHC.Tc.Types.Origin.UserTypeCtxt
- GHC.Tc.Types.Origin: isPushCallStackOrigin :: CtOrigin -> Bool
- GHC.Tc.Types.Origin: mkClsInstSkol :: Class -> [Type] -> SkolemInfoAnon
- GHC.Tc.Types.TH: RnPendingUntyped :: TcRef [PendingRnSplice] -> PendingStuff
- GHC.Tc.Types.TH: data ThStage
- GHC.Tc.Types.TH: impLevel :: ThLevel
- GHC.Tc.Types.TH: instance GHC.Utils.Outputable.Outputable GHC.Tc.Types.TH.ThStage
- GHC.Tc.Types.TH: outerLevel :: ThLevel
- GHC.Tc.Types.TH: thLevel :: ThStage -> ThLevel
- GHC.Tc.Types.TH: topAnnStage :: ThStage
- GHC.Tc.Types.TH: topSpliceStage :: ThStage
- GHC.Tc.Types.TH: topStage :: ThStage
- GHC.Tc.Types.TH: type ThLevel = Int
- GHC.Tc.Utils.Env: StageCheckInstance :: !InstanceWhat -> !PredType -> StageCheckReason
- GHC.Tc.Utils.Env: StageCheckSplice :: !Name -> StageCheckReason
- GHC.Tc.Utils.Env: checkWellStaged :: StageCheckReason -> ThLevel -> ThLevel -> TcM ()
- GHC.Tc.Utils.Env: data StageCheckReason
- GHC.Tc.Utils.Env: failIllegalTyVal :: Name -> TcM a
- GHC.Tc.Utils.Env: isBrackStage :: ThStage -> Bool
- GHC.Tc.Utils.Env: thLevel :: ThStage -> ThLevel
- GHC.Tc.Utils.Env: topIdLvl :: Id -> ThLevel
- GHC.Tc.Utils.Monad: getStage :: TcM ThStage
- GHC.Tc.Utils.Monad: getStageAndBindLevel :: Name -> TcRn (Maybe (TopLevelFlag, ThLevel, ThStage))
- GHC.Tc.Utils.Monad: mkErrInfo :: TidyEnv -> [ErrCtxt] -> TcM SDoc
- GHC.Tc.Utils.Monad: recordThSpliceUse :: TcM ()
- GHC.Tc.Utils.Monad: setStage :: ThStage -> TcM a -> TcRn a
- GHC.Tc.Utils.TcMType: emitWantedEvVars :: CtOrigin -> [TcPredType] -> TcM [EvVar]
- GHC.Tc.Utils.TcMType: isQuantifiableTv :: TcLevel -> TcTyVar -> Bool
- GHC.Tc.Utils.TcMType: newCoercionHoleO :: CtOrigin -> TcPredType -> TcM CoercionHole
- GHC.Tc.Utils.TcMType: newVanillaCoercionHole :: TcPredType -> TcM CoercionHole
- GHC.Tc.Utils.TcMType: tcInfer :: (ExpSigmaType -> TcM a) -> TcM (a, TcSigmaType)
- GHC.Tc.Utils.TcMType: tcInferFRR :: FixedRuntimeRepContext -> (ExpSigmaTypeFRR -> TcM a) -> TcM (a, TcSigmaTypeFRR)
- GHC.Tc.Utils.TcMType: unpackCoercionHole :: CoercionHole -> TcM Coercion
- GHC.Tc.Utils.TcMType: unpackCoercionHole_maybe :: CoercionHole -> TcM (Maybe Coercion)
- GHC.Tc.Utils.TcType: getSubstInScope :: Subst -> InScopeSet
- GHC.Tc.Utils.TcType: isConcreteInfo :: MetaInfo -> Bool
- GHC.Tc.Utils.TcType: isEqPrimPred :: PredType -> Bool
- GHC.Tc.Utils.TcType: isIPLikePred :: Type -> Bool
- GHC.Tc.Utils.Unify: LC_Check :: LevelCheck
- GHC.Tc.Utils.Unify: LC_None :: LevelCheck
- GHC.Tc.Utils.Unify: LC_Promote :: Bool -> LevelCheck
- GHC.Tc.Utils.Unify: NotUnifying :: AreUnifying
- GHC.Tc.Utils.Unify: TEF :: Bool -> CanEqLHS -> AreUnifying -> TyEqFamApp a -> CheckTyEqProblem -> TyEqFlags a
- GHC.Tc.Utils.Unify: TEFA_Break :: FamAppBreaker a -> TyEqFamApp a
- GHC.Tc.Utils.Unify: TEFA_Fail :: TyEqFamApp a
- GHC.Tc.Utils.Unify: TEFA_Recurse :: TyEqFamApp a
- GHC.Tc.Utils.Unify: UC_Defaulting :: UnifyCheckCaller
- GHC.Tc.Utils.Unify: Unifying :: MetaInfo -> TcLevel -> LevelCheck -> AreUnifying
- GHC.Tc.Utils.Unify: [tef_foralls] :: TyEqFlags a -> Bool
- GHC.Tc.Utils.Unify: [tef_lhs] :: TyEqFlags a -> CanEqLHS
- GHC.Tc.Utils.Unify: [tef_occurs] :: TyEqFlags a -> CheckTyEqProblem
- GHC.Tc.Utils.Unify: [tef_unifying] :: TyEqFlags a -> AreUnifying
- GHC.Tc.Utils.Unify: data AreUnifying
- GHC.Tc.Utils.Unify: failCheckWith :: CheckTyEqResult -> TcM (PuResult a b)
- GHC.Tc.Utils.Unify: famAppArgFlags :: TyEqFlags a -> TyEqFlags a
- GHC.Tc.Utils.Unify: instance GHC.Utils.Outputable.Outputable (GHC.Tc.Utils.Unify.TyEqFamApp a)
- GHC.Tc.Utils.Unify: instance GHC.Utils.Outputable.Outputable (GHC.Tc.Utils.Unify.TyEqFlags a)
- GHC.Tc.Utils.Unify: instance GHC.Utils.Outputable.Outputable GHC.Tc.Utils.Unify.AreUnifying
- GHC.Tc.Utils.Unify: instance GHC.Utils.Outputable.Outputable GHC.Tc.Utils.Unify.LevelCheck
- GHC.Tc.Utils.Unify: tcInfer :: (ExpSigmaType -> TcM a) -> TcM (a, TcSigmaType)
- GHC.Tc.Utils.Unify: tcSubMult' :: CtOrigin -> Mult -> Mult -> TcM MultiplicityCheckCoercions
- GHC.Tc.Utils.Unify: touchabilityAndShapeTest :: TcLevel -> TcTyVar -> TcType -> Bool
- GHC.Tc.Utils.Unify: type FamAppBreaker a = TcType -> TcM PuResult a Reduction
- GHC.Tc.Utils.Unify: unifyExpectedType :: HsExpr GhcRn -> TcRhoType -> ExpRhoType -> TcM TcCoercionN
- GHC.Tc.Validity: RuleSigCtxt :: FastString -> Name -> UserTypeCtxt
- GHC.Tc.Validity: instance GHC.Classes.Eq GHC.Tc.Validity.TypeOrKindCtxt
- GHC.Tc.Zonk.Type: instance GHC.Internal.Base.Monoid GHC.Tc.Zonk.Type.UnfilledCoercionHoleMonoid
- GHC.Tc.Zonk.Type: instance GHC.Internal.Base.Semigroup GHC.Tc.Zonk.Type.UnfilledCoercionHoleMonoid
- GHC.Tc.Zonk.Type: isFilledCoercionHole :: CoercionHole -> TcM Bool
- GHC.Tc.Zonk.Type: unpackCoercionHole :: CoercionHole -> TcM Coercion
- GHC.Tc.Zonk.Type: unpackCoercionHole_maybe :: CoercionHole -> TcM (Maybe Coercion)
- GHC.Tc.Zonk.Type: zonkCtEvRewriterSet :: CtEvidence -> TcM CtEvidence
- GHC.Tc.Zonk.Type: zonkCtRewriterSet :: Ct -> TcM Ct
- GHC.Tc.Zonk.Type: zonkRewriterSet :: RewriterSet -> TcM RewriterSet
- GHC.Types.Basic: instance Control.DeepSeq.NFData tc => Control.DeepSeq.NFData (GHC.Types.Basic.TyConFlavour tc)
- GHC.Types.Basic: instance GHC.Classes.Eq GHC.Types.Basic.Activation
- GHC.Types.Basic: instance GHC.Classes.Eq GHC.Types.Basic.Alignment
- GHC.Types.Basic: instance GHC.Classes.Eq GHC.Types.Basic.CbvMark
- GHC.Types.Basic: instance GHC.Classes.Eq GHC.Types.Basic.CompilerPhase
- GHC.Types.Basic: instance GHC.Classes.Eq GHC.Types.Basic.DoPmc
- GHC.Types.Basic: instance GHC.Classes.Eq GHC.Types.Basic.FunctionOrData
- GHC.Types.Basic: instance GHC.Classes.Eq GHC.Types.Basic.GenReason
- GHC.Types.Basic: instance GHC.Classes.Eq GHC.Types.Basic.InlinePragma
- GHC.Types.Basic: instance GHC.Classes.Eq GHC.Types.Basic.InlineSpec
- GHC.Types.Basic: instance GHC.Classes.Eq GHC.Types.Basic.InsideLam
- GHC.Types.Basic: instance GHC.Classes.Eq GHC.Types.Basic.IntWithInf
- GHC.Types.Basic: instance GHC.Classes.Eq GHC.Types.Basic.InterestingCxt
- GHC.Types.Basic: instance GHC.Classes.Eq GHC.Types.Basic.LeftOrRight
- GHC.Types.Basic: instance GHC.Classes.Eq GHC.Types.Basic.Levity
- GHC.Types.Basic: instance GHC.Classes.Eq GHC.Types.Basic.OccInfo
- GHC.Types.Basic: instance GHC.Classes.Eq GHC.Types.Basic.OneShotInfo
- GHC.Types.Basic: instance GHC.Classes.Eq GHC.Types.Basic.Origin
- GHC.Types.Basic: instance GHC.Classes.Eq GHC.Types.Basic.OverlapFlag
- GHC.Types.Basic: instance GHC.Classes.Eq GHC.Types.Basic.OverlapMode
- GHC.Types.Basic: instance GHC.Classes.Eq GHC.Types.Basic.PprPrec
- GHC.Types.Basic: instance GHC.Classes.Eq GHC.Types.Basic.RecFlag
- GHC.Types.Basic: instance GHC.Classes.Eq GHC.Types.Basic.RuleMatchInfo
- GHC.Types.Basic: instance GHC.Classes.Eq GHC.Types.Basic.SwapFlag
- GHC.Types.Basic: instance GHC.Classes.Eq GHC.Types.Basic.TailCallInfo
- GHC.Types.Basic: instance GHC.Classes.Eq GHC.Types.Basic.TupleSort
- GHC.Types.Basic: instance GHC.Classes.Eq GHC.Types.Basic.TypeOrConstraint
- GHC.Types.Basic: instance GHC.Classes.Eq GHC.Types.Basic.TypeOrData
- GHC.Types.Basic: instance GHC.Classes.Eq GHC.Types.Basic.TypeOrKind
- GHC.Types.Basic: instance GHC.Classes.Eq GHC.Types.Basic.UnboxedTupleOrSum
- GHC.Types.Basic: instance GHC.Classes.Eq tc => GHC.Classes.Eq (GHC.Types.Basic.TyConFlavour tc)
- GHC.Types.Basic: instance GHC.Classes.Ord GHC.Types.Basic.Alignment
- GHC.Types.Basic: instance GHC.Classes.Ord GHC.Types.Basic.FunctionOrData
- GHC.Types.Basic: instance GHC.Classes.Ord GHC.Types.Basic.IntWithInf
- GHC.Types.Basic: instance GHC.Classes.Ord GHC.Types.Basic.LeftOrRight
- GHC.Types.Basic: instance GHC.Classes.Ord GHC.Types.Basic.Levity
- GHC.Types.Basic: instance GHC.Classes.Ord GHC.Types.Basic.PprPrec
- GHC.Types.Basic: instance GHC.Classes.Ord GHC.Types.Basic.TupleSort
- GHC.Types.Basic: instance GHC.Classes.Ord GHC.Types.Basic.TypeOrConstraint
- GHC.Types.Breakpoint: BreakpointId :: !Module -> !Int -> BreakpointId
- GHC.Types.Breakpoint: InternalBreakpointId :: !Module -> !Int -> !Module -> !Int -> InternalBreakpointId
- GHC.Types.Breakpoint: [bi_tick_index] :: BreakpointId -> !Int
- GHC.Types.Breakpoint: [bi_tick_mod] :: BreakpointId -> !Module
- GHC.Types.Breakpoint: [ibi_info_index] :: InternalBreakpointId -> !Int
- GHC.Types.Breakpoint: [ibi_info_mod] :: InternalBreakpointId -> !Module
- GHC.Types.Breakpoint: [ibi_tick_index] :: InternalBreakpointId -> !Int
- GHC.Types.Breakpoint: [ibi_tick_mod] :: InternalBreakpointId -> !Module
- GHC.Types.Breakpoint: data BreakpointId
- GHC.Types.Breakpoint: data InternalBreakpointId
- GHC.Types.Breakpoint: toBreakpointId :: InternalBreakpointId -> BreakpointId
- GHC.Types.CompleteMatch: instance GHC.Classes.Eq (GHC.Types.CompleteMatch.CompleteMatchX con)
- GHC.Types.CostCentre: instance GHC.Classes.Eq GHC.Types.CostCentre.CCFlavour
- GHC.Types.CostCentre: instance GHC.Classes.Eq GHC.Types.CostCentre.CostCentre
- GHC.Types.CostCentre: instance GHC.Classes.Eq GHC.Types.CostCentre.CostCentreStack
- GHC.Types.CostCentre: instance GHC.Classes.Eq GHC.Types.CostCentre.IndexedCCFlavour
- GHC.Types.CostCentre: instance GHC.Classes.Ord GHC.Types.CostCentre.CCFlavour
- GHC.Types.CostCentre: instance GHC.Classes.Ord GHC.Types.CostCentre.CostCentre
- GHC.Types.CostCentre: instance GHC.Classes.Ord GHC.Types.CostCentre.CostCentreStack
- GHC.Types.CostCentre: instance GHC.Classes.Ord GHC.Types.CostCentre.IndexedCCFlavour
- GHC.Types.CostCentre.State: instance GHC.Classes.Eq GHC.Types.CostCentre.State.CostCentreIndex
- GHC.Types.CostCentre.State: instance GHC.Classes.Ord GHC.Types.CostCentre.State.CostCentreIndex
- GHC.Types.Cpr: instance GHC.Classes.Eq GHC.Types.Cpr.Cpr
- GHC.Types.Cpr: instance GHC.Classes.Eq GHC.Types.Cpr.CprSig
- GHC.Types.Cpr: instance GHC.Classes.Eq GHC.Types.Cpr.CprType
- GHC.Types.DefaultEnv: [cd_module] :: ClassDefaults -> Maybe Module
- GHC.Types.Demand: instance GHC.Classes.Eq GHC.Types.Demand.Card
- GHC.Types.Demand: instance GHC.Classes.Eq GHC.Types.Demand.Demand
- GHC.Types.Demand: instance GHC.Classes.Eq GHC.Types.Demand.Divergence
- GHC.Types.Demand: instance GHC.Classes.Eq GHC.Types.Demand.DmdEnv
- GHC.Types.Demand: instance GHC.Classes.Eq GHC.Types.Demand.DmdSig
- GHC.Types.Demand: instance GHC.Classes.Eq GHC.Types.Demand.DmdType
- GHC.Types.Demand: instance GHC.Classes.Eq GHC.Types.Demand.SubDemand
- GHC.Types.Error: DiagnosticHint :: !SDoc -> DiagnosticHint
- GHC.Types.Error: data DiagnosticHint
- GHC.Types.Error: instance GHC.Classes.Eq GHC.Types.Error.DiagnosticCode
- GHC.Types.Error: instance GHC.Classes.Eq GHC.Types.Error.DiagnosticReason
- GHC.Types.Error: instance GHC.Classes.Eq GHC.Types.Error.Severity
- GHC.Types.Error: instance GHC.Classes.Ord GHC.Types.Error.DiagnosticCode
- GHC.Types.Error: instance GHC.Classes.Ord GHC.Types.Error.Severity
- GHC.Types.Error: instance GHC.Types.Error.HasDefaultDiagnosticOpts opts => GHC.Types.Error.Diagnostic (GHC.Types.Error.UnknownDiagnostic opts)
- GHC.Types.Error: instance GHC.Utils.Outputable.Outputable GHC.Types.Error.DiagnosticHint
- GHC.Types.Error.Codes: instance (GHC.Types.Error.Codes.ConRecursInto con GHC.Types.~ 'GHC.Internal.Maybe.Just (GHC.Types.Error.UnknownDiagnostic opts)) => GHC.Types.Error.Codes.ConstructorCodes con f seen ('GHC.Internal.Maybe.Just (GHC.Types.Error.UnknownDiagnostic opts))
- GHC.Types.Error.Codes: instance (GHC.Types.Error.Codes.ConRecursInto con GHC.Types.~ 'GHC.Internal.Maybe.Just (GHC.Types.Error.UnknownDiagnostic opts), GHC.Types.Error.Codes.HasType (GHC.Types.Error.UnknownDiagnostic opts) con f) => GHC.Types.Error.Codes.ConstructorCode con f ('GHC.Internal.Maybe.Just (GHC.Types.Error.UnknownDiagnostic opts))
- GHC.Types.Error.Codes: instance (GHC.Types.Error.Codes.ConRecursInto con GHC.Types.~ 'GHC.Internal.Maybe.Just ty, GHC.Types.Error.Codes.HasType ty con f, GHC.Internal.Generics.Generic ty, GHC.Types.Error.Codes.GDiagnosticCode (GHC.Internal.Generics.Rep ty)) => GHC.Types.Error.Codes.ConstructorCode con f ('GHC.Internal.Maybe.Just ty)
- GHC.Types.Error.Codes: instance (GHC.Types.Error.Codes.ConRecursInto con GHC.Types.~ 'GHC.Internal.Maybe.Just ty, GHC.Types.Error.Codes.HasType ty con f, GHC.Internal.Generics.Generic ty, GHC.Types.Error.Codes.GDiagnosticCodes (GHC.Types.Error.Codes.Insert ty seen) (GHC.Internal.Generics.Rep ty), GHC.Types.Error.Codes.Seen seen ty) => GHC.Types.Error.Codes.ConstructorCodes con f seen ('GHC.Internal.Maybe.Just ty)
- GHC.Types.Error.Codes: instance (GHC.Types.Error.Codes.ConstructorCode con f recur, recur GHC.Types.~ GHC.Types.Error.Codes.ConRecursInto con, GHC.Internal.TypeLits.KnownSymbol con) => GHC.Types.Error.Codes.GDiagnosticCode (GHC.Internal.Generics.M1 i ('GHC.Internal.Generics.MetaCons con x y) f)
- GHC.Types.Error.Codes: instance (GHC.Types.Error.Codes.ConstructorCodes con f seen recur, recur GHC.Types.~ GHC.Types.Error.Codes.ConRecursInto con, GHC.Internal.TypeLits.KnownSymbol con) => GHC.Types.Error.Codes.GDiagnosticCodes seen (GHC.Internal.Generics.M1 i ('GHC.Internal.Generics.MetaCons con x y) f)
- GHC.Types.Error.Codes: instance (GHC.Types.Error.Codes.GDiagnosticCode f, GHC.Types.Error.Codes.GDiagnosticCode g) => GHC.Types.Error.Codes.GDiagnosticCode (f GHC.Internal.Generics.:+: g)
- GHC.Types.Error.Codes: instance (GHC.Types.Error.Codes.GDiagnosticCodes seen f, GHC.Types.Error.Codes.GDiagnosticCodes seen g) => GHC.Types.Error.Codes.GDiagnosticCodes seen (f GHC.Internal.Generics.:+: g)
- GHC.Types.Error.Codes: instance (GHC.Types.Error.Codes.KnownConstructor con, GHC.Internal.TypeLits.KnownSymbol con) => GHC.Types.Error.Codes.ConstructorCode con f 'GHC.Internal.Maybe.Nothing
- GHC.Types.Error.Codes: instance (GHC.Types.Error.Codes.KnownConstructor con, GHC.Internal.TypeLits.KnownSymbol con) => GHC.Types.Error.Codes.ConstructorCodes con f seen 'GHC.Internal.Maybe.Nothing
- GHC.Types.Error.Codes: instance (TypeError ...) => GHC.Types.Error.Codes.HasType ty orig f
- GHC.Types.Error.Codes: instance GHC.Types.Error.Codes.GDiagnosticCode f => GHC.Types.Error.Codes.GDiagnosticCode (GHC.Internal.Generics.M1 i ('GHC.Internal.Generics.MetaData nm mod pkg nt) f)
- GHC.Types.Error.Codes: instance GHC.Types.Error.Codes.GDiagnosticCodes seen f => GHC.Types.Error.Codes.GDiagnosticCodes seen (GHC.Internal.Generics.M1 i ('GHC.Internal.Generics.MetaData nm mod pkg nt) f)
- GHC.Types.Error.Codes: instance GHC.Types.Error.Codes.HasType ty orig (GHC.Internal.Generics.M1 i s (GHC.Internal.Generics.K1 x ty))
- GHC.Types.Error.Codes: instance GHC.Types.Error.Codes.HasType ty orig g => GHC.Types.Error.Codes.HasTypeProd ty 'GHC.Internal.Maybe.Nothing orig f g
- GHC.Types.Error.Codes: instance GHC.Types.Error.Codes.HasTypeProd ty (GHC.Types.Error.Codes.HasTypeQ ty f) orig f g => GHC.Types.Error.Codes.HasType ty orig (f GHC.Internal.Generics.:*: g)
- GHC.Types.Error.Codes: instance forall a ty (orig :: GHC.Types.Symbol) (f :: * -> *) (l :: a) (g :: * -> *). GHC.Types.Error.Codes.HasType ty orig f => GHC.Types.Error.Codes.HasTypeProd ty ('GHC.Internal.Maybe.Just l) orig f g
- GHC.Types.FieldLabel: instance GHC.Classes.Eq GHC.Types.FieldLabel.DuplicateRecordFields
- GHC.Types.FieldLabel: instance GHC.Classes.Eq GHC.Types.FieldLabel.FieldLabel
- GHC.Types.FieldLabel: instance GHC.Classes.Eq GHC.Types.FieldLabel.FieldSelectors
- GHC.Types.ForeignCall: instance GHC.Classes.Eq GHC.Types.ForeignCall.CCallConv
- GHC.Types.ForeignCall: instance GHC.Classes.Eq GHC.Types.ForeignCall.CCallSpec
- GHC.Types.ForeignCall: instance GHC.Classes.Eq GHC.Types.ForeignCall.CCallTarget
- GHC.Types.ForeignCall: instance GHC.Classes.Eq GHC.Types.ForeignCall.CType
- GHC.Types.ForeignCall: instance GHC.Classes.Eq GHC.Types.ForeignCall.ForeignCall
- GHC.Types.ForeignCall: instance GHC.Classes.Eq GHC.Types.ForeignCall.Header
- GHC.Types.ForeignCall: instance GHC.Classes.Eq GHC.Types.ForeignCall.Safety
- GHC.Types.GREInfo: instance Control.DeepSeq.NFData GHC.Types.GREInfo.GREInfo
- GHC.Types.GREInfo: instance GHC.Classes.Eq GHC.Types.GREInfo.ConFieldInfo
- GHC.Types.GREInfo: instance GHC.Classes.Eq GHC.Types.GREInfo.ConInfo
- GHC.Types.GREInfo: instance GHC.Classes.Eq GHC.Types.GREInfo.ConLikeInfo
- GHC.Types.GREInfo: instance GHC.Classes.Eq GHC.Types.GREInfo.ConLikeName
- GHC.Types.GREInfo: instance GHC.Classes.Eq GHC.Types.GREInfo.RecFieldInfo
- GHC.Types.Hint: CouldAddTypeKeyword :: ModuleName -> ImportSuggestion
- GHC.Types.Hint: CouldRemoveTypeKeyword :: ModuleName -> ImportSuggestion
- GHC.Types.Hint: instance GHC.Classes.Eq GHC.Types.Hint.AssumedDerivingStrategy
- GHC.Types.Hint: instance GHC.Classes.Ord GHC.Types.Hint.AssumedDerivingStrategy
- GHC.Types.HpcInfo: [hpcUsed] :: HpcInfo -> AnyHpcUsage
- GHC.Types.HpcInfo: isHpcUsed :: HpcInfo -> AnyHpcUsage
- GHC.Types.HpcInfo: type AnyHpcUsage = Bool
- GHC.Types.Id.Info: instance GHC.Classes.Eq GHC.Types.Id.Info.CafInfo
- GHC.Types.Id.Info: instance GHC.Classes.Eq GHC.Types.Id.Info.RecSelParent
- GHC.Types.Id.Info: instance GHC.Classes.Ord GHC.Types.Id.Info.CafInfo
- GHC.Types.Literal: instance GHC.Classes.Eq GHC.Types.Literal.LitNumType
- GHC.Types.Literal: instance GHC.Classes.Eq GHC.Types.Literal.Literal
- GHC.Types.Literal: instance GHC.Classes.Ord GHC.Types.Literal.LitNumType
- GHC.Types.Literal: instance GHC.Classes.Ord GHC.Types.Literal.Literal
- GHC.Types.Name: instance GHC.Classes.Eq GHC.Types.Name.Name
- GHC.Types.Name: instance GHC.Classes.Ord GHC.Types.Name.Name
- GHC.Types.Name.Occurrence: instance GHC.Classes.Eq GHC.Types.Name.Occurrence.NameSpace
- GHC.Types.Name.Occurrence: instance GHC.Classes.Eq GHC.Types.Name.Occurrence.OccName
- GHC.Types.Name.Occurrence: instance GHC.Classes.Ord GHC.Types.Name.Occurrence.NameSpace
- GHC.Types.Name.Occurrence: instance GHC.Classes.Ord GHC.Types.Name.Occurrence.OccName
- GHC.Types.Name.Reader: LookupChild :: Name -> Bool -> Bool -> LookupChild
- GHC.Types.Name.Reader: [lookupDataConFirst] :: LookupChild -> Bool
- GHC.Types.Name.Reader: [prioritiseParent] :: LookupChild -> Bool
- GHC.Types.Name.Reader: [wantedParent] :: LookupChild -> Name
- GHC.Types.Name.Reader: data LookupChild
- GHC.Types.Name.Reader: instance GHC.Classes.Eq GHC.Types.Name.Reader.FieldsOrSelectors
- GHC.Types.Name.Reader: instance GHC.Classes.Eq GHC.Types.Name.Reader.ImpDeclSpec
- GHC.Types.Name.Reader: instance GHC.Classes.Eq GHC.Types.Name.Reader.ImpItemSpec
- GHC.Types.Name.Reader: instance GHC.Classes.Eq GHC.Types.Name.Reader.ImportSpec
- GHC.Types.Name.Reader: instance GHC.Classes.Eq GHC.Types.Name.Reader.Parent
- GHC.Types.Name.Reader: instance GHC.Classes.Eq GHC.Types.Name.Reader.RdrName
- GHC.Types.Name.Reader: instance GHC.Classes.Ord GHC.Types.Name.Reader.RdrName
- GHC.Types.Name.Reader: instance GHC.Utils.Outputable.Outputable GHC.Types.Name.Reader.LookupChild
- GHC.Types.PkgQual: instance GHC.Classes.Eq GHC.Types.PkgQual.PkgQual
- GHC.Types.PkgQual: instance GHC.Classes.Ord GHC.Types.PkgQual.PkgQual
- GHC.Types.ProfAuto: instance GHC.Classes.Eq GHC.Types.ProfAuto.ProfAuto
- GHC.Types.RepType: instance GHC.Classes.Eq GHC.Types.RepType.SlotTy
- GHC.Types.RepType: instance GHC.Classes.Ord GHC.Types.RepType.SlotTy
- GHC.Types.SafeHaskell: instance GHC.Classes.Eq GHC.Types.SafeHaskell.SafeHaskellMode
- GHC.Types.SaneDouble: instance GHC.Classes.Eq GHC.Types.SaneDouble.SaneDouble
- GHC.Types.SaneDouble: instance GHC.Classes.Ord GHC.Types.SaneDouble.SaneDouble
- GHC.Types.SourceFile: instance GHC.Classes.Eq GHC.Types.SourceFile.HsBootOrSig
- GHC.Types.SourceFile: instance GHC.Classes.Eq GHC.Types.SourceFile.HscSource
- GHC.Types.SourceFile: instance GHC.Classes.Ord GHC.Types.SourceFile.HsBootOrSig
- GHC.Types.SourceFile: instance GHC.Classes.Ord GHC.Types.SourceFile.HscSource
- GHC.Types.SourceText: instance GHC.Classes.Eq GHC.Types.SourceText.FractionalExponentBase
- GHC.Types.SourceText: instance GHC.Classes.Eq GHC.Types.SourceText.FractionalLit
- GHC.Types.SourceText: instance GHC.Classes.Eq GHC.Types.SourceText.IntegralLit
- GHC.Types.SourceText: instance GHC.Classes.Eq GHC.Types.SourceText.SourceText
- GHC.Types.SourceText: instance GHC.Classes.Eq GHC.Types.SourceText.StringLiteral
- GHC.Types.SourceText: instance GHC.Classes.Ord GHC.Types.SourceText.FractionalExponentBase
- GHC.Types.SourceText: instance GHC.Classes.Ord GHC.Types.SourceText.FractionalLit
- GHC.Types.SourceText: instance GHC.Classes.Ord GHC.Types.SourceText.IntegralLit
- GHC.Types.SrcLoc: instance (GHC.Classes.Eq l, GHC.Classes.Eq e) => GHC.Classes.Eq (GHC.Types.SrcLoc.GenLocated l e)
- GHC.Types.SrcLoc: instance (GHC.Classes.Ord l, GHC.Classes.Ord e) => GHC.Classes.Ord (GHC.Types.SrcLoc.GenLocated l e)
- GHC.Types.SrcLoc: instance GHC.Classes.Eq GHC.Types.SrcLoc.BufPos
- GHC.Types.SrcLoc: instance GHC.Classes.Eq GHC.Types.SrcLoc.BufSpan
- GHC.Types.SrcLoc: instance GHC.Classes.Eq GHC.Types.SrcLoc.DeltaPos
- GHC.Types.SrcLoc: instance GHC.Classes.Eq GHC.Types.SrcLoc.NoComments
- GHC.Types.SrcLoc: instance GHC.Classes.Eq GHC.Types.SrcLoc.PsLoc
- GHC.Types.SrcLoc: instance GHC.Classes.Eq GHC.Types.SrcLoc.PsSpan
- GHC.Types.SrcLoc: instance GHC.Classes.Eq GHC.Types.SrcLoc.RealSrcLoc
- GHC.Types.SrcLoc: instance GHC.Classes.Eq GHC.Types.SrcLoc.RealSrcSpan
- GHC.Types.SrcLoc: instance GHC.Classes.Eq GHC.Types.SrcLoc.SrcLoc
- GHC.Types.SrcLoc: instance GHC.Classes.Eq GHC.Types.SrcLoc.SrcSpan
- GHC.Types.SrcLoc: instance GHC.Classes.Eq GHC.Types.SrcLoc.UnhelpfulSpanReason
- GHC.Types.SrcLoc: instance GHC.Classes.Eq a => GHC.Classes.Eq (GHC.Types.SrcLoc.EpaLocation' a)
- GHC.Types.SrcLoc: instance GHC.Classes.Ord GHC.Types.SrcLoc.BufPos
- GHC.Types.SrcLoc: instance GHC.Classes.Ord GHC.Types.SrcLoc.BufSpan
- GHC.Types.SrcLoc: instance GHC.Classes.Ord GHC.Types.SrcLoc.DeltaPos
- GHC.Types.SrcLoc: instance GHC.Classes.Ord GHC.Types.SrcLoc.NoComments
- GHC.Types.SrcLoc: instance GHC.Classes.Ord GHC.Types.SrcLoc.PsLoc
- GHC.Types.SrcLoc: instance GHC.Classes.Ord GHC.Types.SrcLoc.PsSpan
- GHC.Types.SrcLoc: instance GHC.Classes.Ord GHC.Types.SrcLoc.RealSrcLoc
- GHC.Types.SrcLoc: instance GHC.Classes.Ord GHC.Types.SrcLoc.RealSrcSpan
- GHC.Types.Target: instance GHC.Classes.Eq GHC.Types.Target.TargetId
- GHC.Types.Tickish: [breakpointModule] :: GenTickish (pass :: TickishPass) -> Module
- GHC.Types.Tickish: instance GHC.Classes.Eq (GHC.Types.Tickish.GenTickish 'GHC.Types.Tickish.TickishPassCmm)
- GHC.Types.Tickish: instance GHC.Classes.Eq (GHC.Types.Tickish.GenTickish 'GHC.Types.Tickish.TickishPassCore)
- GHC.Types.Tickish: instance GHC.Classes.Eq GHC.Types.Tickish.TickishPlacement
- GHC.Types.Tickish: instance GHC.Classes.Eq GHC.Types.Tickish.TickishScoping
- GHC.Types.Tickish: instance GHC.Classes.Ord (GHC.Types.Tickish.GenTickish 'GHC.Types.Tickish.TickishPassCmm)
- GHC.Types.Tickish: instance GHC.Classes.Ord (GHC.Types.Tickish.GenTickish 'GHC.Types.Tickish.TickishPassCore)
- GHC.Types.Unique: instance GHC.Classes.Eq GHC.Types.Unique.Unique
- GHC.Types.Unique: instance GHC.Types.Unique.Uniquable GHC.Types.Int
- GHC.Types.Unique.DFM: instance GHC.Classes.Eq val => GHC.Classes.Eq (GHC.Types.Unique.DFM.TaggedVal val)
- GHC.Types.Unique.DSet: instance GHC.Classes.Eq (GHC.Types.Unique.DSet.UniqDSet a)
- GHC.Types.Unique.FM: instance GHC.Classes.Eq a => GHC.Classes.Eq (GHC.Types.Unique.FM.Edit a)
- GHC.Types.Unique.FM: instance forall k (key :: k) ele. GHC.Classes.Eq ele => GHC.Classes.Eq (GHC.Types.Unique.FM.UniqFM key ele)
- GHC.Types.Unique.FM: strictAddToUFM_C :: Uniquable key => (elt -> elt -> elt) -> UniqFM key elt -> key -> elt -> UniqFM key elt
- GHC.Types.Unique.FM: strictIntersectUFM_C :: forall {k} elt1 elt2 elt3 (key :: k). (elt1 -> elt2 -> elt3) -> UniqFM key elt1 -> UniqFM key elt2 -> UniqFM key elt3
- GHC.Types.Unique.FM: strictPlusUFM :: forall {k} (key :: k) elt. UniqFM key elt -> UniqFM key elt -> UniqFM key elt
- GHC.Types.Unique.FM: strictPlusUFM_C :: forall {k} elt (key :: k). (elt -> elt -> elt) -> UniqFM key elt -> UniqFM key elt -> UniqFM key elt
- GHC.Types.Unique.Map: instance (GHC.Classes.Eq k, GHC.Classes.Eq a) => GHC.Classes.Eq (GHC.Types.Unique.Map.UniqMap k a)
- GHC.Types.Unique.Set: instance GHC.Classes.Eq (GHC.Types.Unique.Set.UniqSet a)
- GHC.Types.Unique.Set: instance GHC.Classes.Eq GHC.Types.Unique.Set.UniqueSet
- GHC.Types.Unique.Set: instance GHC.Classes.Ord GHC.Types.Unique.Set.UniqueSet
- GHC.Types.Unique.Set: minusUniqSet_C :: (a -> a -> Maybe a) -> UniqSet a -> UniqSet a -> UniqSet a
- GHC.Types.Unique.Set: strictAddOneToUniqSet_C :: Uniquable a => (a -> a -> a) -> UniqSet a -> a -> UniqSet a
- GHC.Types.Unique.Set: strictIntersectUniqSets_C :: (a -> a -> a) -> UniqSet a -> UniqSet a -> UniqSet a
- GHC.Types.Unique.Set: strictUnionManyUniqSets_C :: (a -> a -> a) -> [UniqSet a] -> UniqSet a
- GHC.Types.Unique.Set: strictUnionUniqSets_C :: (a -> a -> a) -> UniqSet a -> UniqSet a -> UniqSet a
- GHC.Types.Var: instance (GHC.Classes.Eq var, GHC.Classes.Eq argf) => GHC.Classes.Eq (GHC.Types.Var.VarBndr var argf)
- GHC.Types.Var: instance (GHC.Classes.Ord var, GHC.Classes.Ord argf) => GHC.Classes.Ord (GHC.Types.Var.VarBndr var argf)
- GHC.Types.Var: instance GHC.Classes.Eq GHC.Types.Var.FunTyFlag
- GHC.Types.Var: instance GHC.Classes.Eq GHC.Types.Var.Var
- GHC.Types.Var: instance GHC.Classes.Ord GHC.Types.Var.FunTyFlag
- GHC.Types.Var: instance GHC.Classes.Ord GHC.Types.Var.Var
- GHC.Types.Var: varMult :: Var -> Mult
- GHC.Types.Var.Env: strictPlusVarEnv :: VarEnv a -> VarEnv a -> VarEnv a
- GHC.Types.Var.Env: strictPlusVarEnv_C :: (a -> a -> a) -> VarEnv a -> VarEnv a -> VarEnv a
- GHC.Unit.Env: UnitEnvGraph :: Map UnitEnvGraphKey v -> UnitEnvGraph v
- GHC.Unit.Env: [unitEnv_graph] :: UnitEnvGraph v -> Map UnitEnvGraphKey v
- GHC.Unit.Env: addHomeModInfoToHug :: HomeModInfo -> HomeUnitGraph -> HomeUnitGraph
- GHC.Unit.Env: hugElts :: HomeUnitGraph -> [(UnitId, HomeUnitEnv)]
- GHC.Unit.Env: instance GHC.Internal.Base.Functor GHC.Unit.Env.UnitEnvGraph
- GHC.Unit.Env: instance GHC.Internal.Data.Foldable.Foldable GHC.Unit.Env.UnitEnvGraph
- GHC.Unit.Env: instance GHC.Internal.Data.Traversable.Traversable GHC.Unit.Env.UnitEnvGraph
- GHC.Unit.Env: instance GHC.Utils.Outputable.Outputable (GHC.Unit.Env.UnitEnvGraph GHC.Unit.Env.HomeUnitEnv)
- GHC.Unit.Env: instance GHC.Utils.Outputable.Outputable GHC.Unit.Env.HomeUnitEnv
- GHC.Unit.Env: lookupHug :: HomeUnitGraph -> UnitId -> ModuleName -> Maybe HomeModInfo
- GHC.Unit.Env: lookupHugByModule :: Module -> HomeUnitGraph -> Maybe HomeModInfo
- GHC.Unit.Env: mkHomeUnitEnv :: DynFlags -> HomePackageTable -> Maybe HomeUnit -> HomeUnitEnv
- GHC.Unit.Env: newtype UnitEnvGraph v
- GHC.Unit.Env: type UnitEnvGraphKey = UnitId
- GHC.Unit.Env: ue_renameUnitId :: HasDebugCallStack => UnitId -> UnitId -> UnitEnv -> UnitEnv
- GHC.Unit.Env: ue_setUnitDbs :: Maybe [UnitDatabase UnitId] -> UnitEnv -> UnitEnv
- GHC.Unit.Env: ue_setUnitFlags :: HasDebugCallStack => UnitId -> DynFlags -> UnitEnv -> UnitEnv
- GHC.Unit.Env: ue_setUnits :: UnitState -> UnitEnv -> UnitEnv
- GHC.Unit.Env: unitEnv_adjust :: (v -> v) -> UnitEnvGraphKey -> UnitEnvGraph v -> UnitEnvGraph v
- GHC.Unit.Env: unitEnv_delete :: UnitEnvGraphKey -> UnitEnvGraph v -> UnitEnvGraph v
- GHC.Unit.Env: unitEnv_elts :: UnitEnvGraph v -> [(UnitEnvGraphKey, v)]
- GHC.Unit.Env: unitEnv_foldWithKey :: (b -> UnitEnvGraphKey -> a -> b) -> b -> UnitEnvGraph a -> b
- GHC.Unit.Env: unitEnv_hpts :: UnitEnvGraph HomeUnitEnv -> [HomePackageTable]
- GHC.Unit.Env: unitEnv_insert :: UnitEnvGraphKey -> v -> UnitEnvGraph v -> UnitEnvGraph v
- GHC.Unit.Env: unitEnv_keys :: UnitEnvGraph v -> Set UnitEnvGraphKey
- GHC.Unit.Env: unitEnv_lookup :: UnitEnvGraphKey -> UnitEnvGraph v -> v
- GHC.Unit.Env: unitEnv_lookup_maybe :: UnitEnvGraphKey -> UnitEnvGraph v -> Maybe v
- GHC.Unit.Env: unitEnv_map :: (v -> v) -> UnitEnvGraph v -> UnitEnvGraph v
- GHC.Unit.Env: unitEnv_mapWithKey :: (UnitEnvGraphKey -> v -> b) -> UnitEnvGraph v -> UnitEnvGraph b
- GHC.Unit.Env: unitEnv_member :: UnitEnvGraphKey -> UnitEnvGraph v -> Bool
- GHC.Unit.Env: unitEnv_new :: Map UnitEnvGraphKey v -> UnitEnvGraph v
- GHC.Unit.Env: unitEnv_singleton :: UnitEnvGraphKey -> v -> UnitEnvGraph v
- GHC.Unit.Env: unitEnv_union :: (a -> a -> a) -> UnitEnvGraph a -> UnitEnvGraph a -> UnitEnvGraph a
- GHC.Unit.Env: unsafeGetHomeUnit :: UnitEnv -> HomeUnit
- GHC.Unit.Env: updateHpt :: (HomePackageTable -> HomePackageTable) -> UnitEnv -> UnitEnv
- GHC.Unit.Env: updateHpt_lazy :: (HomePackageTable -> HomePackageTable) -> UnitEnv -> UnitEnv
- GHC.Unit.Home.ModInfo: addHomeModInfoToHpt :: HomeModInfo -> HomePackageTable -> HomePackageTable
- GHC.Unit.Home.ModInfo: addListToHpt :: HomePackageTable -> [(ModuleName, HomeModInfo)] -> HomePackageTable
- GHC.Unit.Home.ModInfo: addToHpt :: HomePackageTable -> ModuleName -> HomeModInfo -> HomePackageTable
- GHC.Unit.Home.ModInfo: allHpt :: (HomeModInfo -> Bool) -> HomePackageTable -> Bool
- GHC.Unit.Home.ModInfo: anyHpt :: (HomeModInfo -> Bool) -> HomePackageTable -> Bool
- GHC.Unit.Home.ModInfo: concatHpt :: (HomeModInfo -> [a]) -> HomePackageTable -> [a]
- GHC.Unit.Home.ModInfo: delFromHpt :: HomePackageTable -> ModuleName -> HomePackageTable
- GHC.Unit.Home.ModInfo: eltsHpt :: HomePackageTable -> [HomeModInfo]
- GHC.Unit.Home.ModInfo: emptyHomePackageTable :: HomePackageTable
- GHC.Unit.Home.ModInfo: filterHpt :: (HomeModInfo -> Bool) -> HomePackageTable -> HomePackageTable
- GHC.Unit.Home.ModInfo: listHMIToHpt :: [HomeModInfo] -> HomePackageTable
- GHC.Unit.Home.ModInfo: listToHpt :: [(ModuleName, HomeModInfo)] -> HomePackageTable
- GHC.Unit.Home.ModInfo: lookupHpt :: HomePackageTable -> ModuleName -> Maybe HomeModInfo
- GHC.Unit.Home.ModInfo: lookupHptByModule :: HomePackageTable -> Module -> Maybe HomeModInfo
- GHC.Unit.Home.ModInfo: lookupHptDirectly :: HomePackageTable -> Unique -> Maybe HomeModInfo
- GHC.Unit.Home.ModInfo: mapHpt :: (HomeModInfo -> HomeModInfo) -> HomePackageTable -> HomePackageTable
- GHC.Unit.Home.ModInfo: pprHPT :: HomePackageTable -> SDoc
- GHC.Unit.Home.ModInfo: type HomePackageTable = DModuleNameEnv HomeModInfo
- GHC.Unit.Info: instance GHC.Classes.Eq GHC.Unit.Info.PackageId
- GHC.Unit.Info: instance GHC.Classes.Eq GHC.Unit.Info.PackageName
- GHC.Unit.Module.Deps: dep_boot_mods :: Dependencies -> Set (UnitId, ModuleNameWithIsBoot)
- GHC.Unit.Module.Deps: dep_direct_mods :: Dependencies -> Set (UnitId, ModuleNameWithIsBoot)
- GHC.Unit.Module.Deps: dep_direct_pkgs :: Dependencies -> Set UnitId
- GHC.Unit.Module.Deps: dep_finsts :: Dependencies -> [Module]
- GHC.Unit.Module.Deps: dep_orphs :: Dependencies -> [Module]
- GHC.Unit.Module.Deps: dep_plugin_pkgs :: Dependencies -> Set UnitId
- GHC.Unit.Module.Deps: dep_sig_mods :: Dependencies -> [ModuleName]
- GHC.Unit.Module.Deps: dep_trusted_pkgs :: Dependencies -> Set UnitId
- GHC.Unit.Module.Deps: instance GHC.Classes.Eq GHC.Unit.Module.Deps.Dependencies
- GHC.Unit.Module.Deps: instance GHC.Classes.Eq GHC.Unit.Module.Deps.Usage
- GHC.Unit.Module.Env: data InstalledModuleWithIsBootEnv elt
- GHC.Unit.Module.Env: delInstalledModuleWithIsBootEnv :: InstalledModuleWithIsBootEnv a -> InstalledModuleWithIsBoot -> InstalledModuleWithIsBootEnv a
- GHC.Unit.Module.Env: emptyInstalledModuleWithIsBootEnv :: InstalledModuleWithIsBootEnv a
- GHC.Unit.Module.Env: extendInstalledModuleWithIsBootEnv :: InstalledModuleWithIsBootEnv a -> InstalledModuleWithIsBoot -> a -> InstalledModuleWithIsBootEnv a
- GHC.Unit.Module.Env: filterInstalledModuleWithIsBootEnv :: (InstalledModuleWithIsBoot -> a -> Bool) -> InstalledModuleWithIsBootEnv a -> InstalledModuleWithIsBootEnv a
- GHC.Unit.Module.Env: installedModuleWithIsBootEnvElts :: InstalledModuleWithIsBootEnv a -> [(InstalledModuleWithIsBoot, a)]
- GHC.Unit.Module.Env: instance GHC.Classes.Eq GHC.Unit.Module.Env.NDModule
- GHC.Unit.Module.Env: instance GHC.Classes.Ord GHC.Unit.Module.Env.NDModule
- GHC.Unit.Module.Env: instance GHC.Utils.Outputable.Outputable elt => GHC.Utils.Outputable.Outputable (GHC.Unit.Module.Env.InstalledModuleWithIsBootEnv elt)
- GHC.Unit.Module.Env: lookupInstalledModuleWithIsBootEnv :: InstalledModuleWithIsBootEnv a -> InstalledModuleWithIsBoot -> Maybe a
- GHC.Unit.Module.Env: mergeInstalledModuleWithIsBootEnv :: (elta -> eltb -> Maybe eltc) -> (InstalledModuleWithIsBootEnv elta -> InstalledModuleWithIsBootEnv eltc) -> (InstalledModuleWithIsBootEnv eltb -> InstalledModuleWithIsBootEnv eltc) -> InstalledModuleWithIsBootEnv elta -> InstalledModuleWithIsBootEnv eltb -> InstalledModuleWithIsBootEnv eltc
- GHC.Unit.Module.Env: plusInstalledModuleWithIsBootEnv :: (elt -> elt -> elt) -> InstalledModuleWithIsBootEnv elt -> InstalledModuleWithIsBootEnv elt -> InstalledModuleWithIsBootEnv elt
- GHC.Unit.Module.Graph: extendMG :: ModuleGraph -> [NodeKey] -> ModSummary -> ModuleGraph
- GHC.Unit.Module.Graph: extendMG' :: ModuleGraph -> ModuleGraphNode -> ModuleGraph
- GHC.Unit.Module.Graph: extendMGInst :: ModuleGraph -> UnitId -> InstantiatedUnit -> ModuleGraph
- GHC.Unit.Module.Graph: instance GHC.Classes.Eq GHC.Unit.Module.Graph.ModNodeKeyWithUid
- GHC.Unit.Module.Graph: instance GHC.Classes.Eq GHC.Unit.Module.Graph.ModuleGraphNode
- GHC.Unit.Module.Graph: instance GHC.Classes.Eq GHC.Unit.Module.Graph.NodeKey
- GHC.Unit.Module.Graph: instance GHC.Classes.Ord GHC.Unit.Module.Graph.ModNodeKeyWithUid
- GHC.Unit.Module.Graph: instance GHC.Classes.Ord GHC.Unit.Module.Graph.ModuleGraphNode
- GHC.Unit.Module.Graph: instance GHC.Classes.Ord GHC.Unit.Module.Graph.NodeKey
- GHC.Unit.Module.Graph: instance GHC.Utils.Outputable.Outputable GHC.Unit.Module.Graph.ModNodeKeyWithUid
- GHC.Unit.Module.Graph: isTemplateHaskellOrQQNonBoot :: ModSummary -> Bool
- GHC.Unit.Module.Graph: mgTransDeps :: ModuleGraph -> Map NodeKey (Set NodeKey)
- GHC.Unit.Module.Graph: moduleGraphNodeModSum :: ModuleGraphNode -> Maybe ModSummary
- GHC.Unit.Module.Graph: moduleGraphNodeModule :: ModuleGraphNode -> Maybe ModuleName
- GHC.Unit.Module.Graph: moduleGraphNodeUnitId :: ModuleGraphNode -> UnitId
- GHC.Unit.Module.Graph: nodeDependencies :: Bool -> ModuleGraphNode -> [NodeKey]
- GHC.Unit.Module.Graph: unionMG :: ModuleGraph -> ModuleGraph -> ModuleGraph
- GHC.Unit.Module.Location: addBootSuffixLocn_maybe :: IsBootInterface -> ModLocation -> ModLocation
- GHC.Unit.Module.Location: addBootSuffix_maybe :: IsBootInterface -> OsPath -> OsPath
- GHC.Unit.Module.ModGuts: [mg_used_th] :: ModGuts -> !Bool
- GHC.Unit.Module.ModIface: ModIfaceBackend :: !Fingerprint -> !Fingerprint -> !Fingerprint -> !Fingerprint -> !Fingerprint -> !Fingerprint -> !WhetherHasOrphans -> !WhetherHasFamInst -> !Fingerprint -> !Fingerprint -> !OccName -> Maybe (WarningTxt GhcRn) -> !Name -> Maybe (WarningTxt GhcRn) -> !OccName -> Maybe Fixity -> !OccName -> Maybe (OccName, Fingerprint) -> ModIfaceBackend
- GHC.Unit.Module.ModIface: [mi_decl_warn_fn] :: ModIfaceBackend -> !OccName -> Maybe (WarningTxt GhcRn)
- GHC.Unit.Module.ModIface: [mi_exp_hash] :: ModIfaceBackend -> !Fingerprint
- GHC.Unit.Module.ModIface: [mi_export_warn_fn] :: ModIfaceBackend -> !Name -> Maybe (WarningTxt GhcRn)
- GHC.Unit.Module.ModIface: [mi_finsts] :: ModIfaceBackend -> !WhetherHasFamInst
- GHC.Unit.Module.ModIface: [mi_fix_fn] :: ModIfaceBackend -> !OccName -> Maybe Fixity
- GHC.Unit.Module.ModIface: [mi_flag_hash] :: ModIfaceBackend -> !Fingerprint
- GHC.Unit.Module.ModIface: [mi_hash_fn] :: ModIfaceBackend -> !OccName -> Maybe (OccName, Fingerprint)
- GHC.Unit.Module.ModIface: [mi_hpc_hash] :: ModIfaceBackend -> !Fingerprint
- GHC.Unit.Module.ModIface: [mi_iface_hash] :: ModIfaceBackend -> !Fingerprint
- GHC.Unit.Module.ModIface: [mi_mod_hash] :: ModIfaceBackend -> !Fingerprint
- GHC.Unit.Module.ModIface: [mi_opt_hash] :: ModIfaceBackend -> !Fingerprint
- GHC.Unit.Module.ModIface: [mi_orphan] :: ModIfaceBackend -> !WhetherHasOrphans
- GHC.Unit.Module.ModIface: [mi_orphan_hash] :: ModIfaceBackend -> !Fingerprint
- GHC.Unit.Module.ModIface: [mi_plugin_hash] :: ModIfaceBackend -> !Fingerprint
- GHC.Unit.Module.ModIface: addSourceFingerprint :: forall (phase :: ModIfacePhase). Fingerprint -> ModIface_ phase -> ModIface_ phase
- GHC.Unit.Module.ModIface: data ModIfaceBackend
- GHC.Unit.Module.ModIface: instance (Control.DeepSeq.NFData (GHC.Unit.Module.ModIface.IfaceBackendExts phase), Control.DeepSeq.NFData (GHC.Unit.Module.ModIface.IfaceDeclExts phase)) => Control.DeepSeq.NFData (GHC.Unit.Module.ModIface.ModIface_ phase)
- GHC.Unit.Module.ModIface: instance Control.DeepSeq.NFData GHC.Unit.Module.ModIface.ModIfaceBackend
- GHC.Unit.Module.ModIface: restoreFromOldModIface :: forall (phase :: ModIfacePhase). ModIface_ phase -> ModIface_ phase -> ModIface_ phase
- GHC.Unit.Module.ModIface: set_mi_extra_decls :: forall (phase :: ModIfacePhase). Maybe [IfaceBindingX IfaceMaybeRhs IfaceTopBndrInfo] -> ModIface_ phase -> ModIface_ phase
- GHC.Unit.Module.ModIface: set_mi_final_exts :: forall (phase :: ModIfacePhase). IfaceBackendExts phase -> ModIface_ phase -> ModIface_ phase
- GHC.Unit.Module.ModIface: set_mi_foreign :: forall (phase :: ModIfacePhase). IfaceForeign -> ModIface_ phase -> ModIface_ phase
- GHC.Unit.Module.ModIface: set_mi_hpc :: forall (phase :: ModIfacePhase). AnyHpcUsage -> ModIface_ phase -> ModIface_ phase
- GHC.Unit.Module.ModIface: set_mi_src_hash :: forall (phase :: ModIfacePhase). Fingerprint -> ModIface_ phase -> ModIface_ phase
- GHC.Unit.Module.ModIface: set_mi_usages :: forall (phase :: ModIfacePhase). [Usage] -> ModIface_ phase -> ModIface_ phase
- GHC.Unit.Module.ModIface: set_mi_used_th :: forall (phase :: ModIfacePhase). Bool -> ModIface_ phase -> ModIface_ phase
- GHC.Unit.Module.ModSummary: [ms_ghc_prim_import] :: ModSummary -> !Bool
- GHC.Unit.Module.Warnings: instance GHC.Classes.Eq (Language.Haskell.Syntax.Extension.IdP pass) => GHC.Classes.Eq (GHC.Unit.Module.Warnings.WarningTxt pass)
- GHC.Unit.Module.Warnings: instance GHC.Classes.Eq (Language.Haskell.Syntax.Extension.IdP pass) => GHC.Classes.Eq (GHC.Unit.Module.Warnings.Warnings pass)
- GHC.Unit.Module.Warnings: instance GHC.Classes.Eq GHC.Unit.Module.Warnings.InWarningCategory
- GHC.Unit.Module.Warnings: instance GHC.Classes.Eq GHC.Unit.Module.Warnings.WarningCategory
- GHC.Unit.Types: bignumUnit :: Unit
- GHC.Unit.Types: bignumUnitId :: UnitId
- GHC.Unit.Types: instance GHC.Classes.Eq (GHC.Unit.Types.GenInstantiatedUnit unit)
- GHC.Unit.Types: instance GHC.Classes.Eq GHC.Unit.Types.UnitId
- GHC.Unit.Types: instance GHC.Classes.Eq mod => GHC.Classes.Eq (GHC.Unit.Types.GenWithIsBoot mod)
- GHC.Unit.Types: instance GHC.Classes.Eq unit => GHC.Classes.Eq (GHC.Unit.Types.Definite unit)
- GHC.Unit.Types: instance GHC.Classes.Eq unit => GHC.Classes.Eq (GHC.Unit.Types.GenModule unit)
- GHC.Unit.Types: instance GHC.Classes.Ord (GHC.Unit.Types.GenInstantiatedUnit unit)
- GHC.Unit.Types: instance GHC.Classes.Ord GHC.Unit.Types.Unit
- GHC.Unit.Types: instance GHC.Classes.Ord GHC.Unit.Types.UnitId
- GHC.Unit.Types: instance GHC.Classes.Ord mod => GHC.Classes.Ord (GHC.Unit.Types.GenWithIsBoot mod)
- GHC.Unit.Types: instance GHC.Classes.Ord unit => GHC.Classes.Ord (GHC.Unit.Types.Definite unit)
- GHC.Unit.Types: instance GHC.Classes.Ord unit => GHC.Classes.Ord (GHC.Unit.Types.GenModule unit)
- GHC.Unit.Types: instance GHC.Internal.Data.Data.Data Language.Haskell.Syntax.Module.Name.ModuleName
- GHC.Unit.Types: instance GHC.Unit.Types.IsUnitId u => GHC.Classes.Eq (GHC.Unit.Types.GenUnit u)
- GHC.Unit.Types: instance GHC.Utils.Binary.Binary Language.Haskell.Syntax.ImpExp.IsBootInterface
- GHC.Unit.Types: notBoot :: mod -> GenWithIsBoot mod
- GHC.Unit.Types: primUnit :: Unit
- GHC.Unit.Types: primUnitId :: UnitId
- GHC.Unit.Types: type InstalledModuleWithIsBoot = GenWithIsBoot InstalledModule
- GHC.Utils.Binary: instance (GHC.Utils.Binary.Binary a, GHC.Classes.Ord a) => GHC.Utils.Binary.Binary (Data.Set.Internal.Set a)
- GHC.Utils.Binary: instance GHC.Classes.Eq GHC.Utils.Binary.BindingName
- GHC.Utils.Binary: instance GHC.Classes.Eq GHC.Utils.Binary.FullBinData
- GHC.Utils.Binary: instance GHC.Classes.Eq a => GHC.Classes.Eq (GHC.Utils.Binary.FixedLengthEncoding a)
- GHC.Utils.Binary: instance GHC.Classes.Ord GHC.Utils.Binary.FullBinData
- GHC.Utils.Binary: instance GHC.Classes.Ord a => GHC.Classes.Ord (GHC.Utils.Binary.FixedLengthEncoding a)
- GHC.Utils.Binary: instance GHC.Utils.Binary.Binary GHC.Num.Integer.Integer
- GHC.Utils.Binary: instance GHC.Utils.Binary.Binary GHC.Types.Bool
- GHC.Utils.Binary: instance GHC.Utils.Binary.Binary GHC.Types.Char
- GHC.Utils.Binary: instance GHC.Utils.Binary.Binary GHC.Types.Int
- GHC.Utils.Binary: instance forall k (a :: k). GHC.Classes.Eq (GHC.Utils.Binary.Bin a)
- GHC.Utils.Binary: instance forall k (a :: k). GHC.Classes.Eq (GHC.Utils.Binary.RelBin a)
- GHC.Utils.Binary: instance forall k (a :: k). GHC.Classes.Eq (GHC.Utils.Binary.RelBinPtr a)
- GHC.Utils.Binary: instance forall k (a :: k). GHC.Classes.Ord (GHC.Utils.Binary.Bin a)
- GHC.Utils.Binary: instance forall k (a :: k). GHC.Classes.Ord (GHC.Utils.Binary.RelBin a)
- GHC.Utils.Binary: instance forall k (a :: k). GHC.Classes.Ord (GHC.Utils.Binary.RelBinPtr a)
- GHC.Utils.Binary.Typeable: instance GHC.Utils.Binary.Binary GHC.Types.KindRep
- GHC.Utils.Binary.Typeable: instance GHC.Utils.Binary.Binary GHC.Types.RuntimeRep
- GHC.Utils.Binary.Typeable: instance GHC.Utils.Binary.Binary GHC.Types.TyCon
- GHC.Utils.Binary.Typeable: instance GHC.Utils.Binary.Binary GHC.Types.TypeLitSort
- GHC.Utils.Binary.Typeable: instance GHC.Utils.Binary.Binary GHC.Types.VecCount
- GHC.Utils.Binary.Typeable: instance GHC.Utils.Binary.Binary GHC.Types.VecElem
- GHC.Utils.CliOption: instance GHC.Classes.Eq GHC.Utils.CliOption.Option
- GHC.Utils.Error: instance GHC.Classes.Eq GHC.Utils.Error.PrintTimings
- GHC.Utils.Json: instance GHC.Utils.Json.ToJson GHC.Types.Int
- GHC.Utils.Logger: instance GHC.Classes.Eq GHC.Utils.Logger.DumpFormat
- GHC.Utils.Misc: foldl1' :: HasCallStack => (a -> a -> a) -> [a] -> a
- GHC.Utils.Outputable: instance GHC.Classes.Eq GHC.Utils.Outputable.BindingSite
- GHC.Utils.Outputable: instance GHC.Classes.Eq GHC.Utils.Outputable.JoinPointHood
- GHC.Utils.Outputable: instance GHC.Utils.Outputable.Outputable GHC.Num.Integer.Integer
- GHC.Utils.Outputable: instance GHC.Utils.Outputable.Outputable GHC.Types.Bool
- GHC.Utils.Outputable: instance GHC.Utils.Outputable.Outputable GHC.Types.Double
- GHC.Utils.Outputable: instance GHC.Utils.Outputable.Outputable GHC.Types.Float
- GHC.Utils.Outputable: instance GHC.Utils.Outputable.Outputable GHC.Types.Int
- GHC.Utils.Outputable: instance GHC.Utils.Outputable.Outputable GHC.Types.Ordering
- GHC.Utils.Outputable: instance GHC.Utils.Outputable.Outputable GHC.Types.Word
- Language.Haskell.Syntax.Basic: HsBang :: SrcUnpackedness -> SrcStrictness -> HsBang
- Language.Haskell.Syntax.Basic: data HsBang
- Language.Haskell.Syntax.Basic: instance GHC.Classes.Eq Language.Haskell.Syntax.Basic.Boxity
- Language.Haskell.Syntax.Basic: instance GHC.Classes.Eq Language.Haskell.Syntax.Basic.FieldLabelString
- Language.Haskell.Syntax.Basic: instance GHC.Classes.Eq Language.Haskell.Syntax.Basic.Fixity
- Language.Haskell.Syntax.Basic: instance GHC.Classes.Eq Language.Haskell.Syntax.Basic.FixityDirection
- Language.Haskell.Syntax.Basic: instance GHC.Classes.Eq Language.Haskell.Syntax.Basic.LexicalFixity
- Language.Haskell.Syntax.Basic: instance GHC.Classes.Eq Language.Haskell.Syntax.Basic.Role
- Language.Haskell.Syntax.Basic: instance GHC.Classes.Eq Language.Haskell.Syntax.Basic.SrcStrictness
- Language.Haskell.Syntax.Basic: instance GHC.Classes.Eq Language.Haskell.Syntax.Basic.SrcUnpackedness
- Language.Haskell.Syntax.Basic: instance GHC.Classes.Ord Language.Haskell.Syntax.Basic.Role
- Language.Haskell.Syntax.Basic: instance GHC.Internal.Data.Data.Data Language.Haskell.Syntax.Basic.HsBang
- Language.Haskell.Syntax.Binds: HsMultAnn :: !XMultAnn pass -> LHsType (NoGhcTc pass) -> HsMultAnn pass
- Language.Haskell.Syntax.Binds: HsNoMultAnn :: !XNoMultAnn pass -> HsMultAnn pass
- Language.Haskell.Syntax.Binds: HsPct1Ann :: !XPct1Ann pass -> HsMultAnn pass
- Language.Haskell.Syntax.Binds: XMultAnn :: !XXMultAnn pass -> HsMultAnn pass
- Language.Haskell.Syntax.Binds: data HsMultAnn pass
- Language.Haskell.Syntax.Binds: type family XXMultAnn p
- Language.Haskell.Syntax.Decls: [con_bndrs] :: ConDecl pass -> XRec pass (HsOuterSigTyVarBndrs pass)
- Language.Haskell.Syntax.Decls: [rd_tmvs] :: RuleDecl pass -> [LRuleBndr pass]
- Language.Haskell.Syntax.Decls: [rd_tyvs] :: RuleDecl pass -> Maybe [LHsTyVarBndr () (NoGhcTc pass)]
- Language.Haskell.Syntax.Decls: hsGroupInstDecls :: HsGroup id -> [LInstDecl id]
- Language.Haskell.Syntax.Decls: instance GHC.Classes.Eq Language.Haskell.Syntax.Decls.NewOrData
- Language.Haskell.Syntax.Decls: instance GHC.Classes.Eq Language.Haskell.Syntax.Decls.SpliceDecoration
- Language.Haskell.Syntax.Decls: instance GHC.Classes.Eq a => GHC.Classes.Eq (Language.Haskell.Syntax.Decls.DataDefnCons a)
- Language.Haskell.Syntax.Decls: instance GHC.Internal.Data.Data.Data Language.Haskell.Syntax.Decls.NewOrData
- Language.Haskell.Syntax.Decls: tyClDeclTyVars :: TyClDecl pass -> LHsQTyVars pass
- Language.Haskell.Syntax.Decls: tyClGroupInstDecls :: [TyClGroup pass] -> [LInstDecl pass]
- Language.Haskell.Syntax.Decls: tyClGroupKindSigs :: [TyClGroup pass] -> [LStandaloneKindSig pass]
- Language.Haskell.Syntax.Decls: tyClGroupRoleDecls :: [TyClGroup pass] -> [LRoleAnnotDecl pass]
- Language.Haskell.Syntax.Decls: tyClGroupTyClDecls :: [TyClGroup pass] -> [LTyClDecl pass]
- Language.Haskell.Syntax.Expr: HsUnboundVar :: XUnboundVar p -> RdrName -> HsExpr p
- Language.Haskell.Syntax.Expr: instance GHC.Classes.Eq Language.Haskell.Syntax.Expr.HsDoFlavour
- Language.Haskell.Syntax.Expr: instance GHC.Classes.Eq Language.Haskell.Syntax.Expr.HsLamVariant
- Language.Haskell.Syntax.Expr: isInfixMatch :: Match id body -> Bool
- Language.Haskell.Syntax.Extension: instance GHC.Classes.Eq Language.Haskell.Syntax.Extension.DataConCantHappen
- Language.Haskell.Syntax.Extension: instance GHC.Classes.Eq Language.Haskell.Syntax.Extension.NoExtField
- Language.Haskell.Syntax.Extension: instance GHC.Classes.Ord Language.Haskell.Syntax.Extension.DataConCantHappen
- Language.Haskell.Syntax.Extension: instance GHC.Classes.Ord Language.Haskell.Syntax.Extension.NoExtField
- Language.Haskell.Syntax.ImpExp: instance Control.DeepSeq.NFData Language.Haskell.Syntax.ImpExp.IsBootInterface
- Language.Haskell.Syntax.ImpExp: instance GHC.Classes.Eq Language.Haskell.Syntax.ImpExp.IEWildcard
- Language.Haskell.Syntax.ImpExp: instance GHC.Classes.Eq Language.Haskell.Syntax.ImpExp.ImportDeclQualifiedStyle
- Language.Haskell.Syntax.ImpExp: instance GHC.Classes.Eq Language.Haskell.Syntax.ImpExp.ImportListInterpretation
- Language.Haskell.Syntax.ImpExp: instance GHC.Classes.Eq Language.Haskell.Syntax.ImpExp.IsBootInterface
- Language.Haskell.Syntax.ImpExp: instance GHC.Classes.Ord Language.Haskell.Syntax.ImpExp.IsBootInterface
- Language.Haskell.Syntax.ImpExp: instance GHC.Internal.Data.Data.Data Language.Haskell.Syntax.ImpExp.IsBootInterface
- Language.Haskell.Syntax.ImpExp: instance GHC.Internal.Show.Show Language.Haskell.Syntax.ImpExp.IsBootInterface
- Language.Haskell.Syntax.Lit: HsInteger :: XHsInteger x -> Integer -> Type -> HsLit x
- Language.Haskell.Syntax.Lit: HsRat :: XHsRat x -> FractionalLit -> Type -> HsLit x
- Language.Haskell.Syntax.Lit: instance GHC.Classes.Eq (Language.Haskell.Syntax.Lit.HsLit x)
- Language.Haskell.Syntax.Lit: instance GHC.Classes.Eq Language.Haskell.Syntax.Lit.OverLitVal
- Language.Haskell.Syntax.Lit: instance GHC.Classes.Ord Language.Haskell.Syntax.Lit.OverLitVal
- Language.Haskell.Syntax.Module.Name: instance GHC.Classes.Eq Language.Haskell.Syntax.Module.Name.ModuleName
- Language.Haskell.Syntax.Module.Name: instance GHC.Classes.Ord Language.Haskell.Syntax.Module.Name.ModuleName
- Language.Haskell.Syntax.Pat: HsConPatTyArg :: !XConPatTyArg p -> HsTyPat p -> HsConPatTyArg p
- Language.Haskell.Syntax.Pat: data HsConPatTyArg p
- Language.Haskell.Syntax.Pat: hsConPatTyArgs :: HsConPatDetails p -> [HsConPatTyArg (NoGhcTc p)]
- Language.Haskell.Syntax.Pat: hsRecFieldSel :: UnXRec p => HsRecField p arg -> IdP p
- Language.Haskell.Syntax.Pat: hsRecFields :: UnXRec p => HsRecFields p arg -> [IdP p]
- Language.Haskell.Syntax.Pat: hsRecFieldsArgs :: UnXRec p => HsRecFields p arg -> [arg]
- Language.Haskell.Syntax.Pat: instance GHC.Classes.Eq Language.Haskell.Syntax.Pat.RecFieldsDotDot
- Language.Haskell.Syntax.Pat: instance GHC.Classes.Ord Language.Haskell.Syntax.Pat.RecFieldsDotDot
- Language.Haskell.Syntax.Specificity: instance GHC.Classes.Eq Language.Haskell.Syntax.Specificity.ForAllTyFlag
- Language.Haskell.Syntax.Specificity: instance GHC.Classes.Eq Language.Haskell.Syntax.Specificity.Specificity
- Language.Haskell.Syntax.Specificity: instance GHC.Classes.Ord Language.Haskell.Syntax.Specificity.ForAllTyFlag
- Language.Haskell.Syntax.Specificity: instance GHC.Classes.Ord Language.Haskell.Syntax.Specificity.Specificity
- Language.Haskell.Syntax.Type: ConDeclField :: XConDeclField pass -> [LFieldOcc pass] -> LBangType pass -> Maybe (LHsDoc pass) -> ConDeclField pass
- Language.Haskell.Syntax.Type: HsBang :: SrcUnpackedness -> SrcStrictness -> HsBang
- Language.Haskell.Syntax.Type: HsBangTy :: XBangTy pass -> HsBang -> LHsType pass -> HsType pass
- Language.Haskell.Syntax.Type: HsLinearArrow :: !XLinearArrow mult pass -> HsArrowOf mult pass
- Language.Haskell.Syntax.Type: HsRecTy :: XRecTy pass -> [LConDeclField pass] -> HsType pass
- Language.Haskell.Syntax.Type: HsScaled :: HsArrow pass -> a -> HsScaled pass a
- Language.Haskell.Syntax.Type: HsUnrestrictedArrow :: !XUnrestrictedArrow mult pass -> HsArrowOf mult pass
- Language.Haskell.Syntax.Type: XArrow :: !XXArrow mult pass -> HsArrowOf mult pass
- Language.Haskell.Syntax.Type: XConDeclField :: !XXConDeclField pass -> ConDeclField pass
- Language.Haskell.Syntax.Type: [cd_fld_doc] :: ConDeclField pass -> Maybe (LHsDoc pass)
- Language.Haskell.Syntax.Type: [cd_fld_ext] :: ConDeclField pass -> XConDeclField pass
- Language.Haskell.Syntax.Type: [cd_fld_names] :: ConDeclField pass -> [LFieldOcc pass]
- Language.Haskell.Syntax.Type: [cd_fld_type] :: ConDeclField pass -> LBangType pass
- Language.Haskell.Syntax.Type: data ConDeclField pass
- Language.Haskell.Syntax.Type: data HsArrowOf mult pass
- Language.Haskell.Syntax.Type: data HsBang
- Language.Haskell.Syntax.Type: data HsScaled pass a
- Language.Haskell.Syntax.Type: hsMult :: HsScaled pass a -> HsArrow pass
- Language.Haskell.Syntax.Type: hsPatSigType :: HsPatSigType pass -> LHsType pass
- Language.Haskell.Syntax.Type: hsScaledThing :: HsScaled pass a -> a
- Language.Haskell.Syntax.Type: instance (GHC.Classes.Eq (Language.Haskell.Syntax.Extension.LIdP pass), GHC.Classes.Eq (Language.Haskell.Syntax.Extension.XCFieldOcc pass), GHC.Classes.Eq (Language.Haskell.Syntax.Extension.XXFieldOcc pass)) => GHC.Classes.Eq (Language.Haskell.Syntax.Type.FieldOcc pass)
- Language.Haskell.Syntax.Type: instance (GHC.Internal.Data.Data.Data tyarg, GHC.Internal.Data.Data.Data rec, GHC.Internal.Data.Data.Data arg) => GHC.Internal.Data.Data.Data (Language.Haskell.Syntax.Type.HsConDetails tyarg arg rec)
- Language.Haskell.Syntax.Type: instance GHC.Classes.Eq Language.Haskell.Syntax.Type.HsIPName
- Language.Haskell.Syntax.Type: instance GHC.Classes.Eq Language.Haskell.Syntax.Type.PromotionFlag
- Language.Haskell.Syntax.Type: instance GHC.Classes.Ord Language.Haskell.Syntax.Type.PromotionFlag
- Language.Haskell.Syntax.Type: noTypeArgs :: [Void]
- Language.Haskell.Syntax.Type: type BangType pass = HsType pass
- Language.Haskell.Syntax.Type: type HsArrow pass = HsArrowOf LHsType pass pass
- Language.Haskell.Syntax.Type: type LBangType pass = XRec pass BangType pass
- Language.Haskell.Syntax.Type: type LConDeclField pass = XRec pass ConDeclField pass
+ GHC: LocalStep :: SrcSpan -> SingleStep
+ GHC: ModuleStep :: SrcSpan -> SingleStep
+ GHC: Opt_GhciBrowser :: GeneralFlag
+ GHC: Opt_GhciBrowserRedirectWasiConsole :: GeneralFlag
+ GHC: Opt_GhciDoLoadTargets :: GeneralFlag
+ GHC: Opt_WriteSelfRecompFlags :: GeneralFlag
+ GHC: Opt_WriteSelfRecompInfo :: GeneralFlag
+ GHC: StepOut :: Maybe SrcSpan -> SingleStep
+ GHC: [breakAt] :: SingleStep -> SrcSpan
+ GHC: [ghciBrowserHost] :: DynFlags -> String
+ GHC: [ghciBrowserPlaywrightBrowserType] :: DynFlags -> Maybe String
+ GHC: [ghciBrowserPlaywrightLaunchOpts] :: DynFlags -> Maybe String
+ GHC: [ghciBrowserPort] :: DynFlags -> Int
+ GHC: [ghciBrowserPuppeteerLaunchOpts] :: DynFlags -> Maybe String
+ GHC: [initiatedFrom] :: SingleStep -> Maybe SrcSpan
+ GHC: [unitSettings] :: DynFlags -> UnitSettings
+ GHC: guessTargetId :: GhcMonad m => String -> m TargetId
+ GHC: initialiseInteractiveDynFlags :: GhcMonad m => DynFlags -> HscEnv -> m HscEnv
+ GHC: isLoadedHomeModule :: GhcMonad m => Module -> m Bool
+ GHC: lookupAllQualifiedModuleNames :: GhcMonad m => PkgQual -> ModuleName -> m [Module]
+ GHC: lookupLoadedHomeModuleByModuleName :: GhcMonad m => ModuleName -> m (Maybe [Module])
+ GHC: normaliseInteractiveDynFlags :: MonadIO m => Logger -> DynFlags -> m DynFlags
+ GHC: setProgramHUG :: GhcMonad m => HomeUnitGraph -> m Bool
+ GHC: setProgramHUG_ :: GhcMonad m => Bool -> HomeUnitGraph -> m Bool
+ GHC: type BreakTickIndex = Int
+ GHC.Builtin.Names: gHC_INTERNAL_JS_PRIM :: Module
+ GHC.Builtin.Names: gHC_INTERNAL_WASM_PRIM_TYPES :: Module
+ GHC.Builtin.Names: unsafeUnpackJSStringUtf8ShShKey :: Unique
+ GHC.Builtin.Names: unsafeUnpackJSStringUtf8ShShName :: Name
+ GHC.Builtin.Names.TH: pragSpecEDIdKey :: Unique
+ GHC.Builtin.Names.TH: pragSpecEDName :: Name
+ GHC.Builtin.Names.TH: pragSpecInlEDIdKey :: Unique
+ GHC.Builtin.Names.TH: pragSpecInlEDName :: Name
+ GHC.Builtin.Names.TH: quasiQuoterTyConKey :: Unique
+ GHC.Builtin.Names.TH: quasiQuoterTyConName :: Name
+ GHC.Builtin.PrimOps: AnnotateStackOp :: PrimOp
+ GHC.Builtin.PrimOps: SetOtherThreadAllocationCounter :: PrimOp
+ GHC.Builtin.PrimOps: instance GHC.Internal.Classes.Eq GHC.Builtin.PrimOps.PrimOp
+ GHC.Builtin.PrimOps: instance GHC.Internal.Classes.Eq GHC.Builtin.PrimOps.PrimOpEffect
+ GHC.Builtin.PrimOps: instance GHC.Internal.Classes.Ord GHC.Builtin.PrimOps.PrimOp
+ GHC.Builtin.PrimOps: instance GHC.Internal.Classes.Ord GHC.Builtin.PrimOps.PrimOpEffect
+ GHC.Builtin.Types: isBuiltInOcc :: OccName -> Bool
+ GHC.Builtin.Types: isInfiniteFamilyOrigName_maybe :: Module -> OccName -> Maybe Name
+ GHC.Builtin.Types: isSumTyOrigName_maybe :: Module -> OccName -> Maybe Name
+ GHC.Builtin.Types: isTupleTyOrigName_maybe :: Module -> OccName -> Maybe Name
+ GHC.Builtin.Types: unboxedSoloDataConName :: Name
+ GHC.Builtin.Types: unboxedSoloTyCon :: TyCon
+ GHC.Builtin.Types: unboxedSoloTyConName :: Name
+ GHC.Builtin.Types: unboxedSumDataConName :: ConTag -> Arity -> Name
+ GHC.Builtin.Types: unboxedSumTyConName :: Arity -> Name
+ GHC.Builtin.Uniques: isCTupleTyConUnique :: Unique -> Maybe Arity
+ GHC.ByteCode.Asm: assembleBCO :: Platform -> ProtoBCO Name -> IO UnlinkedBCO
+ GHC.ByteCode.Asm: instance GHC.ByteCode.Asm.MonadAssembler GHC.ByteCode.Asm.InspectAsm
+ GHC.ByteCode.Asm: instance GHC.ByteCode.Asm.MonadAssembler GHC.ByteCode.Asm.RunAsm
+ GHC.ByteCode.Asm: instance GHC.Internal.Base.Applicative GHC.ByteCode.Asm.InspectAsm
+ GHC.ByteCode.Asm: instance GHC.Internal.Base.Applicative GHC.ByteCode.Asm.RunAsm
+ GHC.ByteCode.Asm: instance GHC.Internal.Base.Functor GHC.ByteCode.Asm.InspectAsm
+ GHC.ByteCode.Asm: instance GHC.Internal.Base.Functor GHC.ByteCode.Asm.OneOrTwo
+ GHC.ByteCode.Asm: instance GHC.Internal.Base.Functor GHC.ByteCode.Asm.RunAsm
+ GHC.ByteCode.Asm: instance GHC.Internal.Base.Monad GHC.ByteCode.Asm.InspectAsm
+ GHC.ByteCode.Asm: instance GHC.Internal.Base.Monad GHC.ByteCode.Asm.RunAsm
+ GHC.ByteCode.Asm: instance GHC.Utils.Outputable.Outputable GHC.ByteCode.Asm.InspectState
+ GHC.ByteCode.Breakpoints: CgBreakInfo :: [IfaceTvBndr] -> [Maybe (IfaceIdBndr, Word)] -> IfaceType -> Either InternalBreakLoc BreakpointId -> CgBreakInfo
+ GHC.ByteCode.Breakpoints: InternalBreakLoc :: BreakpointId -> InternalBreakLoc
+ GHC.ByteCode.Breakpoints: InternalBreakpointId :: Module -> BreakInfoIndex -> InternalBreakpointId
+ GHC.ByteCode.Breakpoints: InternalModBreaks :: IntMap CgBreakInfo -> ModBreaks -> InternalModBreaks
+ GHC.ByteCode.Breakpoints: [cgb_resty] :: CgBreakInfo -> IfaceType
+ GHC.ByteCode.Breakpoints: [cgb_tick_id] :: CgBreakInfo -> Either InternalBreakLoc BreakpointId
+ GHC.ByteCode.Breakpoints: [cgb_tyvars] :: CgBreakInfo -> [IfaceTvBndr]
+ GHC.ByteCode.Breakpoints: [cgb_vars] :: CgBreakInfo -> [Maybe (IfaceIdBndr, Word)]
+ GHC.ByteCode.Breakpoints: [ibi_info_index] :: InternalBreakpointId -> BreakInfoIndex
+ GHC.ByteCode.Breakpoints: [ibi_info_mod] :: InternalBreakpointId -> Module
+ GHC.ByteCode.Breakpoints: [imodBreaks_breakInfo] :: InternalModBreaks -> IntMap CgBreakInfo
+ GHC.ByteCode.Breakpoints: [imodBreaks_modBreaks] :: InternalModBreaks -> ModBreaks
+ GHC.ByteCode.Breakpoints: [internalBreakLoc] :: InternalBreakLoc -> BreakpointId
+ GHC.ByteCode.Breakpoints: data CgBreakInfo
+ GHC.ByteCode.Breakpoints: data InternalBreakpointId
+ GHC.ByteCode.Breakpoints: data InternalModBreaks
+ GHC.ByteCode.Breakpoints: getBreakCCS :: (Module -> IO ModBreaks) -> InternalBreakpointId -> InternalModBreaks -> IO (String, String)
+ GHC.ByteCode.Breakpoints: getBreakDecls :: (Module -> IO ModBreaks) -> InternalBreakpointId -> InternalModBreaks -> IO [String]
+ GHC.ByteCode.Breakpoints: getBreakLoc :: (Module -> IO ModBreaks) -> InternalBreakpointId -> InternalModBreaks -> IO SrcSpan
+ GHC.ByteCode.Breakpoints: getBreakSourceId :: InternalBreakpointId -> InternalModBreaks -> BreakpointId
+ GHC.ByteCode.Breakpoints: getBreakSourceMod :: InternalBreakpointId -> InternalModBreaks -> Module
+ GHC.ByteCode.Breakpoints: getBreakVars :: (Module -> IO ModBreaks) -> InternalBreakpointId -> InternalModBreaks -> IO [OccName]
+ GHC.ByteCode.Breakpoints: getInternalBreak :: InternalBreakpointId -> InternalModBreaks -> CgBreakInfo
+ GHC.ByteCode.Breakpoints: imodBreaks_module :: InternalModBreaks -> Module
+ GHC.ByteCode.Breakpoints: instance Control.DeepSeq.NFData GHC.ByteCode.Breakpoints.InternalBreakLoc
+ GHC.ByteCode.Breakpoints: instance Control.DeepSeq.NFData GHC.ByteCode.Breakpoints.InternalBreakpointId
+ GHC.ByteCode.Breakpoints: instance GHC.Internal.Classes.Eq GHC.ByteCode.Breakpoints.InternalBreakLoc
+ GHC.ByteCode.Breakpoints: instance GHC.Internal.Classes.Eq GHC.ByteCode.Breakpoints.InternalBreakpointId
+ GHC.ByteCode.Breakpoints: instance GHC.Internal.Classes.Ord GHC.ByteCode.Breakpoints.InternalBreakpointId
+ GHC.ByteCode.Breakpoints: instance GHC.Utils.Outputable.Outputable GHC.ByteCode.Breakpoints.CgBreakInfo
+ GHC.ByteCode.Breakpoints: instance GHC.Utils.Outputable.Outputable GHC.ByteCode.Breakpoints.InternalBreakLoc
+ GHC.ByteCode.Breakpoints: instance GHC.Utils.Outputable.Outputable GHC.ByteCode.Breakpoints.InternalBreakpointId
+ GHC.ByteCode.Breakpoints: mkInternalModBreaks :: Module -> IntMap CgBreakInfo -> ModBreaks -> InternalModBreaks
+ GHC.ByteCode.Breakpoints: newtype InternalBreakLoc
+ GHC.ByteCode.Breakpoints: seqInternalModBreaks :: InternalModBreaks -> ()
+ GHC.ByteCode.Breakpoints: type BreakInfoIndex = Int
+ GHC.ByteCode.Instr: instance GHC.Internal.Classes.Eq GHC.ByteCode.Instr.LocalLabel
+ GHC.ByteCode.Instr: instance GHC.Internal.Classes.Ord GHC.ByteCode.Instr.LocalLabel
+ GHC.ByteCode.Instr: instance GHC.Types.Unique.Uniquable GHC.ByteCode.Instr.LocalLabel
+ GHC.ByteCode.Types: BCONPtrCostCentre :: InternalBreakpointId -> BCONPtr
+ GHC.ByteCode.Types: BCONPtrFFIInfo :: FFIInfo -> BCONPtr
+ GHC.ByteCode.Types: BCONPtrFS :: FastString -> BCONPtr
+ GHC.ByteCode.Types: BreakpointId :: Module -> BreakTickIndex -> BreakpointId
+ GHC.ByteCode.Types: InternalBreakpointId :: Module -> BreakInfoIndex -> InternalBreakpointId
+ GHC.ByteCode.Types: InternalModBreaks :: IntMap CgBreakInfo -> ModBreaks -> InternalModBreaks
+ GHC.ByteCode.Types: [bi_tick_index] :: BreakpointId -> BreakTickIndex
+ GHC.ByteCode.Types: [bi_tick_mod] :: BreakpointId -> Module
+ GHC.ByteCode.Types: [cgb_tick_id] :: CgBreakInfo -> Either InternalBreakLoc BreakpointId
+ GHC.ByteCode.Types: [ffiInfoArgs] :: FFIInfo -> [FFIType]
+ GHC.ByteCode.Types: [ffiInfoRet] :: FFIInfo -> FFIType
+ GHC.ByteCode.Types: [ibi_info_index] :: InternalBreakpointId -> BreakInfoIndex
+ GHC.ByteCode.Types: [ibi_info_mod] :: InternalBreakpointId -> Module
+ GHC.ByteCode.Types: [imodBreaks_breakInfo] :: InternalModBreaks -> IntMap CgBreakInfo
+ GHC.ByteCode.Types: [imodBreaks_modBreaks] :: InternalModBreaks -> ModBreaks
+ GHC.ByteCode.Types: data BreakpointId
+ GHC.ByteCode.Types: data FFIInfo
+ GHC.ByteCode.Types: data InternalBreakpointId
+ GHC.ByteCode.Types: data InternalModBreaks
+ GHC.ByteCode.Types: fromSmallArray :: SmallArray a -> FlatBag a
+ GHC.ByteCode.Types: instance GHC.Internal.Classes.Eq GHC.ByteCode.Types.ByteOff
+ GHC.ByteCode.Types: instance GHC.Internal.Classes.Eq GHC.ByteCode.Types.HalfWord
+ GHC.ByteCode.Types: instance GHC.Internal.Classes.Eq GHC.ByteCode.Types.NativeCallType
+ GHC.ByteCode.Types: instance GHC.Internal.Classes.Eq GHC.ByteCode.Types.RegBitmap
+ GHC.ByteCode.Types: instance GHC.Internal.Classes.Eq GHC.ByteCode.Types.WordOff
+ GHC.ByteCode.Types: instance GHC.Internal.Classes.Ord GHC.ByteCode.Types.ByteOff
+ GHC.ByteCode.Types: instance GHC.Internal.Classes.Ord GHC.ByteCode.Types.HalfWord
+ GHC.ByteCode.Types: instance GHC.Internal.Classes.Ord GHC.ByteCode.Types.RegBitmap
+ GHC.ByteCode.Types: instance GHC.Internal.Classes.Ord GHC.ByteCode.Types.WordOff
+ GHC.ByteCode.Types: seqInternalModBreaks :: InternalModBreaks -> ()
+ GHC.ByteCode.Types: type BreakInfoIndex = Int
+ GHC.ByteCode.Types: type BreakTickIndex = Int
+ GHC.Cmm: instance GHC.Internal.Classes.Eq GHC.Cmm.CmmInfoTable
+ GHC.Cmm: instance GHC.Internal.Classes.Eq GHC.Cmm.ProfilingInfo
+ GHC.Cmm: instance GHC.Internal.Classes.Eq GHC.Cmm.SectionProtection
+ GHC.Cmm: instance GHC.Internal.Classes.Ord GHC.Cmm.CmmInfoTable
+ GHC.Cmm: instance GHC.Internal.Classes.Ord GHC.Cmm.ProfilingInfo
+ GHC.Cmm.CLabel: instance GHC.Internal.Classes.Eq GHC.Cmm.CLabel.CLabel
+ GHC.Cmm.CLabel: instance GHC.Internal.Classes.Eq GHC.Cmm.CLabel.CmmLabelInfo
+ GHC.Cmm.CLabel: instance GHC.Internal.Classes.Eq GHC.Cmm.CLabel.ConInfoTableLocation
+ GHC.Cmm.CLabel: instance GHC.Internal.Classes.Eq GHC.Cmm.CLabel.DynamicLinkerLabelInfo
+ GHC.Cmm.CLabel: instance GHC.Internal.Classes.Eq GHC.Cmm.CLabel.ForeignLabelSource
+ GHC.Cmm.CLabel: instance GHC.Internal.Classes.Eq GHC.Cmm.CLabel.IdLabelInfo
+ GHC.Cmm.CLabel: instance GHC.Internal.Classes.Eq GHC.Cmm.CLabel.InfoProvEnt
+ GHC.Cmm.CLabel: instance GHC.Internal.Classes.Eq GHC.Cmm.CLabel.ModuleLabelKind
+ GHC.Cmm.CLabel: instance GHC.Internal.Classes.Eq GHC.Cmm.CLabel.NeedExternDecl
+ GHC.Cmm.CLabel: instance GHC.Internal.Classes.Eq GHC.Cmm.CLabel.RtsLabelInfo
+ GHC.Cmm.CLabel: instance GHC.Internal.Classes.Eq GHC.Cmm.CLabel.TickyIdInfo
+ GHC.Cmm.CLabel: instance GHC.Internal.Classes.Ord GHC.Cmm.CLabel.CLabel
+ GHC.Cmm.CLabel: instance GHC.Internal.Classes.Ord GHC.Cmm.CLabel.CmmLabelInfo
+ GHC.Cmm.CLabel: instance GHC.Internal.Classes.Ord GHC.Cmm.CLabel.ConInfoTableLocation
+ GHC.Cmm.CLabel: instance GHC.Internal.Classes.Ord GHC.Cmm.CLabel.DynamicLinkerLabelInfo
+ GHC.Cmm.CLabel: instance GHC.Internal.Classes.Ord GHC.Cmm.CLabel.ForeignLabelSource
+ GHC.Cmm.CLabel: instance GHC.Internal.Classes.Ord GHC.Cmm.CLabel.IdLabelInfo
+ GHC.Cmm.CLabel: instance GHC.Internal.Classes.Ord GHC.Cmm.CLabel.InfoProvEnt
+ GHC.Cmm.CLabel: instance GHC.Internal.Classes.Ord GHC.Cmm.CLabel.ModuleLabelKind
+ GHC.Cmm.CLabel: instance GHC.Internal.Classes.Ord GHC.Cmm.CLabel.NeedExternDecl
+ GHC.Cmm.CLabel: instance GHC.Internal.Classes.Ord GHC.Cmm.CLabel.RtsLabelInfo
+ GHC.Cmm.CLabel: instance GHC.Internal.Classes.Ord GHC.Cmm.CLabel.TickyIdInfo
+ GHC.Cmm.Dataflow.Label: instance GHC.Internal.Classes.Eq GHC.Cmm.Dataflow.Label.Label
+ GHC.Cmm.Dataflow.Label: instance GHC.Internal.Classes.Eq GHC.Cmm.Dataflow.Label.LabelSet
+ GHC.Cmm.Dataflow.Label: instance GHC.Internal.Classes.Eq v => GHC.Internal.Classes.Eq (GHC.Cmm.Dataflow.Label.LabelMap v)
+ GHC.Cmm.Dataflow.Label: instance GHC.Internal.Classes.Ord GHC.Cmm.Dataflow.Label.Label
+ GHC.Cmm.Dataflow.Label: instance GHC.Internal.Classes.Ord GHC.Cmm.Dataflow.Label.LabelSet
+ GHC.Cmm.Dataflow.Label: instance GHC.Internal.Classes.Ord v => GHC.Internal.Classes.Ord (GHC.Cmm.Dataflow.Label.LabelMap v)
+ GHC.Cmm.Dataflow.Label: mapMapMaybe :: (a -> Maybe b) -> LabelMap a -> LabelMap b
+ GHC.Cmm.DebugBlock: instance GHC.Internal.Classes.Eq GHC.Cmm.DebugBlock.UnwindExpr
+ GHC.Cmm.Dominators: instance GHC.Internal.Classes.Eq GHC.Cmm.Dominators.DominatorSet
+ GHC.Cmm.Dominators: instance GHC.Internal.Classes.Eq GHC.Cmm.Dominators.RPNum
+ GHC.Cmm.Dominators: instance GHC.Internal.Classes.Ord GHC.Cmm.Dominators.RPNum
+ GHC.Cmm.Expr: instance (GHC.Internal.Classes.Ord r, GHC.Cmm.Expr.UserOfRegs r GHC.Cmm.Reg.CmmReg) => GHC.Cmm.Expr.UserOfRegs r GHC.Cmm.Expr.CmmExpr
+ GHC.Cmm.Expr: instance GHC.Internal.Classes.Eq GHC.Cmm.Expr.AlignmentSpec
+ GHC.Cmm.Expr: instance GHC.Internal.Classes.Eq GHC.Cmm.Expr.Area
+ GHC.Cmm.Expr: instance GHC.Internal.Classes.Eq GHC.Cmm.Expr.CmmExpr
+ GHC.Cmm.Expr: instance GHC.Internal.Classes.Eq GHC.Cmm.Expr.CmmLit
+ GHC.Cmm.Expr: instance GHC.Internal.Classes.Ord GHC.Cmm.Expr.AlignmentSpec
+ GHC.Cmm.Expr: instance GHC.Internal.Classes.Ord GHC.Cmm.Expr.Area
+ GHC.Cmm.Expr: instance GHC.Internal.Classes.Ord r => GHC.Cmm.Expr.DefinerOfRegs r r
+ GHC.Cmm.Expr: instance GHC.Internal.Classes.Ord r => GHC.Cmm.Expr.UserOfRegs r r
+ GHC.Cmm.Graph: instance GHC.Internal.Classes.Eq GHC.Cmm.Graph.Transfer
+ GHC.Cmm.Info.Build: instance GHC.Internal.Classes.Eq GHC.Cmm.Info.Build.CAFfyLabel
+ GHC.Cmm.Info.Build: instance GHC.Internal.Classes.Eq GHC.Cmm.Info.Build.SRTEntry
+ GHC.Cmm.Info.Build: instance GHC.Internal.Classes.Eq GHC.Cmm.Info.Build.SomeLabel
+ GHC.Cmm.Info.Build: instance GHC.Internal.Classes.Ord GHC.Cmm.Info.Build.CAFfyLabel
+ GHC.Cmm.Info.Build: instance GHC.Internal.Classes.Ord GHC.Cmm.Info.Build.SRTEntry
+ GHC.Cmm.Info.Build: instance GHC.Internal.Classes.Ord GHC.Cmm.Info.Build.SomeLabel
+ GHC.Cmm.MachOp: MO_I64X2_Max :: CallishMachOp
+ GHC.Cmm.MachOp: MO_I64X2_Min :: CallishMachOp
+ GHC.Cmm.MachOp: MO_W64X2_Max :: CallishMachOp
+ GHC.Cmm.MachOp: MO_W64X2_Min :: CallishMachOp
+ GHC.Cmm.MachOp: callishMachOpArgTys :: Platform -> CallishMachOp -> [CmmType]
+ GHC.Cmm.MachOp: instance GHC.Internal.Classes.Eq GHC.Cmm.MachOp.AtomicMachOp
+ GHC.Cmm.MachOp: instance GHC.Internal.Classes.Eq GHC.Cmm.MachOp.CallishMachOp
+ GHC.Cmm.MachOp: instance GHC.Internal.Classes.Eq GHC.Cmm.MachOp.FMASign
+ GHC.Cmm.MachOp: instance GHC.Internal.Classes.Eq GHC.Cmm.MachOp.MachOp
+ GHC.Cmm.MachOp: instance GHC.Internal.Classes.Eq GHC.Cmm.MachOp.MemoryOrdering
+ GHC.Cmm.MachOp: instance GHC.Internal.Classes.Ord GHC.Cmm.MachOp.MemoryOrdering
+ GHC.Cmm.Node: instance (GHC.Internal.Classes.Ord r, GHC.Cmm.Expr.UserOfRegs r GHC.Cmm.Reg.CmmReg) => GHC.Cmm.Expr.UserOfRegs r GHC.Cmm.Node.ForeignTarget
+ GHC.Cmm.Node: instance GHC.Internal.Classes.Eq (GHC.Cmm.Node.CmmNode e x)
+ GHC.Cmm.Node: instance GHC.Internal.Classes.Eq GHC.Cmm.Node.CmmReturnInfo
+ GHC.Cmm.Node: instance GHC.Internal.Classes.Eq GHC.Cmm.Node.CmmTickScope
+ GHC.Cmm.Node: instance GHC.Internal.Classes.Eq GHC.Cmm.Node.Convention
+ GHC.Cmm.Node: instance GHC.Internal.Classes.Eq GHC.Cmm.Node.ForeignConvention
+ GHC.Cmm.Node: instance GHC.Internal.Classes.Eq GHC.Cmm.Node.ForeignTarget
+ GHC.Cmm.Node: instance GHC.Internal.Classes.Ord GHC.Cmm.Node.CmmTickScope
+ GHC.Cmm.Reducibility: instance GHC.Internal.Classes.Eq GHC.Cmm.Reducibility.Reducibility
+ GHC.Cmm.Reg: instance GHC.Internal.Classes.Eq GHC.Cmm.Reg.CmmReg
+ GHC.Cmm.Reg: instance GHC.Internal.Classes.Eq GHC.Cmm.Reg.GlobalArgRegs
+ GHC.Cmm.Reg: instance GHC.Internal.Classes.Eq GHC.Cmm.Reg.GlobalReg
+ GHC.Cmm.Reg: instance GHC.Internal.Classes.Eq GHC.Cmm.Reg.GlobalRegUse
+ GHC.Cmm.Reg: instance GHC.Internal.Classes.Eq GHC.Cmm.Reg.LocalReg
+ GHC.Cmm.Reg: instance GHC.Internal.Classes.Ord GHC.Cmm.Reg.CmmReg
+ GHC.Cmm.Reg: instance GHC.Internal.Classes.Ord GHC.Cmm.Reg.GlobalArgRegs
+ GHC.Cmm.Reg: instance GHC.Internal.Classes.Ord GHC.Cmm.Reg.GlobalReg
+ GHC.Cmm.Reg: instance GHC.Internal.Classes.Ord GHC.Cmm.Reg.GlobalRegUse
+ GHC.Cmm.Reg: instance GHC.Internal.Classes.Ord GHC.Cmm.Reg.LocalReg
+ GHC.Cmm.Switch: instance GHC.Internal.Classes.Eq GHC.Cmm.Switch.SwitchTargets
+ GHC.Cmm.Type: instance GHC.Internal.Classes.Eq GHC.Cmm.Type.CmmCat
+ GHC.Cmm.Type: instance GHC.Internal.Classes.Eq GHC.Cmm.Type.ForeignHint
+ GHC.Cmm.Type: instance GHC.Internal.Classes.Eq GHC.Cmm.Type.Width
+ GHC.Cmm.Type: instance GHC.Internal.Classes.Ord GHC.Cmm.Type.Width
+ GHC.CmmToAsm.AArch64.Cond: instance GHC.Internal.Classes.Eq GHC.CmmToAsm.AArch64.Cond.Cond
+ GHC.CmmToAsm.AArch64.Instr: J_TBL :: [Maybe BlockId] -> Maybe CLabel -> Reg -> Instr
+ GHC.CmmToAsm.AArch64.Instr: instance GHC.Internal.Classes.Eq GHC.CmmToAsm.AArch64.Instr.DMBISHFlags
+ GHC.CmmToAsm.AArch64.Instr: instance GHC.Internal.Classes.Eq GHC.CmmToAsm.AArch64.Instr.ExtMode
+ GHC.CmmToAsm.AArch64.Instr: instance GHC.Internal.Classes.Eq GHC.CmmToAsm.AArch64.Instr.Operand
+ GHC.CmmToAsm.AArch64.Instr: instance GHC.Internal.Classes.Eq GHC.CmmToAsm.AArch64.Instr.ShiftMode
+ GHC.CmmToAsm.AArch64.Instr: instance GHC.Internal.Classes.Eq GHC.CmmToAsm.AArch64.Instr.Target
+ GHC.CmmToAsm.AArch64.Instr: instance GHC.Internal.Classes.Ord GHC.CmmToAsm.AArch64.Instr.Target
+ GHC.CmmToAsm.AArch64.Regs: instance GHC.Internal.Classes.Eq GHC.CmmToAsm.AArch64.Regs.AddrMode
+ GHC.CmmToAsm.AArch64.Regs: instance GHC.Internal.Classes.Eq GHC.CmmToAsm.AArch64.Regs.Imm
+ GHC.CmmToAsm.BlockLayout: instance GHC.Internal.Classes.Eq GHC.CmmToAsm.BlockLayout.BlockChain
+ GHC.CmmToAsm.BlockLayout: instance GHC.Internal.Classes.Ord GHC.CmmToAsm.BlockLayout.BlockChain
+ GHC.CmmToAsm.CFG: instance GHC.Internal.Classes.Eq GHC.CmmToAsm.CFG.BranchInfo
+ GHC.CmmToAsm.CFG: instance GHC.Internal.Classes.Eq GHC.CmmToAsm.CFG.CfgEdge
+ GHC.CmmToAsm.CFG: instance GHC.Internal.Classes.Eq GHC.CmmToAsm.CFG.EdgeInfo
+ GHC.CmmToAsm.CFG: instance GHC.Internal.Classes.Eq GHC.CmmToAsm.CFG.EdgeWeight
+ GHC.CmmToAsm.CFG: instance GHC.Internal.Classes.Eq GHC.CmmToAsm.CFG.TransitionSource
+ GHC.CmmToAsm.CFG: instance GHC.Internal.Classes.Ord GHC.CmmToAsm.CFG.CfgEdge
+ GHC.CmmToAsm.CFG: instance GHC.Internal.Classes.Ord GHC.CmmToAsm.CFG.EdgeWeight
+ GHC.CmmToAsm.Dwarf.Types: instance GHC.Internal.Classes.Eq GHC.CmmToAsm.Dwarf.Types.DwarfAbbrev
+ GHC.CmmToAsm.Format: instance GHC.Internal.Classes.Eq GHC.CmmToAsm.Format.Format
+ GHC.CmmToAsm.Format: instance GHC.Internal.Classes.Eq GHC.CmmToAsm.Format.ScalarFormat
+ GHC.CmmToAsm.Format: instance GHC.Internal.Classes.Ord GHC.CmmToAsm.Format.Format
+ GHC.CmmToAsm.Format: instance GHC.Internal.Classes.Ord GHC.CmmToAsm.Format.ScalarFormat
+ GHC.CmmToAsm.LA64: instance GHC.CmmToAsm.Instr.Instruction GHC.CmmToAsm.LA64.Instr.Instr
+ GHC.CmmToAsm.LA64: ncgLA64 :: NCGConfig -> NcgImpl RawCmmStatics Instr JumpDest
+ GHC.CmmToAsm.LA64.CodeGen: cmmTopCodeGen :: RawCmmDecl -> NatM [NatCmmDecl RawCmmStatics Instr]
+ GHC.CmmToAsm.LA64.CodeGen: generateJumpTableForInstr :: NCGConfig -> Instr -> Maybe (NatCmmDecl RawCmmStatics Instr)
+ GHC.CmmToAsm.LA64.CodeGen: makeFarBranches :: Platform -> LabelMap RawCmmStatics -> [NatBasicBlock Instr] -> UniqDSM [NatBasicBlock Instr]
+ GHC.CmmToAsm.LA64.Cond: EQ :: Cond
+ GHC.CmmToAsm.LA64.Cond: EQZ :: Cond
+ GHC.CmmToAsm.LA64.Cond: FGE :: Cond
+ GHC.CmmToAsm.LA64.Cond: FGT :: Cond
+ GHC.CmmToAsm.LA64.Cond: FLE :: Cond
+ GHC.CmmToAsm.LA64.Cond: FLT :: Cond
+ GHC.CmmToAsm.LA64.Cond: GE :: Cond
+ GHC.CmmToAsm.LA64.Cond: GEU :: Cond
+ GHC.CmmToAsm.LA64.Cond: LT :: Cond
+ GHC.CmmToAsm.LA64.Cond: LTU :: Cond
+ GHC.CmmToAsm.LA64.Cond: NE :: Cond
+ GHC.CmmToAsm.LA64.Cond: NEZ :: Cond
+ GHC.CmmToAsm.LA64.Cond: SGE :: Cond
+ GHC.CmmToAsm.LA64.Cond: SGT :: Cond
+ GHC.CmmToAsm.LA64.Cond: SLE :: Cond
+ GHC.CmmToAsm.LA64.Cond: SLT :: Cond
+ GHC.CmmToAsm.LA64.Cond: UGE :: Cond
+ GHC.CmmToAsm.LA64.Cond: UGT :: Cond
+ GHC.CmmToAsm.LA64.Cond: ULE :: Cond
+ GHC.CmmToAsm.LA64.Cond: ULT :: Cond
+ GHC.CmmToAsm.LA64.Cond: data Cond
+ GHC.CmmToAsm.LA64.Cond: instance GHC.Internal.Classes.Eq GHC.CmmToAsm.LA64.Cond.Cond
+ GHC.CmmToAsm.LA64.Cond: instance GHC.Internal.Show.Show GHC.CmmToAsm.LA64.Cond.Cond
+ GHC.CmmToAsm.LA64.Instr: ADD :: Operand -> Operand -> Operand -> Instr
+ GHC.CmmToAsm.LA64.Instr: ALSL :: Operand -> Operand -> Operand -> Operand -> Instr
+ GHC.CmmToAsm.LA64.Instr: ALSLU :: Operand -> Operand -> Operand -> Operand -> Instr
+ GHC.CmmToAsm.LA64.Instr: AND :: Operand -> Operand -> Operand -> Instr
+ GHC.CmmToAsm.LA64.Instr: ANDN :: Operand -> Operand -> Operand -> Instr
+ GHC.CmmToAsm.LA64.Instr: ANN :: SDoc -> Instr -> Instr
+ GHC.CmmToAsm.LA64.Instr: B :: Target -> Instr
+ GHC.CmmToAsm.LA64.Instr: BCOND :: Cond -> Operand -> Operand -> Target -> Instr
+ GHC.CmmToAsm.LA64.Instr: BCOND1 :: Cond -> Operand -> Operand -> Target -> Instr
+ GHC.CmmToAsm.LA64.Instr: BEQZ :: Operand -> Target -> Instr
+ GHC.CmmToAsm.LA64.Instr: BITREV4B :: Operand -> Operand -> Instr
+ GHC.CmmToAsm.LA64.Instr: BITREV8B :: Operand -> Operand -> Instr
+ GHC.CmmToAsm.LA64.Instr: BITREVD :: Operand -> Operand -> Instr
+ GHC.CmmToAsm.LA64.Instr: BITREVW :: Operand -> Operand -> Instr
+ GHC.CmmToAsm.LA64.Instr: BL :: Target -> [Reg] -> Instr
+ GHC.CmmToAsm.LA64.Instr: BNEZ :: Operand -> Target -> Instr
+ GHC.CmmToAsm.LA64.Instr: BSTRINS :: Format -> Operand -> Operand -> Operand -> Operand -> Instr
+ GHC.CmmToAsm.LA64.Instr: BSTRPICK :: Format -> Operand -> Operand -> Operand -> Operand -> Instr
+ GHC.CmmToAsm.LA64.Instr: BYTEPICK :: Operand -> Operand -> Operand -> Operand -> Instr
+ GHC.CmmToAsm.LA64.Instr: CALL :: Target -> [Reg] -> Instr
+ GHC.CmmToAsm.LA64.Instr: CALL36 :: Target -> Instr
+ GHC.CmmToAsm.LA64.Instr: CLO :: Operand -> Operand -> Instr
+ GHC.CmmToAsm.LA64.Instr: CLZ :: Operand -> Operand -> Instr
+ GHC.CmmToAsm.LA64.Instr: COMMENT :: SDoc -> Instr
+ GHC.CmmToAsm.LA64.Instr: CSET :: Cond -> Operand -> Operand -> Operand -> Instr
+ GHC.CmmToAsm.LA64.Instr: CTO :: Operand -> Operand -> Instr
+ GHC.CmmToAsm.LA64.Instr: CTZ :: Operand -> Operand -> Instr
+ GHC.CmmToAsm.LA64.Instr: DBAR :: BarrierType -> Instr
+ GHC.CmmToAsm.LA64.Instr: DELTA :: Int -> Instr
+ GHC.CmmToAsm.LA64.Instr: DIV :: Operand -> Operand -> Operand -> Instr
+ GHC.CmmToAsm.LA64.Instr: DIVU :: Operand -> Operand -> Operand -> Instr
+ GHC.CmmToAsm.LA64.Instr: EXT :: Operand -> Operand -> Instr
+ GHC.CmmToAsm.LA64.Instr: FABS :: Operand -> Operand -> Instr
+ GHC.CmmToAsm.LA64.Instr: FCVT :: Operand -> Operand -> Instr
+ GHC.CmmToAsm.LA64.Instr: FCVTZS :: Operand -> Operand -> Operand -> Instr
+ GHC.CmmToAsm.LA64.Instr: FMA :: FMASign -> Operand -> Operand -> Operand -> Operand -> Instr
+ GHC.CmmToAsm.LA64.Instr: FMAX :: Operand -> Operand -> Operand -> Instr
+ GHC.CmmToAsm.LA64.Instr: FMAXA :: Operand -> Operand -> Operand -> Instr
+ GHC.CmmToAsm.LA64.Instr: FMIN :: Operand -> Operand -> Operand -> Instr
+ GHC.CmmToAsm.LA64.Instr: FMINA :: Operand -> Operand -> Operand -> Instr
+ GHC.CmmToAsm.LA64.Instr: FNEG :: Operand -> Operand -> Instr
+ GHC.CmmToAsm.LA64.Instr: FSQRT :: Operand -> Operand -> Instr
+ GHC.CmmToAsm.LA64.Instr: Hint0 :: BarrierType
+ GHC.CmmToAsm.LA64.Instr: IBAR :: BarrierType -> Instr
+ GHC.CmmToAsm.LA64.Instr: J :: Target -> Instr
+ GHC.CmmToAsm.LA64.Instr: J_TBL :: [Maybe BlockId] -> Maybe CLabel -> Reg -> Instr
+ GHC.CmmToAsm.LA64.Instr: LD :: Format -> Operand -> Operand -> Instr
+ GHC.CmmToAsm.LA64.Instr: LDATA :: Section -> RawCmmStatics -> Instr
+ GHC.CmmToAsm.LA64.Instr: LDPTR :: Format -> Operand -> Operand -> Instr
+ GHC.CmmToAsm.LA64.Instr: LDU :: Format -> Operand -> Operand -> Instr
+ GHC.CmmToAsm.LA64.Instr: LDX :: Format -> Operand -> Operand -> Instr
+ GHC.CmmToAsm.LA64.Instr: LDXU :: Format -> Operand -> Operand -> Instr
+ GHC.CmmToAsm.LA64.Instr: LOCATION :: Int -> Int -> Int -> LexicalFastString -> Instr
+ GHC.CmmToAsm.LA64.Instr: LU12I :: Operand -> Operand -> Instr
+ GHC.CmmToAsm.LA64.Instr: LU32I :: Operand -> Operand -> Instr
+ GHC.CmmToAsm.LA64.Instr: LU52I :: Operand -> Operand -> Operand -> Instr
+ GHC.CmmToAsm.LA64.Instr: MASKEQZ :: Operand -> Operand -> Operand -> Instr
+ GHC.CmmToAsm.LA64.Instr: MASKNEZ :: Operand -> Operand -> Operand -> Instr
+ GHC.CmmToAsm.LA64.Instr: MOD :: Operand -> Operand -> Operand -> Instr
+ GHC.CmmToAsm.LA64.Instr: MODU :: Operand -> Operand -> Operand -> Instr
+ GHC.CmmToAsm.LA64.Instr: MOV :: Operand -> Operand -> Instr
+ GHC.CmmToAsm.LA64.Instr: MUL :: Operand -> Operand -> Operand -> Instr
+ GHC.CmmToAsm.LA64.Instr: MULH :: Operand -> Operand -> Operand -> Instr
+ GHC.CmmToAsm.LA64.Instr: MULHU :: Operand -> Operand -> Operand -> Instr
+ GHC.CmmToAsm.LA64.Instr: MULTILINE_COMMENT :: SDoc -> Instr
+ GHC.CmmToAsm.LA64.Instr: MULW :: Operand -> Operand -> Operand -> Instr
+ GHC.CmmToAsm.LA64.Instr: MULWU :: Operand -> Operand -> Operand -> Instr
+ GHC.CmmToAsm.LA64.Instr: NEG :: Operand -> Operand -> Instr
+ GHC.CmmToAsm.LA64.Instr: NEWBLOCK :: BlockId -> Instr
+ GHC.CmmToAsm.LA64.Instr: NOP :: Instr
+ GHC.CmmToAsm.LA64.Instr: NOR :: Operand -> Operand -> Operand -> Instr
+ GHC.CmmToAsm.LA64.Instr: OR :: Operand -> Operand -> Operand -> Instr
+ GHC.CmmToAsm.LA64.Instr: ORN :: Operand -> Operand -> Operand -> Instr
+ GHC.CmmToAsm.LA64.Instr: OpAddr :: AddrMode -> Operand
+ GHC.CmmToAsm.LA64.Instr: OpImm :: Imm -> Operand
+ GHC.CmmToAsm.LA64.Instr: OpReg :: Width -> Reg -> Operand
+ GHC.CmmToAsm.LA64.Instr: PCADDI :: Operand -> Operand -> Instr
+ GHC.CmmToAsm.LA64.Instr: PCADDU12I :: Operand -> Operand -> Instr
+ GHC.CmmToAsm.LA64.Instr: PCADDU18I :: Operand -> Operand -> Instr
+ GHC.CmmToAsm.LA64.Instr: PCALAU12I :: Operand -> Operand -> Instr
+ GHC.CmmToAsm.LA64.Instr: POP_STACK_FRAME :: Instr
+ GHC.CmmToAsm.LA64.Instr: PRELD :: Operand -> Operand -> Instr
+ GHC.CmmToAsm.LA64.Instr: PUSH_STACK_FRAME :: Instr
+ GHC.CmmToAsm.LA64.Instr: REVB2H :: Operand -> Operand -> Instr
+ GHC.CmmToAsm.LA64.Instr: REVB2W :: Operand -> Operand -> Instr
+ GHC.CmmToAsm.LA64.Instr: REVB4H :: Operand -> Operand -> Instr
+ GHC.CmmToAsm.LA64.Instr: REVBD :: Operand -> Operand -> Instr
+ GHC.CmmToAsm.LA64.Instr: REVH2W :: Operand -> Operand -> Instr
+ GHC.CmmToAsm.LA64.Instr: REVHD :: Operand -> Operand -> Instr
+ GHC.CmmToAsm.LA64.Instr: ROTR :: Operand -> Operand -> Operand -> Instr
+ GHC.CmmToAsm.LA64.Instr: SCVTF :: Operand -> Operand -> Instr
+ GHC.CmmToAsm.LA64.Instr: SLL :: Operand -> Operand -> Operand -> Instr
+ GHC.CmmToAsm.LA64.Instr: SRA :: Operand -> Operand -> Operand -> Instr
+ GHC.CmmToAsm.LA64.Instr: SRL :: Operand -> Operand -> Operand -> Instr
+ GHC.CmmToAsm.LA64.Instr: SSLT :: Operand -> Operand -> Operand -> Instr
+ GHC.CmmToAsm.LA64.Instr: SSLTU :: Operand -> Operand -> Operand -> Instr
+ GHC.CmmToAsm.LA64.Instr: ST :: Format -> Operand -> Operand -> Instr
+ GHC.CmmToAsm.LA64.Instr: STPTR :: Format -> Operand -> Operand -> Instr
+ GHC.CmmToAsm.LA64.Instr: STX :: Format -> Operand -> Operand -> Instr
+ GHC.CmmToAsm.LA64.Instr: SUB :: Operand -> Operand -> Operand -> Instr
+ GHC.CmmToAsm.LA64.Instr: TAIL36 :: Operand -> Target -> Instr
+ GHC.CmmToAsm.LA64.Instr: TBlock :: BlockId -> Target
+ GHC.CmmToAsm.LA64.Instr: TLabel :: CLabel -> Target
+ GHC.CmmToAsm.LA64.Instr: TReg :: Reg -> Target
+ GHC.CmmToAsm.LA64.Instr: XOR :: Operand -> Operand -> Operand -> Instr
+ GHC.CmmToAsm.LA64.Instr: allocMoreStack :: Platform -> Int -> NatCmmDecl statics Instr -> UniqDSM (NatCmmDecl statics Instr, [(BlockId, BlockId)])
+ GHC.CmmToAsm.LA64.Instr: callerSavedRegisters :: [Reg]
+ GHC.CmmToAsm.LA64.Instr: canFallthroughTo :: Instr -> BlockId -> Bool
+ GHC.CmmToAsm.LA64.Instr: d0 :: Operand
+ GHC.CmmToAsm.LA64.Instr: d1 :: Operand
+ GHC.CmmToAsm.LA64.Instr: d10 :: Operand
+ GHC.CmmToAsm.LA64.Instr: d11 :: Operand
+ GHC.CmmToAsm.LA64.Instr: d12 :: Operand
+ GHC.CmmToAsm.LA64.Instr: d13 :: Operand
+ GHC.CmmToAsm.LA64.Instr: d14 :: Operand
+ GHC.CmmToAsm.LA64.Instr: d15 :: Operand
+ GHC.CmmToAsm.LA64.Instr: d16 :: Operand
+ GHC.CmmToAsm.LA64.Instr: d17 :: Operand
+ GHC.CmmToAsm.LA64.Instr: d18 :: Operand
+ GHC.CmmToAsm.LA64.Instr: d19 :: Operand
+ GHC.CmmToAsm.LA64.Instr: d2 :: Operand
+ GHC.CmmToAsm.LA64.Instr: d20 :: Operand
+ GHC.CmmToAsm.LA64.Instr: d21 :: Operand
+ GHC.CmmToAsm.LA64.Instr: d22 :: Operand
+ GHC.CmmToAsm.LA64.Instr: d23 :: Operand
+ GHC.CmmToAsm.LA64.Instr: d24 :: Operand
+ GHC.CmmToAsm.LA64.Instr: d25 :: Operand
+ GHC.CmmToAsm.LA64.Instr: d26 :: Operand
+ GHC.CmmToAsm.LA64.Instr: d27 :: Operand
+ GHC.CmmToAsm.LA64.Instr: d28 :: Operand
+ GHC.CmmToAsm.LA64.Instr: d29 :: Operand
+ GHC.CmmToAsm.LA64.Instr: d3 :: Operand
+ GHC.CmmToAsm.LA64.Instr: d30 :: Operand
+ GHC.CmmToAsm.LA64.Instr: d31 :: Operand
+ GHC.CmmToAsm.LA64.Instr: d4 :: Operand
+ GHC.CmmToAsm.LA64.Instr: d5 :: Operand
+ GHC.CmmToAsm.LA64.Instr: d6 :: Operand
+ GHC.CmmToAsm.LA64.Instr: d7 :: Operand
+ GHC.CmmToAsm.LA64.Instr: d8 :: Operand
+ GHC.CmmToAsm.LA64.Instr: d9 :: Operand
+ GHC.CmmToAsm.LA64.Instr: data BarrierType
+ GHC.CmmToAsm.LA64.Instr: data Instr
+ GHC.CmmToAsm.LA64.Instr: data Operand
+ GHC.CmmToAsm.LA64.Instr: data Target
+ GHC.CmmToAsm.LA64.Instr: fitsInNbits :: Int -> Int -> Bool
+ GHC.CmmToAsm.LA64.Instr: fp :: Operand
+ GHC.CmmToAsm.LA64.Instr: instance GHC.Internal.Classes.Eq GHC.CmmToAsm.LA64.Instr.Operand
+ GHC.CmmToAsm.LA64.Instr: instance GHC.Internal.Show.Show GHC.CmmToAsm.LA64.Instr.Operand
+ GHC.CmmToAsm.LA64.Instr: instance GHC.Utils.Outputable.Outputable GHC.CmmToAsm.Instr.RegUsage
+ GHC.CmmToAsm.LA64.Instr: instrCon :: Instr -> String
+ GHC.CmmToAsm.LA64.Instr: isEncodeableInWidth :: Width -> Integer -> Bool
+ GHC.CmmToAsm.LA64.Instr: isFloatOp :: Operand -> Bool
+ GHC.CmmToAsm.LA64.Instr: isFloatReg :: Reg -> Bool
+ GHC.CmmToAsm.LA64.Instr: isIntOp :: Operand -> Bool
+ GHC.CmmToAsm.LA64.Instr: isJumpishInstr :: Instr -> Bool
+ GHC.CmmToAsm.LA64.Instr: isMetaInstr :: Instr -> Bool
+ GHC.CmmToAsm.LA64.Instr: isNbitEncodeable :: Int -> Integer -> Bool
+ GHC.CmmToAsm.LA64.Instr: isUnsignOp :: Int -> Bool
+ GHC.CmmToAsm.LA64.Instr: jumpDestsOfInstr :: Instr -> [BlockId]
+ GHC.CmmToAsm.LA64.Instr: ldFormat :: Format -> Format
+ GHC.CmmToAsm.LA64.Instr: maxSpillSlots :: NCGConfig -> Int
+ GHC.CmmToAsm.LA64.Instr: mkJumpInstr :: BlockId -> [Instr]
+ GHC.CmmToAsm.LA64.Instr: mkLoadInstr :: NCGConfig -> RegWithFormat -> Int -> Int -> [Instr]
+ GHC.CmmToAsm.LA64.Instr: mkRegRegMoveInstr :: Reg -> Reg -> Instr
+ GHC.CmmToAsm.LA64.Instr: mkSpillInstr :: HasCallStack => NCGConfig -> RegWithFormat -> Int -> Int -> [Instr]
+ GHC.CmmToAsm.LA64.Instr: mkStackAllocInstr :: Platform -> Int -> [Instr]
+ GHC.CmmToAsm.LA64.Instr: mkStackDeallocInstr :: Platform -> Int -> [Instr]
+ GHC.CmmToAsm.LA64.Instr: opReg :: Reg -> Operand
+ GHC.CmmToAsm.LA64.Instr: opRegNo :: RegNo -> Operand
+ GHC.CmmToAsm.LA64.Instr: patchJumpInstr :: Instr -> (BlockId -> BlockId) -> Instr
+ GHC.CmmToAsm.LA64.Instr: patchRegsOfInstr :: Instr -> (Reg -> Reg) -> Instr
+ GHC.CmmToAsm.LA64.Instr: ra :: Operand
+ GHC.CmmToAsm.LA64.Instr: regUsageOfInstr :: Platform -> Instr -> RegUsage
+ GHC.CmmToAsm.LA64.Instr: sp :: Operand
+ GHC.CmmToAsm.LA64.Instr: spillSlotSize :: Int
+ GHC.CmmToAsm.LA64.Instr: spillSlotToOffset :: Int -> Int
+ GHC.CmmToAsm.LA64.Instr: stackAlign :: Int
+ GHC.CmmToAsm.LA64.Instr: stackFrameHeaderSize :: Int
+ GHC.CmmToAsm.LA64.Instr: takeDeltaInstr :: Instr -> Maybe Int
+ GHC.CmmToAsm.LA64.Instr: takeRegRegMoveInstr :: Instr -> Maybe (Reg, Reg)
+ GHC.CmmToAsm.LA64.Instr: tmp :: Operand
+ GHC.CmmToAsm.LA64.Instr: tp :: Operand
+ GHC.CmmToAsm.LA64.Instr: widthFromOpReg :: Operand -> Width
+ GHC.CmmToAsm.LA64.Instr: widthToInt :: Width -> Int
+ GHC.CmmToAsm.LA64.Instr: x0 :: Operand
+ GHC.CmmToAsm.LA64.Instr: x1 :: Operand
+ GHC.CmmToAsm.LA64.Instr: x10 :: Operand
+ GHC.CmmToAsm.LA64.Instr: x11 :: Operand
+ GHC.CmmToAsm.LA64.Instr: x12 :: Operand
+ GHC.CmmToAsm.LA64.Instr: x13 :: Operand
+ GHC.CmmToAsm.LA64.Instr: x14 :: Operand
+ GHC.CmmToAsm.LA64.Instr: x15 :: Operand
+ GHC.CmmToAsm.LA64.Instr: x16 :: Operand
+ GHC.CmmToAsm.LA64.Instr: x17 :: Operand
+ GHC.CmmToAsm.LA64.Instr: x18 :: Operand
+ GHC.CmmToAsm.LA64.Instr: x19 :: Operand
+ GHC.CmmToAsm.LA64.Instr: x2 :: Operand
+ GHC.CmmToAsm.LA64.Instr: x20 :: Operand
+ GHC.CmmToAsm.LA64.Instr: x21 :: Operand
+ GHC.CmmToAsm.LA64.Instr: x22 :: Operand
+ GHC.CmmToAsm.LA64.Instr: x23 :: Operand
+ GHC.CmmToAsm.LA64.Instr: x24 :: Operand
+ GHC.CmmToAsm.LA64.Instr: x25 :: Operand
+ GHC.CmmToAsm.LA64.Instr: x26 :: Operand
+ GHC.CmmToAsm.LA64.Instr: x27 :: Operand
+ GHC.CmmToAsm.LA64.Instr: x28 :: Operand
+ GHC.CmmToAsm.LA64.Instr: x29 :: Operand
+ GHC.CmmToAsm.LA64.Instr: x3 :: Operand
+ GHC.CmmToAsm.LA64.Instr: x30 :: Operand
+ GHC.CmmToAsm.LA64.Instr: x31 :: Operand
+ GHC.CmmToAsm.LA64.Instr: x4 :: Operand
+ GHC.CmmToAsm.LA64.Instr: x5 :: Operand
+ GHC.CmmToAsm.LA64.Instr: x6 :: Operand
+ GHC.CmmToAsm.LA64.Instr: x7 :: Operand
+ GHC.CmmToAsm.LA64.Instr: x8 :: Operand
+ GHC.CmmToAsm.LA64.Instr: x9 :: Operand
+ GHC.CmmToAsm.LA64.Instr: zero :: Operand
+ GHC.CmmToAsm.LA64.Ppr: pprInstr :: IsDoc doc => Platform -> Instr -> doc
+ GHC.CmmToAsm.LA64.Ppr: pprNatCmmDecl :: IsDoc doc => NCGConfig -> NatCmmDecl RawCmmStatics Instr -> doc
+ GHC.CmmToAsm.LA64.RegInfo: DestBlockId :: BlockId -> JumpDest
+ GHC.CmmToAsm.LA64.RegInfo: canShortcut :: Instr -> Maybe JumpDest
+ GHC.CmmToAsm.LA64.RegInfo: getJumpDestBlockId :: JumpDest -> Maybe BlockId
+ GHC.CmmToAsm.LA64.RegInfo: instance GHC.Utils.Outputable.Outputable GHC.CmmToAsm.LA64.RegInfo.JumpDest
+ GHC.CmmToAsm.LA64.RegInfo: newtype JumpDest
+ GHC.CmmToAsm.LA64.RegInfo: shortcutJump :: (BlockId -> Maybe JumpDest) -> Instr -> Instr
+ GHC.CmmToAsm.LA64.RegInfo: shortcutStatics :: (BlockId -> Maybe JumpDest) -> RawCmmStatics -> RawCmmStatics
+ GHC.CmmToAsm.LA64.Regs: AddrReg :: Reg -> AddrMode
+ GHC.CmmToAsm.LA64.Regs: AddrRegImm :: Reg -> Imm -> AddrMode
+ GHC.CmmToAsm.LA64.Regs: AddrRegReg :: Reg -> Reg -> AddrMode
+ GHC.CmmToAsm.LA64.Regs: ImmCLbl :: CLabel -> Imm
+ GHC.CmmToAsm.LA64.Regs: ImmConstantDiff :: Imm -> Imm -> Imm
+ GHC.CmmToAsm.LA64.Regs: ImmConstantSum :: Imm -> Imm -> Imm
+ GHC.CmmToAsm.LA64.Regs: ImmDouble :: Rational -> Imm
+ GHC.CmmToAsm.LA64.Regs: ImmFloat :: Rational -> Imm
+ GHC.CmmToAsm.LA64.Regs: ImmIndex :: CLabel -> Int -> Imm
+ GHC.CmmToAsm.LA64.Regs: ImmInt :: Int -> Imm
+ GHC.CmmToAsm.LA64.Regs: ImmInteger :: Integer -> Imm
+ GHC.CmmToAsm.LA64.Regs: ImmLit :: FastString -> Imm
+ GHC.CmmToAsm.LA64.Regs: allFpArgRegs :: [Reg]
+ GHC.CmmToAsm.LA64.Regs: allGpArgRegs :: [Reg]
+ GHC.CmmToAsm.LA64.Regs: allMachRegNos :: [RegNo]
+ GHC.CmmToAsm.LA64.Regs: allocatableRegs :: Platform -> [RealReg]
+ GHC.CmmToAsm.LA64.Regs: classOfRealReg :: RealReg -> RegClass
+ GHC.CmmToAsm.LA64.Regs: data AddrMode
+ GHC.CmmToAsm.LA64.Regs: data Imm
+ GHC.CmmToAsm.LA64.Regs: fpMachReg :: Reg
+ GHC.CmmToAsm.LA64.Regs: instance GHC.Internal.Classes.Eq GHC.CmmToAsm.LA64.Regs.AddrMode
+ GHC.CmmToAsm.LA64.Regs: instance GHC.Internal.Classes.Eq GHC.CmmToAsm.LA64.Regs.Imm
+ GHC.CmmToAsm.LA64.Regs: instance GHC.Internal.Show.Show GHC.CmmToAsm.LA64.Regs.AddrMode
+ GHC.CmmToAsm.LA64.Regs: instance GHC.Internal.Show.Show GHC.CmmToAsm.LA64.Regs.Imm
+ GHC.CmmToAsm.LA64.Regs: litToImm :: CmmLit -> Imm
+ GHC.CmmToAsm.LA64.Regs: mkVirtualReg :: Unique -> Format -> VirtualReg
+ GHC.CmmToAsm.LA64.Regs: raReg :: Reg
+ GHC.CmmToAsm.LA64.Regs: realRegSqueeze :: RegClass -> RealReg -> Int
+ GHC.CmmToAsm.LA64.Regs: regDotColor :: RealReg -> SDoc
+ GHC.CmmToAsm.LA64.Regs: spMachReg :: Reg
+ GHC.CmmToAsm.LA64.Regs: tmpReg :: Reg
+ GHC.CmmToAsm.LA64.Regs: tpMachReg :: Reg
+ GHC.CmmToAsm.LA64.Regs: virtualRegSqueeze :: RegClass -> VirtualReg -> Int
+ GHC.CmmToAsm.LA64.Regs: zeroReg :: Reg
+ GHC.CmmToAsm.PIC: instance GHC.Internal.Classes.Eq GHC.CmmToAsm.PIC.ReferenceKind
+ GHC.CmmToAsm.PPC.Cond: instance GHC.Internal.Classes.Eq GHC.CmmToAsm.PPC.Cond.Cond
+ GHC.CmmToAsm.RV64.Cond: instance GHC.Internal.Classes.Eq GHC.CmmToAsm.RV64.Cond.Cond
+ GHC.CmmToAsm.RV64.Instr: instance GHC.Internal.Classes.Eq GHC.CmmToAsm.RV64.Instr.Operand
+ GHC.CmmToAsm.RV64.Regs: instance GHC.Internal.Classes.Eq GHC.CmmToAsm.RV64.Regs.AddrMode
+ GHC.CmmToAsm.RV64.Regs: instance GHC.Internal.Classes.Eq GHC.CmmToAsm.RV64.Regs.Imm
+ GHC.CmmToAsm.Reg.Graph.Base: instance GHC.Internal.Classes.Eq GHC.CmmToAsm.Reg.Graph.Base.Reg
+ GHC.CmmToAsm.Reg.Graph.Base: instance GHC.Internal.Classes.Eq GHC.CmmToAsm.Reg.Graph.Base.RegClass
+ GHC.CmmToAsm.Reg.Graph.Base: instance GHC.Internal.Classes.Eq GHC.CmmToAsm.Reg.Graph.Base.RegSub
+ GHC.CmmToAsm.Reg.Graph.Base: instance GHC.Internal.Classes.Ord GHC.CmmToAsm.Reg.Graph.Base.RegSub
+ GHC.CmmToAsm.Reg.Linear.Base: instance GHC.Internal.Classes.Eq GHC.CmmToAsm.Reg.Linear.Base.Loc
+ GHC.CmmToAsm.Reg.Linear.Base: instance GHC.Internal.Classes.Eq GHC.CmmToAsm.Reg.Linear.Base.ReadingOrWriting
+ GHC.CmmToAsm.Reg.Linear.Base: instance GHC.Internal.Classes.Eq GHC.CmmToAsm.Reg.Linear.Base.RealRegUsage
+ GHC.CmmToAsm.Reg.Linear.Base: instance GHC.Internal.Classes.Ord GHC.CmmToAsm.Reg.Linear.Base.Loc
+ GHC.CmmToAsm.Reg.Linear.Base: instance GHC.Internal.Classes.Ord GHC.CmmToAsm.Reg.Linear.Base.ReadingOrWriting
+ GHC.CmmToAsm.Reg.Linear.Base: instance GHC.Internal.Classes.Ord GHC.CmmToAsm.Reg.Linear.Base.RealRegUsage
+ GHC.CmmToAsm.Reg.Linear.Base: instance GHC.Internal.Show.Show GHC.CmmToAsm.Reg.Linear.Base.Loc
+ GHC.CmmToAsm.Reg.Linear.FreeRegs: instance GHC.CmmToAsm.Reg.Linear.FreeRegs.FR GHC.CmmToAsm.Reg.Linear.LA64.FreeRegs
+ GHC.CmmToAsm.Reg.Linear.LA64: FreeRegs :: Word32 -> Word32 -> FreeRegs
+ GHC.CmmToAsm.Reg.Linear.LA64: allocateReg :: HasCallStack => RealReg -> FreeRegs -> FreeRegs
+ GHC.CmmToAsm.Reg.Linear.LA64: data FreeRegs
+ GHC.CmmToAsm.Reg.Linear.LA64: getFreeRegs :: RegClass -> FreeRegs -> [RealReg]
+ GHC.CmmToAsm.Reg.Linear.LA64: initFreeRegs :: Platform -> FreeRegs
+ GHC.CmmToAsm.Reg.Linear.LA64: instance GHC.Internal.Show.Show GHC.CmmToAsm.Reg.Linear.LA64.FreeRegs
+ GHC.CmmToAsm.Reg.Linear.LA64: instance GHC.Utils.Outputable.Outputable GHC.CmmToAsm.Reg.Linear.LA64.FreeRegs
+ GHC.CmmToAsm.Reg.Linear.LA64: noFreeRegs :: FreeRegs
+ GHC.CmmToAsm.Reg.Linear.LA64: releaseReg :: HasCallStack => RealReg -> FreeRegs -> FreeRegs
+ GHC.CmmToAsm.Reg.Linear.LA64: showBits :: Word32 -> String
+ GHC.CmmToAsm.Reg.Target: mapRegFormatSet :: HasDebugCallStack => (Reg -> Reg) -> UniqSet RegWithFormat -> UniqSet RegWithFormat
+ GHC.CmmToAsm.Wasm.Types: instance GHC.Internal.Classes.Eq GHC.CmmToAsm.Wasm.Types.SomeWasmType
+ GHC.CmmToAsm.Wasm.Types: instance GHC.Internal.Classes.Eq GHC.CmmToAsm.Wasm.Types.SymKind
+ GHC.CmmToAsm.Wasm.Types: instance GHC.Internal.Classes.Eq GHC.CmmToAsm.Wasm.Types.SymName
+ GHC.CmmToAsm.Wasm.Types: instance GHC.Internal.Classes.Ord GHC.CmmToAsm.Wasm.Types.SymName
+ GHC.CmmToAsm.X86.CodeGen: instance GHC.Internal.Classes.Eq GHC.CmmToAsm.X86.CodeGen.Padding
+ GHC.CmmToAsm.X86.CodeGen: instance GHC.Internal.Classes.Eq GHC.CmmToAsm.X86.CodeGen.StackRef
+ GHC.CmmToAsm.X86.CodeGen: instance GHC.Internal.Classes.Ord GHC.CmmToAsm.X86.CodeGen.Padding
+ GHC.CmmToAsm.X86.CodeGen: instance GHC.Internal.Classes.Ord GHC.CmmToAsm.X86.CodeGen.StackRef
+ GHC.CmmToAsm.X86.Cond: instance GHC.Internal.Classes.Eq GHC.CmmToAsm.X86.Cond.Cond
+ GHC.CmmToAsm.X86.Instr: BLEND :: Format -> Imm -> Operand -> Reg -> Instr
+ GHC.CmmToAsm.X86.Instr: MOVLHPS :: Format -> Reg -> Reg -> Instr
+ GHC.CmmToAsm.X86.Instr: PACKUSWB :: Format -> Operand -> Reg -> Instr
+ GHC.CmmToAsm.X86.Instr: PADD :: Format -> Operand -> Reg -> Instr
+ GHC.CmmToAsm.X86.Instr: PALIGNR :: Format -> Imm -> Operand -> Reg -> Instr
+ GHC.CmmToAsm.X86.Instr: PAND :: Format -> Operand -> Reg -> Instr
+ GHC.CmmToAsm.X86.Instr: PANDN :: Format -> Operand -> Reg -> Instr
+ GHC.CmmToAsm.X86.Instr: PBLENDW :: Format -> Imm -> Operand -> Reg -> Instr
+ GHC.CmmToAsm.X86.Instr: PCMPGT :: Format -> Operand -> Reg -> Instr
+ GHC.CmmToAsm.X86.Instr: PEXTR :: Format -> Format -> Imm -> Reg -> Operand -> Instr
+ GHC.CmmToAsm.X86.Instr: PINSR :: Format -> Format -> Imm -> Operand -> Reg -> Instr
+ GHC.CmmToAsm.X86.Instr: PMULL :: Format -> Operand -> Reg -> Instr
+ GHC.CmmToAsm.X86.Instr: PMULUDQ :: Format -> Operand -> Reg -> Instr
+ GHC.CmmToAsm.X86.Instr: POR :: Format -> Operand -> Reg -> Instr
+ GHC.CmmToAsm.X86.Instr: PSHUFB :: Format -> Operand -> Reg -> Instr
+ GHC.CmmToAsm.X86.Instr: PSHUFHW :: Format -> Imm -> Operand -> Reg -> Instr
+ GHC.CmmToAsm.X86.Instr: PSHUFLW :: Format -> Imm -> Operand -> Reg -> Instr
+ GHC.CmmToAsm.X86.Instr: PSLL :: Format -> Operand -> Reg -> Instr
+ GHC.CmmToAsm.X86.Instr: PSRL :: Format -> Operand -> Reg -> Instr
+ GHC.CmmToAsm.X86.Instr: PSUB :: Format -> Operand -> Reg -> Instr
+ GHC.CmmToAsm.X86.Instr: PUNPCKHBW :: Format -> Operand -> Reg -> Instr
+ GHC.CmmToAsm.X86.Instr: PUNPCKHDQ :: Format -> Operand -> Reg -> Instr
+ GHC.CmmToAsm.X86.Instr: PUNPCKHQDQ :: Format -> Operand -> Reg -> Instr
+ GHC.CmmToAsm.X86.Instr: PUNPCKHWD :: Format -> Operand -> Reg -> Instr
+ GHC.CmmToAsm.X86.Instr: PUNPCKLBW :: Format -> Operand -> Reg -> Instr
+ GHC.CmmToAsm.X86.Instr: PUNPCKLDQ :: Format -> Operand -> Reg -> Instr
+ GHC.CmmToAsm.X86.Instr: PUNPCKLWD :: Format -> Operand -> Reg -> Instr
+ GHC.CmmToAsm.X86.Instr: UNPCKH :: Format -> Operand -> Reg -> Instr
+ GHC.CmmToAsm.X86.Instr: VBLEND :: Format -> Imm -> Operand -> Reg -> Reg -> Instr
+ GHC.CmmToAsm.X86.Instr: VINSERTPS :: Format -> Imm -> Operand -> Reg -> Reg -> Instr
+ GHC.CmmToAsm.X86.Instr: VMOVHLPS :: Format -> Reg -> Reg -> Reg -> Instr
+ GHC.CmmToAsm.X86.Instr: VMOVLHPS :: Format -> Reg -> Reg -> Reg -> Instr
+ GHC.CmmToAsm.X86.Instr: VMOV_MERGE :: Format -> Reg -> Reg -> Reg -> Instr
+ GHC.CmmToAsm.X86.Instr: VPBROADCAST :: Format -> Format -> Operand -> Reg -> Instr
+ GHC.CmmToAsm.X86.Instr: VUNPCKH :: Format -> Operand -> Reg -> Reg -> Instr
+ GHC.CmmToAsm.X86.Instr: VUNPCKL :: Format -> Operand -> Reg -> Reg -> Instr
+ GHC.CmmToAsm.X86.Instr: instance GHC.Internal.Classes.Eq GHC.CmmToAsm.X86.Instr.MinMaxType
+ GHC.CmmToAsm.X86.Instr: instance GHC.Internal.Classes.Eq GHC.CmmToAsm.X86.Instr.MinOrMax
+ GHC.CmmToC: instance GHC.Internal.Classes.Eq GHC.CmmToC.Fixity
+ GHC.CmmToLlvm.CodeGen: instance GHC.Internal.Classes.Eq GHC.CmmToLlvm.CodeGen.Signage
+ GHC.CmmToLlvm.Version.Type: instance GHC.Internal.Classes.Eq GHC.CmmToLlvm.Version.Type.LlvmVersion
+ GHC.CmmToLlvm.Version.Type: instance GHC.Internal.Classes.Ord GHC.CmmToLlvm.Version.Type.LlvmVersion
+ GHC.Core: collectValArgs :: Expr b -> (Expr b, [Arg b])
+ GHC.Core: instance Control.DeepSeq.NFData GHC.Core.IsOrphan
+ GHC.Core: instance GHC.Internal.Classes.Eq GHC.Core.AltCon
+ GHC.Core: instance GHC.Internal.Classes.Eq GHC.Core.UnfoldingCache
+ GHC.Core: instance GHC.Internal.Classes.Eq GHC.Core.UnfoldingGuidance
+ GHC.Core: instance GHC.Internal.Classes.Ord GHC.Core.AltCon
+ GHC.Core: rhssOfBinds :: [Bind b] -> [Expr b]
+ GHC.Core: type InTyCoVar = TyCoVar
+ GHC.Core: type OutTyCoVar = TyCoVar
+ GHC.Core.Class: instance GHC.Internal.Classes.Eq GHC.Core.Class.Class
+ GHC.Core.Coercion: hasCoercionHole :: Type -> Bool
+ GHC.Core.Coercion: mkForAllVisCos :: HasDebugCallStack => [ForAllTyBinder] -> Coercion -> Coercion
+ GHC.Core.Coercion: updateLCSubst :: LiftingContext -> (Subst -> (Subst, a)) -> (LiftingContext, a)
+ GHC.Core.Coercion.Axiom: instance Control.DeepSeq.NFData Language.Haskell.Syntax.Basic.Role
+ GHC.Core.Coercion.Axiom: instance GHC.Internal.Classes.Eq (GHC.Core.Coercion.Axiom.CoAxiom br)
+ GHC.Core.Coercion.Axiom: instance GHC.Internal.Classes.Eq GHC.Core.Coercion.Axiom.CoAxiomRule
+ GHC.Core.ConLike: conLikeVisArity :: ConLike -> VisArity
+ GHC.Core.ConLike: instance GHC.Internal.Classes.Eq GHC.Core.ConLike.ConLike
+ GHC.Core.DataCon: dataConUserTyVarBindersNeedWrapper :: DataCon -> Bool
+ GHC.Core.DataCon: dataConVisArity :: DataCon -> VisArity
+ GHC.Core.DataCon: instance Control.DeepSeq.NFData Language.Haskell.Syntax.Basic.SrcStrictness
+ GHC.Core.DataCon: instance Control.DeepSeq.NFData Language.Haskell.Syntax.Basic.SrcUnpackedness
+ GHC.Core.DataCon: instance GHC.Internal.Classes.Eq GHC.Core.DataCon.DataCon
+ GHC.Core.DataCon: instance GHC.Internal.Classes.Eq GHC.Core.DataCon.StrictnessMark
+ GHC.Core.DataCon: instance GHC.Internal.Data.Data.Data GHC.Core.DataCon.HsSrcBang
+ GHC.Core.DataCon: isLazyDataConRep :: DataCon -> Bool
+ GHC.Core.DataCon: isUnaryClassDataCon :: DataCon -> Bool
+ GHC.Core.DataCon: isUnpacked :: HsImplBang -> Bool
+ GHC.Core.FVs: addBndrFV :: CoreBndr -> FV -> FV
+ GHC.Core.FVs: addBndrsFV :: [CoreBndr] -> FV -> FV
+ GHC.Core.FVs: exprLocalFVs :: CoreExpr -> FV
+ GHC.Core.Lint: instance GHC.Internal.Classes.Eq GHC.Core.Lint.StaticPtrCheck
+ GHC.Core.Make: mkCoreConWrapApps :: DataCon -> [CoreExpr] -> CoreExpr
+ GHC.Core.Make: mkCoreTyLams :: [TyVarBinder] -> CoreExpr -> CoreExpr
+ GHC.Core.Map.Expr: instance GHC.Internal.Classes.Eq (GHC.Core.Map.Type.DeBruijn GHC.Core.CoreAlt)
+ GHC.Core.Map.Expr: instance GHC.Internal.Classes.Eq (GHC.Core.Map.Type.DeBruijn GHC.Core.CoreExpr)
+ GHC.Core.Map.Expr: mapMaybeTM :: TrieMap m => (a -> Maybe b) -> m a -> m b
+ GHC.Core.Map.Type: instance GHC.Internal.Classes.Eq (GHC.Core.Map.Type.DeBruijn GHC.Core.TyCo.Rep.Coercion)
+ GHC.Core.Map.Type: instance GHC.Internal.Classes.Eq (GHC.Core.Map.Type.DeBruijn GHC.Core.TyCo.Rep.Type)
+ GHC.Core.Map.Type: instance GHC.Internal.Classes.Eq (GHC.Core.Map.Type.DeBruijn GHC.Types.Var.Var)
+ GHC.Core.Map.Type: instance GHC.Internal.Classes.Eq (GHC.Core.Map.Type.DeBruijn a) => GHC.Internal.Classes.Eq (GHC.Core.Map.Type.DeBruijn (GHC.Internal.Maybe.Maybe a))
+ GHC.Core.Map.Type: instance GHC.Internal.Classes.Eq (GHC.Core.Map.Type.DeBruijn a) => GHC.Internal.Classes.Eq (GHC.Core.Map.Type.DeBruijn [a])
+ GHC.Core.Map.Type: mapMaybeTM :: TrieMap m => (a -> Maybe b) -> m a -> m b
+ GHC.Core.Multiplicity: instance GHC.Internal.Classes.Eq GHC.Core.Multiplicity.IsSubmult
+ GHC.Core.Opt.Arity: instance GHC.Internal.Classes.Eq GHC.Core.Opt.Arity.ArityType
+ GHC.Core.Opt.Arity: instance GHC.Internal.Classes.Eq GHC.Core.Opt.Arity.Cost
+ GHC.Core.Opt.CallerCC.Types: instance Control.DeepSeq.NFData GHC.Core.Opt.CallerCC.Types.CallerCcFilter
+ GHC.Core.Opt.CallerCC.Types: instance Control.DeepSeq.NFData GHC.Core.Opt.CallerCC.Types.NamePattern
+ GHC.Core.Opt.SetLevels: instance GHC.Internal.Classes.Eq GHC.Core.Opt.SetLevels.Level
+ GHC.Core.Opt.Simplify.Env: checkSimplEnvIS :: SimplEnvIS -> Bool
+ GHC.Core.Opt.Simplify.Env: getFullSubst :: InScopeSet -> SimplEnv -> Subst
+ GHC.Core.Opt.Simplify.Env: getTCvSubst :: SimplEnv -> Subst
+ GHC.Core.Opt.Simplify.Env: pprBadSimplEnvIS :: SimplEnvIS -> SDoc
+ GHC.Core.Opt.Simplify.Env: type SimplEnvIS = SimplEnv
+ GHC.Core.Opt.Simplify.Utils: [ai_rules] :: ArgInfo -> [CoreRule]
+ GHC.Core.Opt.Simplify.Utils: argSpecArg :: ArgSpec -> OutExpr
+ GHC.Core.Opt.Simplify.Utils: contOutArgs :: SimplEnv -> SimplCont -> [OutExpr]
+ GHC.Core.Opt.Simplify.Utils: dropContArgs :: FullArgCount -> SimplCont -> SimplCont
+ GHC.Core.Opt.Stats: instance GHC.Internal.Classes.Eq GHC.Core.Opt.Stats.Tick
+ GHC.Core.Opt.Stats: instance GHC.Internal.Classes.Ord GHC.Core.Opt.Stats.Tick
+ GHC.Core.Opt.WorkWrap.Utils: canUnboxTyCon :: HasDebugCallStack => TyCon -> Maybe [DataCon]
+ GHC.Core.Opt.WorkWrap.Utils: canUnboxType :: HasDebugCallStack => Type -> Maybe [DataCon]
+ GHC.Core.Opt.WorkWrap.Utils: instance GHC.Internal.Classes.Eq GHC.Core.Opt.WorkWrap.Utils.IsRecDataConResult
+ GHC.Core.PatSyn: instance GHC.Internal.Classes.Eq GHC.Core.PatSyn.PatSyn
+ GHC.Core.PatSyn: patSynVisArity :: PatSyn -> VisArity
+ GHC.Core.Predicate: TyFamLHS :: TyCon -> [Type] -> CanEqLHS
+ GHC.Core.Predicate: TyVarLHS :: TyVar -> CanEqLHS
+ GHC.Core.Predicate: canEqLHSKind :: CanEqLHS -> Kind
+ GHC.Core.Predicate: canEqLHSType :: CanEqLHS -> Type
+ GHC.Core.Predicate: canEqLHS_maybe :: Type -> Maybe CanEqLHS
+ GHC.Core.Predicate: canTyFamEqLHS_maybe :: Type -> Maybe CanEqLHS
+ GHC.Core.Predicate: couldBeIPLike :: Type -> Bool
+ GHC.Core.Predicate: data CanEqLHS
+ GHC.Core.Predicate: decomposeIPPred :: Type -> (Id, [Type])
+ GHC.Core.Predicate: eqCanEqLHS :: CanEqLHS -> CanEqLHS -> Bool
+ GHC.Core.Predicate: instance GHC.Internal.Classes.Eq GHC.Core.Predicate.EqRel
+ GHC.Core.Predicate: instance GHC.Internal.Classes.Ord GHC.Core.Predicate.EqRel
+ GHC.Core.Predicate: instance GHC.Utils.Outputable.Outputable GHC.Core.Predicate.CanEqLHS
+ GHC.Core.Predicate: isEqClassPred :: PredType -> Bool
+ GHC.Core.Predicate: isEvId :: Var -> Bool
+ GHC.Core.Predicate: isReprEqPred :: PredType -> Bool
+ GHC.Core.Predicate: isSimplePredTy :: HasDebugCallStack => Type -> Bool
+ GHC.Core.Predicate: isUnaryClass :: Class -> Bool
+ GHC.Core.Predicate: mightMentionIP :: (Type -> Bool) -> (Type -> Bool) -> Class -> [Type] -> Bool
+ GHC.Core.Predicate: mkEqPred :: EqRel -> Type -> Type -> PredType
+ GHC.Core.Predicate: mkEqPredRole :: Role -> Type -> Type -> PredType
+ GHC.Core.Predicate: mkNomEqPred :: Type -> Type -> Type
+ GHC.Core.Predicate: mkReprEqPred :: Type -> Type -> Type
+ GHC.Core.Predicate: pprPredType :: PredType -> SDoc
+ GHC.Core.Predicate: scopedSort :: [Var] -> [Var]
+ GHC.Core.Predicate: tyCoVarsOfTypeWellScoped :: Type -> [TyVar]
+ GHC.Core.Predicate: tyCoVarsOfTypesWellScoped :: [Type] -> [TyVar]
+ GHC.Core.Rules: ruleIsOrphan :: CoreRule -> Bool
+ GHC.Core.Rules: ruleLhsIsMoreSpecific :: InScopeSet -> [Var] -> [CoreExpr] -> CoreRule -> Bool
+ GHC.Core.SimpleOpt: [so_inline] :: SimpleOpts -> Bool
+ GHC.Core.SimpleOpt: simpleOptExprNoInline :: HasDebugCallStack => SimpleOpts -> CoreExpr -> CoreExpr
+ GHC.Core.Subst: cloneBndrsM :: MonadUnique m => Subst -> [Var] -> m (Subst, [Var])
+ GHC.Core.Subst: cloneRecIdBndrsM :: MonadUnique m => Subst -> [Id] -> m (Subst, [Id])
+ GHC.Core.Subst: substInScopeSet :: Subst -> InScopeSet
+ GHC.Core.TyCo.Compare: instance GHC.Internal.Classes.Eq GHC.Core.TyCo.Compare.TypeOrdering
+ GHC.Core.TyCo.Compare: instance GHC.Internal.Classes.Ord GHC.Core.TyCo.Compare.TypeOrdering
+ GHC.Core.TyCo.Compare: tcEqTyConAppArgs :: [Type] -> [Type] -> Bool
+ GHC.Core.TyCo.Rep: instance Control.DeepSeq.NFData GHC.Core.TyCo.Rep.FunSel
+ GHC.Core.TyCo.Rep: instance GHC.Internal.Classes.Eq GHC.Core.TyCo.Rep.CoSel
+ GHC.Core.TyCo.Rep: instance GHC.Internal.Classes.Eq GHC.Core.TyCo.Rep.FunSel
+ GHC.Core.TyCo.Rep: instance GHC.Internal.Classes.Eq GHC.Core.TyCo.Rep.TyLit
+ GHC.Core.TyCo.Rep: instance GHC.Internal.Classes.Eq GHC.Core.TyCo.Rep.UnivCoProvenance
+ GHC.Core.TyCo.Rep: instance GHC.Internal.Classes.Ord GHC.Core.TyCo.Rep.CoSel
+ GHC.Core.TyCo.Rep: instance GHC.Internal.Classes.Ord GHC.Core.TyCo.Rep.FunSel
+ GHC.Core.TyCo.Rep: instance GHC.Internal.Classes.Ord GHC.Core.TyCo.Rep.UnivCoProvenance
+ GHC.Core.TyCo.Subst: mkSubst :: InScopeSet -> IdSubstEnv -> TvSubstEnv -> CvSubstEnv -> Subst
+ GHC.Core.TyCo.Subst: substInScopeSet :: Subst -> InScopeSet
+ GHC.Core.TyCon: UnaryClassTyCon :: DataCon -> AlgTyConRhs
+ GHC.Core.TyCon: instance Control.DeepSeq.NFData GHC.Core.TyCon.Injectivity
+ GHC.Core.TyCon: instance Control.DeepSeq.NFData GHC.Core.TyCon.TyConBndrVis
+ GHC.Core.TyCon: instance GHC.Internal.Classes.Eq GHC.Core.TyCon.Injectivity
+ GHC.Core.TyCon: instance GHC.Internal.Classes.Eq GHC.Core.TyCon.PrimElemRep
+ GHC.Core.TyCon: instance GHC.Internal.Classes.Eq GHC.Core.TyCon.PrimOrVoidRep
+ GHC.Core.TyCon: instance GHC.Internal.Classes.Eq GHC.Core.TyCon.PrimRep
+ GHC.Core.TyCon: instance GHC.Internal.Classes.Eq GHC.Core.TyCon.TyCon
+ GHC.Core.TyCon: instance GHC.Internal.Classes.Ord GHC.Core.TyCon.PrimElemRep
+ GHC.Core.TyCon: instance GHC.Internal.Classes.Ord GHC.Core.TyCon.PrimOrVoidRep
+ GHC.Core.TyCon: instance GHC.Internal.Classes.Ord GHC.Core.TyCon.PrimRep
+ GHC.Core.TyCon: isBoxedDataTyCon :: TyCon -> Bool
+ GHC.Core.TyCon: isInferredTyConBinder :: VarBndr var TyConBndrVis -> Bool
+ GHC.Core.TyCon: isInvisSpecTyConBinder :: VarBndr tv TyConBndrVis -> Bool
+ GHC.Core.TyCon: isUnaryClassTyCon :: TyCon -> Bool
+ GHC.Core.TyCon: isUnaryClassTyCon_maybe :: TyCon -> Maybe (Class, DataCon)
+ GHC.Core.Type: collectPiTyBinders :: Type -> [PiTyBinder]
+ GHC.Core.Type: invisibleBndrCount :: Type -> Int
+ GHC.Core.Type: isDataFamilyApp :: Type -> Bool
+ GHC.Core.Type: isSatTyFamApp :: Type -> Maybe (TyCon, [Type])
+ GHC.Core.Type: liftedTypeOrConstraintKind :: TypeOrConstraint -> Kind
+ GHC.Core.Type: splitVisibleFunTy_maybe :: Type -> Maybe (Type, Type)
+ GHC.Core.Type: substInScopeSet :: Subst -> InScopeSet
+ GHC.Core.Unify: DontBindMe :: BindFlag
+ GHC.Core.Unify: MARCast :: MaybeApartReason
+ GHC.Core.Unify: alwaysBindFam :: BindFamFun
+ GHC.Core.Unify: alwaysBindTv :: BindTvFun
+ GHC.Core.Unify: dontCareBindFam :: HasCallStack => BindFamFun
+ GHC.Core.Unify: instance GHC.Internal.Classes.Eq GHC.Core.Unify.BindFlag
+ GHC.Core.Unify: matchBindTv :: TyCoVarSet -> BindTvFun
+ GHC.Core.Unify: tcUnifyDebugger :: Type -> Type -> Maybe Subst
+ GHC.Core.Unify: tcUnifyFunDeps :: TyCoVarSet -> [Type] -> [Type] -> Maybe Subst
+ GHC.Core.Unify: tcUnifyTyForInjectivity :: AmIUnifying -> InScopeSet -> Type -> Type -> Maybe Subst
+ GHC.Core.Unify: type BindFamFun = TyCon -> [Type] -> Type -> BindFlag
+ GHC.Core.Unify: type BindTvFun = TyCoVar -> Type -> BindFlag
+ GHC.Core.Utils: exprIsUnaryClassFun :: CoreExpr -> Bool
+ GHC.Core.Utils: isUnaryClassId :: Id -> Bool
+ GHC.CoreToIface: toIfaceBooleanFormula :: BooleanFormula GhcRn -> IfaceBooleanFormula
+ GHC.CoreToStg: instance GHC.Internal.Classes.Eq GHC.CoreToStg.HowBound
+ GHC.CoreToStg: instance GHC.Internal.Classes.Eq GHC.CoreToStg.LetInfo
+ GHC.CoreToStg.AddImplicitBinds: addImplicitBinds :: CorePrepPgmConfig -> ModLocation -> [TyCon] -> CoreProgram -> IO CoreProgram
+ GHC.CoreToStg.Prep: instance GHC.Internal.Classes.Eq GHC.CoreToStg.Prep.BindInfo
+ GHC.CoreToStg.Prep: instance GHC.Internal.Classes.Eq GHC.CoreToStg.Prep.FloatInfo
+ GHC.CoreToStg.Prep: instance GHC.Utils.Outputable.Outputable GHC.CoreToStg.Prep.FloatDecision
+ GHC.Data.Bag: foldBag_flip :: (a -> b -> b) -> Bag a -> b -> b
+ GHC.Data.Bool: instance GHC.Internal.Classes.Eq GHC.Data.Bool.OverridingBool
+ GHC.Data.Bool: instance GHC.Internal.Classes.Ord GHC.Data.Bool.OverridingBool
+ GHC.Data.BooleanFormula: bfMap :: forall (p :: Pass) (p' :: Pass). (LIdP (GhcPass p) -> LIdP (GhcPass p')) -> BooleanFormula (GhcPass p) -> BooleanFormula (GhcPass p')
+ GHC.Data.BooleanFormula: bfTraverse :: forall f (p :: Pass) (p' :: Pass). Applicative f => (LIdP (GhcPass p) -> f (LIdP (GhcPass p'))) -> BooleanFormula (GhcPass p) -> f (BooleanFormula (GhcPass p'))
+ GHC.Data.BooleanFormula: instance GHC.Hs.Extension.OutputableBndrId p => GHC.Utils.Outputable.Outputable (Language.Haskell.Syntax.BooleanFormula.BooleanFormula (GHC.Hs.Extension.GhcPass p))
+ GHC.Data.BooleanFormula: pprBooleanFormulaNormal :: forall (p :: Pass). OutputableBndrId p => BooleanFormula (GhcPass p) -> SDoc
+ GHC.Data.FastString: instance GHC.Internal.Classes.Eq GHC.Data.FastString.FastString
+ GHC.Data.FastString: instance GHC.Internal.Classes.Eq GHC.Data.FastString.LexicalFastString
+ GHC.Data.FastString: instance GHC.Internal.Classes.Eq GHC.Data.FastString.NonDetFastString
+ GHC.Data.FastString: instance GHC.Internal.Classes.Ord GHC.Data.FastString.LexicalFastString
+ GHC.Data.FastString: instance GHC.Internal.Classes.Ord GHC.Data.FastString.NonDetFastString
+ GHC.Data.FlatBag: fromSmallArray :: SmallArray a -> FlatBag a
+ GHC.Data.Graph.Directed: emptyGraph :: Graph a
+ GHC.Data.Graph.Directed: instance GHC.Internal.Classes.Eq GHC.Data.Graph.Directed.EdgeType
+ GHC.Data.Graph.Directed: instance GHC.Internal.Classes.Eq GHC.Data.Graph.Directed.Time
+ GHC.Data.Graph.Directed: instance GHC.Internal.Classes.Ord GHC.Data.Graph.Directed.EdgeType
+ GHC.Data.Graph.Directed: instance GHC.Internal.Classes.Ord GHC.Data.Graph.Directed.Time
+ GHC.Data.Graph.Directed.Internal: Edge :: node -> node -> Edge node
+ GHC.Data.Graph.Directed.Internal: Graph :: IntGraph -> (Vertex -> node) -> (node -> Maybe Vertex) -> Graph node
+ GHC.Data.Graph.Directed.Internal: [gr_int_graph] :: Graph node -> IntGraph
+ GHC.Data.Graph.Directed.Internal: [gr_node_to_vertex] :: Graph node -> node -> Maybe Vertex
+ GHC.Data.Graph.Directed.Internal: [gr_vertex_to_node] :: Graph node -> Vertex -> node
+ GHC.Data.Graph.Directed.Internal: data Edge node
+ GHC.Data.Graph.Directed.Internal: data Graph node
+ GHC.Data.Graph.Directed.Internal: edgesG :: Graph node -> [Edge node]
+ GHC.Data.Graph.Directed.Internal: instance GHC.Utils.Outputable.Outputable node => GHC.Utils.Outputable.Outputable (GHC.Data.Graph.Directed.Internal.Edge node)
+ GHC.Data.Graph.Directed.Internal: instance GHC.Utils.Outputable.Outputable node => GHC.Utils.Outputable.Outputable (GHC.Data.Graph.Directed.Internal.Graph node)
+ GHC.Data.Graph.Directed.Internal: preorderF :: Forest a -> [a]
+ GHC.Data.Graph.Directed.Internal: reachable :: IntGraph -> [Vertex] -> [Vertex]
+ GHC.Data.Graph.Directed.Internal: scc :: IntGraph -> [SCC Vertex]
+ GHC.Data.Graph.Directed.Internal: type IntGraph = Graph
+ GHC.Data.Graph.Directed.Internal: verticesG :: Graph node -> [node]
+ GHC.Data.Graph.Directed.Reachability: allReachable :: ReachabilityIndex node -> node -> [node]
+ GHC.Data.Graph.Directed.Reachability: allReachableMany :: ReachabilityIndex node -> [node] -> [node]
+ GHC.Data.Graph.Directed.Reachability: cyclicGraphReachability :: Graph node -> ReachabilityIndex node
+ GHC.Data.Graph.Directed.Reachability: data ReachabilityIndex node
+ GHC.Data.Graph.Directed.Reachability: graphReachability :: Graph node -> ReachabilityIndex node
+ GHC.Data.Graph.Directed.Reachability: isReachable :: ReachabilityIndex node -> node -> node -> Bool
+ GHC.Data.Graph.Directed.Reachability: isReachableMany :: ReachabilityIndex node -> [node] -> node -> Bool
+ GHC.Data.Graph.Directed.Reachability: reachabilityIndexMembers :: ReachabilityIndex node -> [node]
+ GHC.Data.Graph.Inductive.Graph: instance (GHC.Data.Graph.Inductive.Graph.Graph gr, GHC.Internal.Classes.Ord a, GHC.Internal.Classes.Ord b) => GHC.Internal.Classes.Eq (GHC.Data.Graph.Inductive.Graph.OrdGr gr a b)
+ GHC.Data.Graph.Inductive.Graph: instance (GHC.Data.Graph.Inductive.Graph.Graph gr, GHC.Internal.Classes.Ord a, GHC.Internal.Classes.Ord b) => GHC.Internal.Classes.Ord (GHC.Data.Graph.Inductive.Graph.OrdGr gr a b)
+ GHC.Data.Graph.Inductive.Graph: instance GHC.Internal.Classes.Eq a => GHC.Internal.Classes.Eq (GHC.Data.Graph.Inductive.Graph.LPath a)
+ GHC.Data.Graph.Inductive.Graph: instance GHC.Internal.Classes.Eq b => GHC.Internal.Classes.Eq (GHC.Data.Graph.Inductive.Graph.GroupEdges b)
+ GHC.Data.Graph.Inductive.Graph: instance GHC.Internal.Classes.Ord a => GHC.Internal.Classes.Ord (GHC.Data.Graph.Inductive.Graph.LPath a)
+ GHC.Data.Graph.Inductive.PatriciaTree: instance (GHC.Internal.Classes.Eq a, GHC.Internal.Classes.Ord b) => GHC.Internal.Classes.Eq (GHC.Data.Graph.Inductive.PatriciaTree.Gr a b)
+ GHC.Data.Graph.Inductive.PatriciaTree: instance GHC.Internal.Classes.Eq a => GHC.Internal.Classes.Eq (GHC.Data.Graph.Inductive.PatriciaTree.FromListCounting a)
+ GHC.Data.Graph.UnVar: instance GHC.Internal.Classes.Eq GHC.Data.Graph.UnVar.UnVarSet
+ GHC.Data.IOEnv: updEnvIO :: (env -> IO env') -> IOEnv env' a -> IOEnv env a
+ GHC.Data.List: mapAndUnzip :: (a -> (b, c)) -> [a] -> ([b], [c])
+ GHC.Data.List: mapAndUnzip3 :: (a -> (b, c, d)) -> [a] -> ([b], [c], [d])
+ GHC.Data.List: mapAndUnzip4 :: (a -> (b, c, d, e)) -> [a] -> ([b], [c], [d], [e])
+ GHC.Data.List.Infinite: enumFrom :: Enum a => a -> Infinite a
+ GHC.Data.List.Infinite: instance GHC.Internal.Base.Monad GHC.Data.List.Infinite.Infinite
+ GHC.Data.List.NonEmpty: (!!) :: HasCallStack => NonEmpty a -> Int -> a
+ GHC.Data.List.NonEmpty: (:|) :: a -> [a] -> NonEmpty a
+ GHC.Data.List.NonEmpty: (<|) :: a -> NonEmpty a -> NonEmpty a
+ GHC.Data.List.NonEmpty: append :: NonEmpty a -> NonEmpty a -> NonEmpty a
+ GHC.Data.List.NonEmpty: appendList :: NonEmpty a -> [a] -> NonEmpty a
+ GHC.Data.List.NonEmpty: break :: (a -> Bool) -> NonEmpty a -> ([a], [a])
+ GHC.Data.List.NonEmpty: compareLength :: NonEmpty a -> Int -> Ordering
+ GHC.Data.List.NonEmpty: cons :: a -> NonEmpty a -> NonEmpty a
+ GHC.Data.List.NonEmpty: cycle :: NonEmpty a -> NonEmpty a
+ GHC.Data.List.NonEmpty: data NonEmpty a
+ GHC.Data.List.NonEmpty: drop :: Int -> NonEmpty a -> [a]
+ GHC.Data.List.NonEmpty: dropWhile :: (a -> Bool) -> NonEmpty a -> [a]
+ GHC.Data.List.NonEmpty: filter :: (a -> Bool) -> NonEmpty a -> [a]
+ GHC.Data.List.NonEmpty: fromList :: HasCallStack => [a] -> NonEmpty a
+ GHC.Data.List.NonEmpty: group :: (Foldable f, Eq a) => f a -> [NonEmpty a]
+ GHC.Data.List.NonEmpty: group1 :: Eq a => NonEmpty a -> NonEmpty (NonEmpty a)
+ GHC.Data.List.NonEmpty: groupAllWith :: Ord b => (a -> b) -> [a] -> [NonEmpty a]
+ GHC.Data.List.NonEmpty: groupAllWith1 :: Ord b => (a -> b) -> NonEmpty a -> NonEmpty (NonEmpty a)
+ GHC.Data.List.NonEmpty: groupBy :: Foldable f => (a -> a -> Bool) -> f a -> [NonEmpty a]
+ GHC.Data.List.NonEmpty: groupBy1 :: (a -> a -> Bool) -> NonEmpty a -> NonEmpty (NonEmpty a)
+ GHC.Data.List.NonEmpty: groupWith :: (Foldable f, Eq b) => (a -> b) -> f a -> [NonEmpty a]
+ GHC.Data.List.NonEmpty: groupWith1 :: Eq b => (a -> b) -> NonEmpty a -> NonEmpty (NonEmpty a)
+ GHC.Data.List.NonEmpty: head :: NonEmpty a -> a
+ GHC.Data.List.NonEmpty: infixl 9 !!
+ GHC.Data.List.NonEmpty: infixr 5 :|
+ GHC.Data.List.NonEmpty: init :: NonEmpty a -> [a]
+ GHC.Data.List.NonEmpty: inits :: Foldable f => f a -> NonEmpty [a]
+ GHC.Data.List.NonEmpty: inits1 :: NonEmpty a -> NonEmpty (NonEmpty a)
+ GHC.Data.List.NonEmpty: insert :: (Foldable f, Ord a) => a -> f a -> NonEmpty a
+ GHC.Data.List.NonEmpty: intersperse :: a -> NonEmpty a -> NonEmpty a
+ GHC.Data.List.NonEmpty: isPrefixOf :: Eq a => [a] -> NonEmpty a -> Bool
+ GHC.Data.List.NonEmpty: isSingleton :: NonEmpty a -> Bool
+ GHC.Data.List.NonEmpty: iterate :: (a -> a) -> a -> NonEmpty a
+ GHC.Data.List.NonEmpty: last :: NonEmpty a -> a
+ GHC.Data.List.NonEmpty: length :: NonEmpty a -> Int
+ GHC.Data.List.NonEmpty: map :: (a -> b) -> NonEmpty a -> NonEmpty b
+ GHC.Data.List.NonEmpty: mapAndUnzip :: (a -> (b, c)) -> NonEmpty a -> (NonEmpty b, NonEmpty c)
+ GHC.Data.List.NonEmpty: mapAndUnzip3 :: (a -> (b, c, d)) -> NonEmpty a -> (NonEmpty b, NonEmpty c, NonEmpty d)
+ GHC.Data.List.NonEmpty: nonEmpty :: [a] -> Maybe (NonEmpty a)
+ GHC.Data.List.NonEmpty: nub :: Eq a => NonEmpty a -> NonEmpty a
+ GHC.Data.List.NonEmpty: nubBy :: (a -> a -> Bool) -> NonEmpty a -> NonEmpty a
+ GHC.Data.List.NonEmpty: partition :: (a -> Bool) -> NonEmpty a -> ([a], [a])
+ GHC.Data.List.NonEmpty: permutations :: [a] -> NonEmpty [a]
+ GHC.Data.List.NonEmpty: permutations1 :: NonEmpty a -> NonEmpty (NonEmpty a)
+ GHC.Data.List.NonEmpty: prependList :: [a] -> NonEmpty a -> NonEmpty a
+ GHC.Data.List.NonEmpty: repeat :: a -> NonEmpty a
+ GHC.Data.List.NonEmpty: reverse :: NonEmpty a -> NonEmpty a
+ GHC.Data.List.NonEmpty: scanl :: Foldable f => (b -> a -> b) -> b -> f a -> NonEmpty b
+ GHC.Data.List.NonEmpty: scanl1 :: (a -> a -> a) -> NonEmpty a -> NonEmpty a
+ GHC.Data.List.NonEmpty: scanr :: Foldable f => (a -> b -> b) -> b -> f a -> NonEmpty b
+ GHC.Data.List.NonEmpty: scanr1 :: (a -> a -> a) -> NonEmpty a -> NonEmpty a
+ GHC.Data.List.NonEmpty: singleton :: a -> NonEmpty a
+ GHC.Data.List.NonEmpty: some1 :: Alternative f => f a -> f (NonEmpty a)
+ GHC.Data.List.NonEmpty: sort :: Ord a => NonEmpty a -> NonEmpty a
+ GHC.Data.List.NonEmpty: sortBy :: (a -> a -> Ordering) -> NonEmpty a -> NonEmpty a
+ GHC.Data.List.NonEmpty: sortOn :: Ord b => (a -> b) -> NonEmpty a -> NonEmpty a
+ GHC.Data.List.NonEmpty: sortWith :: Ord o => (a -> o) -> NonEmpty a -> NonEmpty a
+ GHC.Data.List.NonEmpty: span :: (a -> Bool) -> NonEmpty a -> ([a], [a])
+ GHC.Data.List.NonEmpty: splitAt :: Int -> NonEmpty a -> ([a], [a])
+ GHC.Data.List.NonEmpty: tail :: NonEmpty a -> [a]
+ GHC.Data.List.NonEmpty: tails :: Foldable f => f a -> NonEmpty [a]
+ GHC.Data.List.NonEmpty: tails1 :: NonEmpty a -> NonEmpty (NonEmpty a)
+ GHC.Data.List.NonEmpty: take :: Int -> NonEmpty a -> [a]
+ GHC.Data.List.NonEmpty: takeWhile :: (a -> Bool) -> NonEmpty a -> [a]
+ GHC.Data.List.NonEmpty: toList :: Foldable t => t a -> [a]
+ GHC.Data.List.NonEmpty: transpose :: NonEmpty (NonEmpty a) -> NonEmpty (NonEmpty a)
+ GHC.Data.List.NonEmpty: uncons :: NonEmpty a -> (a, Maybe (NonEmpty a))
+ GHC.Data.List.NonEmpty: unfold :: (a -> (b, Maybe a)) -> a -> NonEmpty b
+ GHC.Data.List.NonEmpty: unfoldr :: (a -> (b, Maybe a)) -> a -> NonEmpty b
+ GHC.Data.List.NonEmpty: unzip :: NonEmpty (a, b) -> (NonEmpty a, NonEmpty b)
+ GHC.Data.List.NonEmpty: unzip3 :: NonEmpty (a, b, c) -> (NonEmpty a, NonEmpty b, NonEmpty c)
+ GHC.Data.List.NonEmpty: xor :: NonEmpty Bool -> Bool
+ GHC.Data.List.NonEmpty: zip :: NonEmpty a -> NonEmpty b -> NonEmpty (a, b)
+ GHC.Data.List.NonEmpty: zipWith :: (a -> b -> c) -> NonEmpty a -> NonEmpty b -> NonEmpty c
+ GHC.Data.List.NonEmpty: zipWithM :: Applicative f => (a -> b -> f c) -> NonEmpty a -> NonEmpty b -> f (NonEmpty c)
+ GHC.Data.Pair: instance Data.Foldable1.Foldable1 GHC.Data.Pair.Pair
+ GHC.Data.SmallArray: newSmallArrayIO :: Int -> a -> IO (SmallMutableArrayIO a)
+ GHC.Data.SmallArray: type SmallMutableArrayIO a = SmallMutableArray RealWorld a
+ GHC.Data.SmallArray: unsafeFreezeSmallArrayIO :: SmallMutableArrayIO a -> IO (SmallArray a)
+ GHC.Data.SmallArray: writeSmallArrayIO :: SmallMutableArrayIO a -> Int -> a -> IO ()
+ GHC.Data.Strict: instance (GHC.Internal.Classes.Eq a, GHC.Internal.Classes.Eq b) => GHC.Internal.Classes.Eq (GHC.Data.Strict.Pair a b)
+ GHC.Data.Strict: instance (GHC.Internal.Classes.Ord a, GHC.Internal.Classes.Ord b) => GHC.Internal.Classes.Ord (GHC.Data.Strict.Pair a b)
+ GHC.Data.Strict: instance Control.DeepSeq.NFData a => Control.DeepSeq.NFData (GHC.Data.Strict.Maybe a)
+ GHC.Data.Strict: instance GHC.Internal.Classes.Eq a => GHC.Internal.Classes.Eq (GHC.Data.Strict.Maybe a)
+ GHC.Data.Strict: instance GHC.Internal.Classes.Ord a => GHC.Internal.Classes.Ord (GHC.Data.Strict.Maybe a)
+ GHC.Data.TrieMap: instance (GHC.Internal.Classes.Eq (GHC.Data.TrieMap.Key m), GHC.Data.TrieMap.TrieMap m) => GHC.Data.TrieMap.TrieMap (GHC.Data.TrieMap.GenMap m)
+ GHC.Data.TrieMap: instance (GHC.Internal.Classes.Eq (GHC.Data.TrieMap.Key m), GHC.Data.TrieMap.TrieMap m) => GHC.Internal.Data.Foldable.Foldable (GHC.Data.TrieMap.GenMap m)
+ GHC.Data.TrieMap: instance GHC.Internal.Classes.Ord k => GHC.Data.TrieMap.TrieMap (Data.Map.Internal.Map k)
+ GHC.Data.TrieMap: mapMaybeTM :: TrieMap m => (a -> Maybe b) -> m a -> m b
+ GHC.Data.UnionFind: instance GHC.Internal.Classes.Eq (GHC.Data.UnionFind.Point s a)
+ GHC.Data.Word64Map.Internal: instance GHC.Internal.Classes.Eq a => GHC.Internal.Classes.Eq (GHC.Data.Word64Map.Internal.Word64Map a)
+ GHC.Data.Word64Map.Internal: instance GHC.Internal.Classes.Ord a => GHC.Internal.Classes.Ord (GHC.Data.Word64Map.Internal.Word64Map a)
+ GHC.Data.Word64Set.Internal: instance GHC.Internal.Classes.Eq GHC.Data.Word64Set.Internal.Word64Set
+ GHC.Data.Word64Set.Internal: instance GHC.Internal.Classes.Ord GHC.Data.Word64Set.Internal.Word64Set
+ GHC.Driver.Backend.Internal: instance GHC.Internal.Classes.Eq GHC.Driver.Backend.Internal.BackendName
+ GHC.Driver.Backpack: instance GHC.Internal.Classes.Eq GHC.Driver.Backpack.SessionType
+ GHC.Driver.Config: EvalStepNone :: EvalStep
+ GHC.Driver.Config: EvalStepOut :: EvalStep
+ GHC.Driver.Config: EvalStepSingle :: EvalStep
+ GHC.Driver.Config: data EvalStep
+ GHC.Driver.Config.Parser: supportedLanguagePragmas :: DynFlags -> [String]
+ GHC.Driver.Downsweep: DownsweepUseCompile :: DownsweepMode
+ GHC.Driver.Downsweep: DownsweepUseFixed :: DownsweepMode
+ GHC.Driver.Downsweep: External :: UnitId -> SummariseResult
+ GHC.Driver.Downsweep: FoundHome :: ModuleNodeInfo -> SummariseResult
+ GHC.Driver.Downsweep: FoundHomeWithError :: (UnitId, DriverMessages) -> SummariseResult
+ GHC.Driver.Downsweep: FoundInstantiation :: InstantiatedUnit -> SummariseResult
+ GHC.Driver.Downsweep: NotThere :: SummariseResult
+ GHC.Driver.Downsweep: checkHomeUnitsClosed :: UnitEnv -> [DriverMessages]
+ GHC.Driver.Downsweep: data DownsweepMode
+ GHC.Driver.Downsweep: data SummariseResult
+ GHC.Driver.Downsweep: downsweep :: HscEnv -> (GhcMessage -> AnyGhcDiagnostic) -> Maybe Messager -> [ModSummary] -> [ModuleName] -> Bool -> IO ([DriverMessages], ModuleGraph)
+ GHC.Driver.Downsweep: downsweepFromRootNodes :: HscEnv -> Map (UnitId, FilePath) ModSummary -> [ModuleName] -> Bool -> DownsweepMode -> [ModuleNodeInfo] -> [UnitId] -> IO ([DriverMessages], [ModuleGraphNode])
+ GHC.Driver.Downsweep: downsweepInstalledModules :: HscEnv -> [Module] -> IO ModuleGraph
+ GHC.Driver.Downsweep: downsweepInteractiveImports :: HscEnv -> InteractiveContext -> IO ModuleGraph
+ GHC.Driver.Downsweep: downsweepThunk :: HscEnv -> ModSummary -> IO ModuleGraph
+ GHC.Driver.Downsweep: instance GHC.Internal.Classes.Eq GHC.Driver.Downsweep.CodeGenEnable
+ GHC.Driver.Downsweep: instance GHC.Internal.Classes.Ord GHC.Driver.Downsweep.CodeGenEnable
+ GHC.Driver.Downsweep: instance GHC.Internal.Show.Show GHC.Driver.Downsweep.CodeGenEnable
+ GHC.Driver.Downsweep: instance GHC.Utils.Outputable.Outputable GHC.Driver.Downsweep.CodeGenEnable
+ GHC.Driver.Downsweep: instantiationNodes :: UnitId -> UnitState -> [(UnitId, InstantiatedUnit)]
+ GHC.Driver.Downsweep: summariseFile :: HscEnv -> HomeUnit -> Map (UnitId, FilePath) ModSummary -> FilePath -> Maybe Phase -> Maybe (StringBuffer, UTCTime) -> IO (Either DriverMessages ModSummary)
+ GHC.Driver.Downsweep: summariseModule :: HscEnv -> HomeUnit -> Map (UnitId, FilePath) ModSummary -> IsBootInterface -> Located ModuleName -> PkgQual -> Maybe (StringBuffer, UTCTime) -> [ModuleName] -> IO SummariseResult
+ GHC.Driver.Downsweep: summariseModuleInterface :: HscEnv -> HomeUnit -> IsBootInterface -> Located ModuleName -> PkgQual -> [ModuleName] -> IO SummariseResult
+ GHC.Driver.DynFlags: Opt_D_dump_stg_from_js_sinker :: DumpFlag
+ GHC.Driver.DynFlags: Opt_GhciBrowser :: GeneralFlag
+ GHC.Driver.DynFlags: Opt_GhciBrowserRedirectWasiConsole :: GeneralFlag
+ GHC.Driver.DynFlags: Opt_GhciDoLoadTargets :: GeneralFlag
+ GHC.Driver.DynFlags: Opt_WarnBadlyLevelledTypes :: WarningFlag
+ GHC.Driver.DynFlags: Opt_WarnDeprecatedPragmas :: WarningFlag
+ GHC.Driver.DynFlags: Opt_WarnPatternNamespaceSpecifier :: WarningFlag
+ GHC.Driver.DynFlags: Opt_WarnRuleLhsEqualities :: WarningFlag
+ GHC.Driver.DynFlags: Opt_WarnUnusableUnpackPragmas :: WarningFlag
+ GHC.Driver.DynFlags: Opt_WarnUselessSpecialisations :: WarningFlag
+ GHC.Driver.DynFlags: Opt_WriteSelfRecompFlags :: GeneralFlag
+ GHC.Driver.DynFlags: Opt_WriteSelfRecompInfo :: GeneralFlag
+ GHC.Driver.DynFlags: [ghciBrowserHost] :: DynFlags -> String
+ GHC.Driver.DynFlags: [ghciBrowserPlaywrightBrowserType] :: DynFlags -> Maybe String
+ GHC.Driver.DynFlags: [ghciBrowserPlaywrightLaunchOpts] :: DynFlags -> Maybe String
+ GHC.Driver.DynFlags: [ghciBrowserPort] :: DynFlags -> Int
+ GHC.Driver.DynFlags: [ghciBrowserPuppeteerLaunchOpts] :: DynFlags -> Maybe String
+ GHC.Driver.DynFlags: [unitSettings] :: DynFlags -> UnitSettings
+ GHC.Driver.DynFlags: baseUnitId :: DynFlags -> UnitId
+ GHC.Driver.DynFlags: instance GHC.Internal.Classes.Eq GHC.Driver.DynFlags.DynLibLoader
+ GHC.Driver.DynFlags: instance GHC.Internal.Classes.Eq GHC.Driver.DynFlags.DynamicTooState
+ GHC.Driver.DynFlags: instance GHC.Internal.Classes.Eq GHC.Driver.DynFlags.GhcLink
+ GHC.Driver.DynFlags: instance GHC.Internal.Classes.Eq GHC.Driver.DynFlags.GhcMode
+ GHC.Driver.DynFlags: instance GHC.Internal.Classes.Eq GHC.Driver.DynFlags.IgnorePackageFlag
+ GHC.Driver.DynFlags: instance GHC.Internal.Classes.Eq GHC.Driver.DynFlags.ModRenaming
+ GHC.Driver.DynFlags: instance GHC.Internal.Classes.Eq GHC.Driver.DynFlags.PackageArg
+ GHC.Driver.DynFlags: instance GHC.Internal.Classes.Eq GHC.Driver.DynFlags.PackageDBFlag
+ GHC.Driver.DynFlags: instance GHC.Internal.Classes.Eq GHC.Driver.DynFlags.PackageFlag
+ GHC.Driver.DynFlags: instance GHC.Internal.Classes.Eq GHC.Driver.DynFlags.PkgDbRef
+ GHC.Driver.DynFlags: instance GHC.Internal.Classes.Eq GHC.Driver.DynFlags.TrustFlag
+ GHC.Driver.DynFlags: instance GHC.Internal.Classes.Ord GHC.Driver.DynFlags.DynamicTooState
+ GHC.Driver.DynFlags: isSse3Enabled :: DynFlags -> Bool
+ GHC.Driver.DynFlags: isSsse3Enabled :: DynFlags -> Bool
+ GHC.Driver.Env: hscInsertHPT :: HomeModInfo -> HscEnv -> IO ()
+ GHC.Driver.Env: hsc_mod_graph :: HscEnv -> ModuleGraph
+ GHC.Driver.Env: hugAnnsBelow :: HscEnv -> UnitId -> ModuleNameWithIsBoot -> IO AnnEnv
+ GHC.Driver.Env: hugCompleteSigsBelow :: HscEnv -> UnitId -> ModuleNameWithIsBoot -> IO CompleteMatches
+ GHC.Driver.Env: hugInstancesBelow :: HscEnv -> UnitId -> ModuleNameWithIsBoot -> IO (InstEnv, [FamInst])
+ GHC.Driver.Env: hugRulesBelow :: HscEnv -> UnitId -> ModuleNameWithIsBoot -> IO RuleBase
+ GHC.Driver.Env: lookupIfaceByModuleHsc :: HscEnv -> Module -> IO (Maybe ModIface)
+ GHC.Driver.Env: setModuleGraph :: ModuleGraph -> HscEnv -> HscEnv
+ GHC.Driver.Errors.Types: type AnyGhcDiagnostic = UnknownDiagnosticFor GhcMessage
+ GHC.Driver.Flags: Off :: a -> OnOff a
+ GHC.Driver.Flags: On :: a -> OnOff a
+ GHC.Driver.Flags: Opt_D_dump_stg_from_js_sinker :: DumpFlag
+ GHC.Driver.Flags: Opt_GhciBrowser :: GeneralFlag
+ GHC.Driver.Flags: Opt_GhciBrowserRedirectWasiConsole :: GeneralFlag
+ GHC.Driver.Flags: Opt_GhciDoLoadTargets :: GeneralFlag
+ GHC.Driver.Flags: Opt_WarnBadlyLevelledTypes :: WarningFlag
+ GHC.Driver.Flags: Opt_WarnDeprecatedPragmas :: WarningFlag
+ GHC.Driver.Flags: Opt_WarnPatternNamespaceSpecifier :: WarningFlag
+ GHC.Driver.Flags: Opt_WarnRuleLhsEqualities :: WarningFlag
+ GHC.Driver.Flags: Opt_WarnUnusableUnpackPragmas :: WarningFlag
+ GHC.Driver.Flags: Opt_WarnUselessSpecialisations :: WarningFlag
+ GHC.Driver.Flags: Opt_WriteSelfRecompFlags :: GeneralFlag
+ GHC.Driver.Flags: Opt_WriteSelfRecompInfo :: GeneralFlag
+ GHC.Driver.Flags: data OnOff a
+ GHC.Driver.Flags: instance GHC.Internal.Classes.Eq GHC.Driver.Flags.Deprecation
+ GHC.Driver.Flags: instance GHC.Internal.Classes.Eq GHC.Driver.Flags.DumpFlag
+ GHC.Driver.Flags: instance GHC.Internal.Classes.Eq GHC.Driver.Flags.ExtensionDeprecation
+ GHC.Driver.Flags: instance GHC.Internal.Classes.Eq GHC.Driver.Flags.GeneralFlag
+ GHC.Driver.Flags: instance GHC.Internal.Classes.Eq GHC.Driver.Flags.Language
+ GHC.Driver.Flags: instance GHC.Internal.Classes.Eq GHC.Driver.Flags.WarningFlag
+ GHC.Driver.Flags: instance GHC.Internal.Classes.Eq GHC.Driver.Flags.WarningGroup
+ GHC.Driver.Flags: instance GHC.Internal.Classes.Eq a => GHC.Internal.Classes.Eq (GHC.Driver.Flags.OnOff a)
+ GHC.Driver.Flags: instance GHC.Internal.Classes.Ord GHC.Driver.Flags.Deprecation
+ GHC.Driver.Flags: instance GHC.Internal.Classes.Ord GHC.Driver.Flags.WarningFlag
+ GHC.Driver.Flags: instance GHC.Internal.Show.Show a => GHC.Internal.Show.Show (GHC.Driver.Flags.OnOff a)
+ GHC.Driver.Flags: instance GHC.Utils.Outputable.Outputable a => GHC.Utils.Outputable.Outputable (GHC.Driver.Flags.OnOff a)
+ GHC.Driver.IncludeSpecs: IncludeSpecs :: [String] -> [String] -> [String] -> IncludeSpecs
+ GHC.Driver.IncludeSpecs: [includePathsGlobal] :: IncludeSpecs -> [String]
+ GHC.Driver.IncludeSpecs: [includePathsQuoteImplicit] :: IncludeSpecs -> [String]
+ GHC.Driver.IncludeSpecs: [includePathsQuote] :: IncludeSpecs -> [String]
+ GHC.Driver.IncludeSpecs: addGlobalInclude :: IncludeSpecs -> [String] -> IncludeSpecs
+ GHC.Driver.IncludeSpecs: addImplicitQuoteInclude :: IncludeSpecs -> [String] -> IncludeSpecs
+ GHC.Driver.IncludeSpecs: addQuoteInclude :: IncludeSpecs -> [String] -> IncludeSpecs
+ GHC.Driver.IncludeSpecs: data IncludeSpecs
+ GHC.Driver.IncludeSpecs: flattenIncludes :: IncludeSpecs -> [String]
+ GHC.Driver.IncludeSpecs: instance GHC.Internal.Show.Show GHC.Driver.IncludeSpecs.IncludeSpecs
+ GHC.Driver.Main: genModDetails :: HscEnv -> ModIface -> IO ModDetails
+ GHC.Driver.Main: loadIfaceByteCodeLazy :: HscEnv -> ModIface -> ModLocation -> TypeEnv -> IO (Maybe Linkable)
+ GHC.Driver.Make: summariseModuleInterface :: HscEnv -> HomeUnit -> IsBootInterface -> Located ModuleName -> PkgQual -> [ModuleName] -> IO SummariseResult
+ GHC.Driver.MakeAction: JSemLimit :: SemaphoreName -> WorkerLimit
+ GHC.Driver.MakeAction: MakeAction :: RunMakeM a -> MVar (Maybe a) -> MakeAction
+ GHC.Driver.MakeAction: MakeEnv :: HscEnv -> AbstractSem -> (forall a. () => Int -> ((Logger -> Logger) -> IO a) -> IO a) -> Maybe Messager -> (GhcMessage -> AnyGhcDiagnostic) -> MakeEnv
+ GHC.Driver.MakeAction: NumProcessorsLimit :: Int -> WorkerLimit
+ GHC.Driver.MakeAction: [compile_sem] :: MakeEnv -> AbstractSem
+ GHC.Driver.MakeAction: [diag_wrapper] :: MakeEnv -> GhcMessage -> AnyGhcDiagnostic
+ GHC.Driver.MakeAction: [env_messager] :: MakeEnv -> Maybe Messager
+ GHC.Driver.MakeAction: [hsc_env] :: MakeEnv -> HscEnv
+ GHC.Driver.MakeAction: [withLogger] :: MakeEnv -> forall a. () => Int -> ((Logger -> Logger) -> IO a) -> IO a
+ GHC.Driver.MakeAction: data MakeAction
+ GHC.Driver.MakeAction: data MakeEnv
+ GHC.Driver.MakeAction: data WorkerLimit
+ GHC.Driver.MakeAction: instance GHC.Internal.Classes.Eq GHC.Driver.MakeAction.WorkerLimit
+ GHC.Driver.MakeAction: mkWorkerLimit :: DynFlags -> IO WorkerLimit
+ GHC.Driver.MakeAction: runAllPipelines :: WorkerLimit -> MakeEnv -> [MakeAction] -> IO ()
+ GHC.Driver.MakeAction: runParPipelines :: WorkerLimit -> HscEnv -> (GhcMessage -> AnyGhcDiagnostic) -> Maybe Messager -> [MakeAction] -> IO ()
+ GHC.Driver.MakeAction: runPipelines :: WorkerLimit -> HscEnv -> (GhcMessage -> AnyGhcDiagnostic) -> Maybe Messager -> [MakeAction] -> IO ()
+ GHC.Driver.MakeAction: runSeqPipelines :: HscEnv -> (GhcMessage -> AnyGhcDiagnostic) -> Maybe Messager -> [MakeAction] -> IO ()
+ GHC.Driver.MakeAction: runWorkerLimit :: WorkerLimit -> (AbstractSem -> IO a) -> IO a
+ GHC.Driver.MakeAction: type RunMakeM a = ReaderT MakeEnv MaybeT IO a
+ GHC.Driver.MakeAction: withLocalTmpFS :: TmpFs -> (TmpFs -> IO a) -> IO a
+ GHC.Driver.MakeAction: withLocalTmpFSMake :: MakeEnv -> (MakeEnv -> IO a) -> IO a
+ GHC.Driver.MakeAction: withLoggerHsc :: Int -> MakeEnv -> (HscEnv -> IO a) -> IO a
+ GHC.Driver.MakeAction: withParLog :: TVar LogQueueQueue -> Int -> ((Logger -> Logger) -> IO b) -> IO b
+ GHC.Driver.MakeFile: doMkDependModuleGraph :: GhcMonad m => DynFlags -> ModuleGraph -> m ()
+ GHC.Driver.Messager: batchMsg :: Messager
+ GHC.Driver.Messager: batchMultiMsg :: Messager
+ GHC.Driver.Messager: oneShotMsg :: Logger -> RecompileRequired -> IO ()
+ GHC.Driver.Messager: showModuleIndex :: (Int, Int) -> SDoc
+ GHC.Driver.Messager: type Messager = HscEnv -> (Int, Int) -> RecompileRequired -> ModuleGraphNode -> IO ()
+ GHC.Driver.Phases: instance GHC.Internal.Classes.Eq GHC.Driver.Phases.Phase
+ GHC.Driver.Phases: isHaskellBootSuffix :: String -> Bool
+ GHC.Driver.Ppr: printForUserColoured :: DynFlags -> Handle -> NamePprCtx -> Depth -> SDoc -> IO ()
+ GHC.Driver.Session: Opt_D_dump_stg_from_js_sinker :: DumpFlag
+ GHC.Driver.Session: Opt_GhciBrowser :: GeneralFlag
+ GHC.Driver.Session: Opt_GhciBrowserRedirectWasiConsole :: GeneralFlag
+ GHC.Driver.Session: Opt_GhciDoLoadTargets :: GeneralFlag
+ GHC.Driver.Session: Opt_WarnBadlyLevelledTypes :: WarningFlag
+ GHC.Driver.Session: Opt_WarnDeprecatedPragmas :: WarningFlag
+ GHC.Driver.Session: Opt_WarnPatternNamespaceSpecifier :: WarningFlag
+ GHC.Driver.Session: Opt_WarnRuleLhsEqualities :: WarningFlag
+ GHC.Driver.Session: Opt_WarnUnusableUnpackPragmas :: WarningFlag
+ GHC.Driver.Session: Opt_WarnUselessSpecialisations :: WarningFlag
+ GHC.Driver.Session: Opt_WriteSelfRecompFlags :: GeneralFlag
+ GHC.Driver.Session: Opt_WriteSelfRecompInfo :: GeneralFlag
+ GHC.Driver.Session: [ghciBrowserHost] :: DynFlags -> String
+ GHC.Driver.Session: [ghciBrowserPlaywrightBrowserType] :: DynFlags -> Maybe String
+ GHC.Driver.Session: [ghciBrowserPlaywrightLaunchOpts] :: DynFlags -> Maybe String
+ GHC.Driver.Session: [ghciBrowserPort] :: DynFlags -> Int
+ GHC.Driver.Session: [ghciBrowserPuppeteerLaunchOpts] :: DynFlags -> Maybe String
+ GHC.Driver.Session: [sUnitSettings] :: Settings -> UnitSettings
+ GHC.Driver.Session: [unitSettings] :: DynFlags -> UnitSettings
+ GHC.Driver.Session: baseUnitId :: DynFlags -> UnitId
+ GHC.Driver.Session: isSse3Enabled :: DynFlags -> Bool
+ GHC.Driver.Session: isSse4_1Enabled :: DynFlags -> Bool
+ GHC.Driver.Session: isSsse3Enabled :: DynFlags -> Bool
+ GHC.Driver.Session: setHomeUnitId :: UnitId -> DynFlags -> DynFlags
+ GHC.Driver.Session.Inspect: ModuleInfo :: TypeEnv -> [AvailInfo] -> [ClsInst] -> Maybe ModIface -> SafeHaskellMode -> Maybe InternalModBreaks -> ModuleInfo
+ GHC.Driver.Session.Inspect: [minf_exports] :: ModuleInfo -> [AvailInfo]
+ GHC.Driver.Session.Inspect: [minf_iface] :: ModuleInfo -> Maybe ModIface
+ GHC.Driver.Session.Inspect: [minf_instances] :: ModuleInfo -> [ClsInst]
+ GHC.Driver.Session.Inspect: [minf_modBreaks] :: ModuleInfo -> Maybe InternalModBreaks
+ GHC.Driver.Session.Inspect: [minf_safe] :: ModuleInfo -> SafeHaskellMode
+ GHC.Driver.Session.Inspect: [minf_type_env] :: ModuleInfo -> TypeEnv
+ GHC.Driver.Session.Inspect: availsToGlobalRdrEnv :: HasDebugCallStack => HscEnv -> Module -> [AvailInfo] -> IfGlobalRdrEnv
+ GHC.Driver.Session.Inspect: data ModuleInfo
+ GHC.Driver.Session.Inspect: getBindings :: GhcMonad m => m [TyThing]
+ GHC.Driver.Session.Inspect: getHomeModuleInfo :: HscEnv -> Module -> IO (Maybe ModuleInfo)
+ GHC.Driver.Session.Inspect: getInsts :: GhcMonad m => m ([ClsInst], [FamInst])
+ GHC.Driver.Session.Inspect: getModuleGraph :: GhcMonad m => m ModuleGraph
+ GHC.Driver.Session.Inspect: getModuleInfo :: GhcMonad m => Module -> m (Maybe ModuleInfo)
+ GHC.Driver.Session.Inspect: getNamePprCtx :: GhcMonad m => m NamePprCtx
+ GHC.Driver.Session.Inspect: getPackageModuleInfo :: HscEnv -> Module -> IO (Maybe ModuleInfo)
+ GHC.Driver.Session.Inspect: isLoaded :: GhcMonad m => ModuleName -> m Bool
+ GHC.Driver.Session.Inspect: isLoadedHomeModule :: GhcMonad m => Module -> m Bool
+ GHC.Driver.Session.Inspect: isLoadedModule :: GhcMonad m => UnitId -> ModuleName -> m Bool
+ GHC.Driver.Session.Inspect: mkNamePprCtxForModule :: GhcMonad m => Module -> ModuleInfo -> m NamePprCtx
+ GHC.Driver.Session.Inspect: modInfoExports :: ModuleInfo -> [Name]
+ GHC.Driver.Session.Inspect: modInfoExportsWithSelectors :: ModuleInfo -> [Name]
+ GHC.Driver.Session.Inspect: modInfoIface :: ModuleInfo -> Maybe ModIface
+ GHC.Driver.Session.Inspect: modInfoInstances :: ModuleInfo -> [ClsInst]
+ GHC.Driver.Session.Inspect: modInfoIsExportedName :: ModuleInfo -> Name -> Bool
+ GHC.Driver.Session.Inspect: modInfoLookupName :: GhcMonad m => ModuleInfo -> Name -> m (Maybe TyThing)
+ GHC.Driver.Session.Inspect: modInfoModBreaks :: ModuleInfo -> Maybe InternalModBreaks
+ GHC.Driver.Session.Inspect: modInfoSafe :: ModuleInfo -> SafeHaskellMode
+ GHC.Driver.Session.Inspect: modInfoTyThings :: ModuleInfo -> [TyThing]
+ GHC.Driver.Session.Units: initMake :: [(String, Maybe Phase)] -> Ghc [(String, Maybe Phase)]
+ GHC.Driver.Session.Units: initMulti :: NonEmpty String -> (DynFlags -> [(String, Maybe Phase)] -> [String] -> [String] -> IO ()) -> Ghc [(String, Maybe UnitId, Maybe Phase)]
+ GHC.Hs: instance GHC.Internal.Classes.Eq GHC.Hs.AnnsModule
+ GHC.Hs.Binds: HsRuleBndrsAnn :: Maybe (TokForall, EpToken ".") -> Maybe (TokForall, EpToken ".") -> HsRuleBndrsAnn
+ GHC.Hs.Binds: SpecPragE :: Name -> Id -> InlinePragma -> [Var] -> LHsExpr GhcTc -> TcSpecPrag
+ GHC.Hs.Binds: [rb_tmanns] :: HsRuleBndrsAnn -> Maybe (TokForall, EpToken ".")
+ GHC.Hs.Binds: [rb_tyanns] :: HsRuleBndrsAnn -> Maybe (TokForall, EpToken ".")
+ GHC.Hs.Binds: [spe_bndrs] :: TcSpecPrag -> [Var]
+ GHC.Hs.Binds: [spe_call] :: TcSpecPrag -> LHsExpr GhcTc
+ GHC.Hs.Binds: [spe_fn_id] :: TcSpecPrag -> Id
+ GHC.Hs.Binds: [spe_fn_nm] :: TcSpecPrag -> Name
+ GHC.Hs.Binds: [spe_inl] :: TcSpecPrag -> InlinePragma
+ GHC.Hs.Binds: data HsRuleBndrsAnn
+ GHC.Hs.Binds: instance GHC.Hs.Extension.OutputableBndrId p => GHC.Utils.Outputable.Outputable (Language.Haskell.Syntax.Binds.RuleBndr (GHC.Hs.Extension.GhcPass p))
+ GHC.Hs.Binds: instance GHC.Hs.Extension.OutputableBndrId p => GHC.Utils.Outputable.Outputable (Language.Haskell.Syntax.Binds.RuleBndrs (GHC.Hs.Extension.GhcPass p))
+ GHC.Hs.Binds: instance GHC.Internal.Classes.Eq GHC.Hs.Binds.ActivationAnn
+ GHC.Hs.Binds: instance GHC.Internal.Classes.Eq GHC.Hs.Binds.HsRuleBndrsAnn
+ GHC.Hs.Binds: instance GHC.Internal.Classes.Eq GHC.Hs.Binds.NamespaceSpecifier
+ GHC.Hs.Binds: instance GHC.Internal.Data.Data.Data GHC.Hs.Binds.HsRuleBndrsAnn
+ GHC.Hs.Binds: instance GHC.Parser.Annotation.NoAnn GHC.Hs.Binds.HsRuleBndrsAnn
+ GHC.Hs.Binds: instance GHC.Utils.Outputable.Outputable (GHC.Hs.Extension.XRecGhc (GHC.Hs.Extension.IdGhcP p)) => GHC.Utils.Outputable.Outputable (Language.Haskell.Syntax.Binds.RecordPatSynField (GHC.Hs.Extension.GhcPass p))
+ GHC.Hs.Decls: [con_inner_bndrs] :: ConDecl pass -> [HsForAllTelescope pass]
+ GHC.Hs.Decls: [con_outer_bndrs] :: ConDecl pass -> XRec pass (HsOuterSigTyVarBndrs pass)
+ GHC.Hs.Decls: [rd_bndrs] :: RuleDecl pass -> RuleBndrs pass
+ GHC.Hs.Decls: instance GHC.Internal.Classes.Eq GHC.Hs.Decls.HsRuleAnn
+ GHC.Hs.Decls: tyClDeclFlavour :: forall (p :: Pass) tc. TyClDecl (GhcPass p) -> TyConFlavour tc
+ GHC.Hs.Doc: instance (GHC.Internal.Classes.Eq (Language.Haskell.Syntax.Extension.IdP pass), GHC.Internal.Classes.Eq a) => GHC.Internal.Classes.Eq (GHC.Hs.Doc.WithHsDocIdentifiers a pass)
+ GHC.Hs.DocString: instance GHC.Internal.Classes.Eq GHC.Hs.DocString.HsDocString
+ GHC.Hs.DocString: instance GHC.Internal.Classes.Eq GHC.Hs.DocString.HsDocStringChunk
+ GHC.Hs.DocString: instance GHC.Internal.Classes.Eq GHC.Hs.DocString.HsDocStringDecorator
+ GHC.Hs.DocString: instance GHC.Internal.Classes.Ord GHC.Hs.DocString.HsDocStringChunk
+ GHC.Hs.DocString: instance GHC.Internal.Classes.Ord GHC.Hs.DocString.HsDocStringDecorator
+ GHC.Hs.Dump: instance GHC.Internal.Classes.Eq GHC.Hs.Dump.BlankEpAnnotations
+ GHC.Hs.Dump: instance GHC.Internal.Classes.Eq GHC.Hs.Dump.BlankSrcSpan
+ GHC.Hs.Expr: HoleError :: HoleKind
+ GHC.Hs.Expr: HoleVar :: LIdP GhcPs -> HoleKind
+ GHC.Hs.Expr: HsImplicitLiftSplice :: Set ThLevelIndex -> ThLevelIndex -> Maybe GlobalRdrElt -> LIdOccP GhcRn -> HsImplicitLiftSplice
+ GHC.Hs.Expr: HsQuasiQuoteExt :: UntypedSpliceFlavour -> HsQuasiQuoteExt
+ GHC.Hs.Expr: HsTypedSpliceNested :: SplicePointName -> HsTypedSpliceResult
+ GHC.Hs.Expr: HsTypedSpliceTop :: HsTypedSpliceResult
+ GHC.Hs.Expr: HsUserSpliceExt :: UntypedSpliceFlavour -> HsUserSpliceExt
+ GHC.Hs.Expr: [implicit_lift_bind_lvl] :: HsImplicitLiftSplice -> Set ThLevelIndex
+ GHC.Hs.Expr: [implicit_lift_gre] :: HsImplicitLiftSplice -> Maybe GlobalRdrElt
+ GHC.Hs.Expr: [implicit_lift_lid] :: HsImplicitLiftSplice -> LIdOccP GhcRn
+ GHC.Hs.Expr: [implicit_lift_used_lvl] :: HsImplicitLiftSplice -> ThLevelIndex
+ GHC.Hs.Expr: [quasi_quote_flavour] :: HsQuasiQuoteExt -> UntypedSpliceFlavour
+ GHC.Hs.Expr: [user_splice_flavour] :: HsUserSpliceExt -> UntypedSpliceFlavour
+ GHC.Hs.Expr: data HoleKind
+ GHC.Hs.Expr: data HsImplicitLiftSplice
+ GHC.Hs.Expr: data HsQuasiQuoteExt
+ GHC.Hs.Expr: data HsTypedSpliceResult
+ GHC.Hs.Expr: data HsUserSpliceExt
+ GHC.Hs.Expr: instance (GHC.Hs.Extension.OutputableBndrId pl, GHC.Hs.Extension.OutputableBndrId pr, Language.Haskell.Syntax.Extension.Anno (Language.Haskell.Syntax.Expr.StmtLR (GHC.Hs.Extension.GhcPass pl) (GHC.Hs.Extension.GhcPass pr) body) GHC.Internal.Types.~ GHC.Parser.Annotation.SrcSpanAnnA, GHC.Utils.Outputable.Outputable body) => GHC.Utils.Outputable.Outputable (Language.Haskell.Syntax.Expr.StmtLR (GHC.Hs.Extension.GhcPass pl) (GHC.Hs.Extension.GhcPass pr) body)
+ GHC.Hs.Expr: instance GHC.Internal.Data.Data.Data GHC.Hs.Expr.HoleKind
+ GHC.Hs.Expr: isInfixMatch :: forall (p :: Pass) body. Match (GhcPass p) body -> Bool
+ GHC.Hs.Expr: mkHsVar :: forall (p :: Pass). IsPass p => LIdP (GhcPass p) -> HsExpr (GhcPass p)
+ GHC.Hs.Expr: mkHsVarWithUserRdr :: forall (p :: Pass). IsPass p => RdrName -> LIdP (GhcPass p) -> HsExpr (GhcPass p)
+ GHC.Hs.Expr: multAnnToHsExpr :: HsMultAnnOf (LocatedA (HsExpr GhcRn)) GhcRn -> Maybe (LocatedA (HsExpr GhcRn))
+ GHC.Hs.Expr: unnamedHoleRdrName :: RdrName
+ GHC.Hs.Extension: type LIdGhcP (p :: Pass) = XRecGhc IdGhcP p
+ GHC.Hs.Extension: type LIdOccGhcP (p :: Pass) = XRecGhc IdOccGhcP p
+ GHC.Hs.Extension: type XRecGhc a = GenLocated Anno a a
+ GHC.Hs.ImpExp: EpAnnLevelQuote :: EpToken "quote" -> EpAnnLevel
+ GHC.Hs.ImpExp: EpAnnLevelSplice :: EpToken "splice" -> EpAnnLevel
+ GHC.Hs.ImpExp: [importDeclAnnLevel] :: EpAnnImportDecl -> Maybe EpAnnLevel
+ GHC.Hs.ImpExp: data EpAnnLevel
+ GHC.Hs.ImpExp: ieLIEWrappedName :: forall (p :: Pass). IE (GhcPass p) -> LIEWrappedName (GhcPass p)
+ GHC.Hs.ImpExp: instance GHC.Internal.Classes.Eq (Language.Haskell.Syntax.ImpExp.IEWrappedName GHC.Hs.Extension.GhcPs)
+ GHC.Hs.ImpExp: instance GHC.Internal.Classes.Eq (Language.Haskell.Syntax.ImpExp.IEWrappedName GHC.Hs.Extension.GhcRn)
+ GHC.Hs.ImpExp: instance GHC.Internal.Classes.Eq (Language.Haskell.Syntax.ImpExp.IEWrappedName GHC.Hs.Extension.GhcTc)
+ GHC.Hs.ImpExp: instance GHC.Internal.Data.Data.Data GHC.Hs.ImpExp.EpAnnLevel
+ GHC.Hs.ImpExp: instance GHC.Parser.Annotation.HasLoc GHC.Hs.ImpExp.EpAnnLevel
+ GHC.Hs.Instances: instance (GHC.Internal.Data.Typeable.Internal.Typeable p, GHC.Internal.Data.Data.Data (Language.Haskell.Syntax.Extension.Anno (GHC.Hs.Extension.IdGhcP p)), GHC.Internal.Data.Data.Data (GHC.Hs.Extension.IdGhcP p)) => GHC.Internal.Data.Data.Data (Language.Haskell.Syntax.BooleanFormula.BooleanFormula (GHC.Hs.Extension.GhcPass p))
+ GHC.Hs.Instances: instance GHC.Internal.Classes.Eq (Language.Haskell.Syntax.ImpExp.IE GHC.Hs.Extension.GhcPs)
+ GHC.Hs.Instances: instance GHC.Internal.Classes.Eq (Language.Haskell.Syntax.ImpExp.IE GHC.Hs.Extension.GhcRn)
+ GHC.Hs.Instances: instance GHC.Internal.Classes.Eq (Language.Haskell.Syntax.ImpExp.IE GHC.Hs.Extension.GhcTc)
+ GHC.Hs.Instances: instance GHC.Internal.Data.Data.Data (Language.Haskell.Syntax.Binds.RuleBndr GHC.Hs.Extension.GhcPs)
+ GHC.Hs.Instances: instance GHC.Internal.Data.Data.Data (Language.Haskell.Syntax.Binds.RuleBndr GHC.Hs.Extension.GhcRn)
+ GHC.Hs.Instances: instance GHC.Internal.Data.Data.Data (Language.Haskell.Syntax.Binds.RuleBndr GHC.Hs.Extension.GhcTc)
+ GHC.Hs.Instances: instance GHC.Internal.Data.Data.Data (Language.Haskell.Syntax.Binds.RuleBndrs GHC.Hs.Extension.GhcPs)
+ GHC.Hs.Instances: instance GHC.Internal.Data.Data.Data (Language.Haskell.Syntax.Binds.RuleBndrs GHC.Hs.Extension.GhcRn)
+ GHC.Hs.Instances: instance GHC.Internal.Data.Data.Data (Language.Haskell.Syntax.Binds.RuleBndrs GHC.Hs.Extension.GhcTc)
+ GHC.Hs.Instances: instance GHC.Internal.Data.Data.Data (Language.Haskell.Syntax.Expr.HsTypedSplice GHC.Hs.Extension.GhcPs)
+ GHC.Hs.Instances: instance GHC.Internal.Data.Data.Data (Language.Haskell.Syntax.Expr.HsTypedSplice GHC.Hs.Extension.GhcRn)
+ GHC.Hs.Instances: instance GHC.Internal.Data.Data.Data (Language.Haskell.Syntax.Expr.HsTypedSplice GHC.Hs.Extension.GhcTc)
+ GHC.Hs.Instances: instance GHC.Internal.Data.Data.Data (Language.Haskell.Syntax.Type.HsConDeclField GHC.Hs.Extension.GhcPs)
+ GHC.Hs.Instances: instance GHC.Internal.Data.Data.Data (Language.Haskell.Syntax.Type.HsConDeclField GHC.Hs.Extension.GhcRn)
+ GHC.Hs.Instances: instance GHC.Internal.Data.Data.Data (Language.Haskell.Syntax.Type.HsConDeclField GHC.Hs.Extension.GhcTc)
+ GHC.Hs.Instances: instance GHC.Internal.Data.Data.Data (Language.Haskell.Syntax.Type.HsConDeclRecField GHC.Hs.Extension.GhcPs)
+ GHC.Hs.Instances: instance GHC.Internal.Data.Data.Data (Language.Haskell.Syntax.Type.HsConDeclRecField GHC.Hs.Extension.GhcRn)
+ GHC.Hs.Instances: instance GHC.Internal.Data.Data.Data (Language.Haskell.Syntax.Type.HsConDeclRecField GHC.Hs.Extension.GhcTc)
+ GHC.Hs.Instances: instance GHC.Internal.Data.Data.Data (Language.Haskell.Syntax.Type.HsMultAnnOf (GHC.Parser.Annotation.LocatedA (Language.Haskell.Syntax.Expr.HsExpr GHC.Hs.Extension.GhcPs)) GHC.Hs.Extension.GhcPs)
+ GHC.Hs.Instances: instance GHC.Internal.Data.Data.Data (Language.Haskell.Syntax.Type.HsMultAnnOf (GHC.Parser.Annotation.LocatedA (Language.Haskell.Syntax.Expr.HsExpr GHC.Hs.Extension.GhcRn)) GHC.Hs.Extension.GhcRn)
+ GHC.Hs.Instances: instance GHC.Internal.Data.Data.Data (Language.Haskell.Syntax.Type.HsMultAnnOf (GHC.Parser.Annotation.LocatedA (Language.Haskell.Syntax.Expr.HsExpr GHC.Hs.Extension.GhcTc)) GHC.Hs.Extension.GhcTc)
+ GHC.Hs.Instances: instance GHC.Internal.Data.Data.Data (Language.Haskell.Syntax.Type.HsMultAnnOf (GHC.Parser.Annotation.LocatedA (Language.Haskell.Syntax.Type.HsType GHC.Hs.Extension.GhcPs)) GHC.Hs.Extension.GhcPs)
+ GHC.Hs.Instances: instance GHC.Internal.Data.Data.Data (Language.Haskell.Syntax.Type.HsMultAnnOf (GHC.Parser.Annotation.LocatedA (Language.Haskell.Syntax.Type.HsType GHC.Hs.Extension.GhcRn)) GHC.Hs.Extension.GhcRn)
+ GHC.Hs.Instances: instance GHC.Internal.Data.Data.Data (Language.Haskell.Syntax.Type.HsMultAnnOf (GHC.Parser.Annotation.LocatedA (Language.Haskell.Syntax.Type.HsType GHC.Hs.Extension.GhcRn)) GHC.Hs.Extension.GhcTc)
+ GHC.Hs.Instances: instance GHC.Internal.Data.Data.Data GHC.Hs.Binds.TcSpecPrag
+ GHC.Hs.Instances: instance GHC.Internal.Data.Data.Data GHC.Hs.Binds.TcSpecPrags
+ GHC.Hs.Instances: instance GHC.Internal.Data.Data.Data GHC.Hs.Expr.HsImplicitLiftSplice
+ GHC.Hs.Instances: instance GHC.Internal.Data.Data.Data GHC.Hs.Expr.HsQuasiQuoteExt
+ GHC.Hs.Instances: instance GHC.Internal.Data.Data.Data GHC.Hs.Expr.HsTypedSpliceResult
+ GHC.Hs.Instances: instance GHC.Internal.Data.Data.Data GHC.Hs.Expr.HsUserSpliceExt
+ GHC.Hs.Instances: instance GHC.Internal.Data.Data.Data GHC.Hs.Lit.HsLitTc
+ GHC.Hs.Instances: instance GHC.Internal.Data.Data.Data GHC.Hs.Type.HsTypeGhcPsExt
+ GHC.Hs.Instances: instance GHC.Internal.Data.Data.Data a => GHC.Internal.Data.Data.Data (GHC.Types.Name.Reader.WithUserRdr a)
+ GHC.Hs.Lit: HsInteger :: SourceText -> Integer -> Type -> HsLitTc
+ GHC.Hs.Lit: HsRat :: FractionalLit -> Type -> HsLitTc
+ GHC.Hs.Lit: data HsLitTc
+ GHC.Hs.Lit: instance GHC.Hs.Extension.IsPass p => GHC.Utils.Outputable.Outputable (Language.Haskell.Syntax.Lit.HsLit (GHC.Hs.Extension.GhcPass p))
+ GHC.Hs.Lit: instance GHC.Internal.Classes.Eq (Language.Haskell.Syntax.Extension.XXOverLit p) => GHC.Internal.Classes.Eq (Language.Haskell.Syntax.Lit.HsOverLit p)
+ GHC.Hs.Lit: instance GHC.Internal.Classes.Eq GHC.Hs.Lit.HsLitTc
+ GHC.Hs.Lit: instance GHC.Internal.Classes.Ord (Language.Haskell.Syntax.Extension.XXOverLit p) => GHC.Internal.Classes.Ord (Language.Haskell.Syntax.Lit.HsOverLit p)
+ GHC.Hs.Pat: instance (GHC.Utils.Outputable.Outputable arg, GHC.Utils.Outputable.Outputable (Language.Haskell.Syntax.Extension.XRec p (Language.Haskell.Syntax.Pat.HsRecField p arg)), Language.Haskell.Syntax.Extension.XRec p Language.Haskell.Syntax.Pat.RecFieldsDotDot GHC.Internal.Types.~ GHC.Parser.Annotation.LocatedE Language.Haskell.Syntax.Pat.RecFieldsDotDot) => GHC.Utils.Outputable.Outputable (Language.Haskell.Syntax.Pat.HsRecFields p arg)
+ GHC.Hs.Pat: isInvisArgLPat :: UnXRec p => LPat p -> Bool
+ GHC.Hs.Pat: isVisArgLPat :: UnXRec p => LPat p -> Bool
+ GHC.Hs.Type: CDF :: XConDeclField pass -> SrcUnpackedness -> SrcStrictness -> HsMultAnn pass -> LHsType pass -> Maybe (LHsDoc pass) -> HsConDeclField pass
+ GHC.Hs.Type: EpArrow :: TokRarrow -> EpArrowOrColon
+ GHC.Hs.Type: EpColon :: TokDcolon -> EpArrowOrColon
+ GHC.Hs.Type: EpPatBind :: EpArrowOrColon
+ GHC.Hs.Type: HsConDeclRecField :: XConDeclRecField pass -> [LFieldOcc pass] -> HsConDeclField pass -> HsConDeclRecField pass
+ GHC.Hs.Type: HsCoreTy :: HsCoreTy -> HsTypeGhcPsExt
+ GHC.Hs.Type: HsLinearAnn :: XLinearAnn mult pass -> HsMultAnnOf mult pass
+ GHC.Hs.Type: HsUnannotated :: XUnannotated mult pass -> HsMultAnnOf mult pass
+ GHC.Hs.Type: XConDeclRecField :: XXConDeclRecField pass -> HsConDeclRecField pass
+ GHC.Hs.Type: XMultAnnOf :: XXMultAnnOf mult pass -> HsMultAnnOf mult pass
+ GHC.Hs.Type: [cdf_bang] :: HsConDeclField pass -> SrcStrictness
+ GHC.Hs.Type: [cdf_doc] :: HsConDeclField pass -> Maybe (LHsDoc pass)
+ GHC.Hs.Type: [cdf_ext] :: HsConDeclField pass -> XConDeclField pass
+ GHC.Hs.Type: [cdf_multiplicity] :: HsConDeclField pass -> HsMultAnn pass
+ GHC.Hs.Type: [cdf_type] :: HsConDeclField pass -> LHsType pass
+ GHC.Hs.Type: [cdf_unpack] :: HsConDeclField pass -> SrcUnpackedness
+ GHC.Hs.Type: [cdrf_ext] :: HsConDeclRecField pass -> XConDeclRecField pass
+ GHC.Hs.Type: [cdrf_names] :: HsConDeclRecField pass -> [LFieldOcc pass]
+ GHC.Hs.Type: [cdrf_spec] :: HsConDeclRecField pass -> HsConDeclField pass
+ GHC.Hs.Type: data EpArrowOrColon
+ GHC.Hs.Type: data EpLinear
+ GHC.Hs.Type: data HsConDeclField pass
+ GHC.Hs.Type: data HsConDeclRecField pass
+ GHC.Hs.Type: data HsMultAnnOf mult pass
+ GHC.Hs.Type: data HsTypeGhcPsExt
+ GHC.Hs.Type: expandHsMultAnnOf :: (LocatedN Name -> t GhcRn) -> HsMultAnnOf (LocatedA (t GhcRn)) GhcRn -> Maybe (LocatedA (t GhcRn))
+ GHC.Hs.Type: hsForAllTelescopeBndrs :: forall (p :: Pass). HsForAllTelescope (GhcPass p) -> [LHsTyVarBndr ForAllTyFlag (GhcPass p)]
+ GHC.Hs.Type: hsPlainTypeField :: LHsType GhcPs -> HsConDeclField GhcPs
+ GHC.Hs.Type: instance (GHC.Utils.Outputable.Outputable arg, GHC.Utils.Outputable.Outputable rec) => GHC.Utils.Outputable.Outputable (Language.Haskell.Syntax.Type.HsConDetails arg rec)
+ GHC.Hs.Type: instance (GHC.Utils.Outputable.Outputable mult, GHC.Hs.Extension.OutputableBndrId pass) => GHC.Utils.Outputable.Outputable (Language.Haskell.Syntax.Type.HsMultAnnOf mult (GHC.Hs.Extension.GhcPass pass))
+ GHC.Hs.Type: instance GHC.Hs.Extension.OutputableBndrId p => GHC.Utils.Outputable.Outputable (Language.Haskell.Syntax.Type.HsConDeclRecField (GHC.Hs.Extension.GhcPass p))
+ GHC.Hs.Type: instance GHC.Hs.Type.OutputableBndrFlag Language.Haskell.Syntax.Specificity.ForAllTyFlag p
+ GHC.Hs.Type: instance GHC.Internal.Data.Data.Data GHC.Hs.Type.EpArrowOrColon
+ GHC.Hs.Type: instance GHC.Internal.Data.Data.Data GHC.Hs.Type.EpLinear
+ GHC.Hs.Type: instance GHC.Parser.Annotation.NoAnn GHC.Hs.Type.EpLinear
+ GHC.Hs.Type: instance GHC.Utils.Outputable.Outputable (GHC.Hs.Extension.XRecGhc (GHC.Hs.Extension.IdGhcP p)) => GHC.Utils.Outputable.Outputable (Language.Haskell.Syntax.Type.FieldOcc (GHC.Hs.Extension.GhcPass p))
+ GHC.Hs.Type: mkConDeclField :: HsMultAnn GhcPs -> LHsType GhcPs -> HsConDeclField GhcPs
+ GHC.Hs.Type: multAnnToHsType :: HsMultAnn GhcRn -> Maybe (LHsType GhcRn)
+ GHC.Hs.Type: pprHsConDeclFieldNoMult :: forall (p :: Pass). OutputableBndrId p => HsConDeclField (GhcPass p) -> SDoc
+ GHC.Hs.Type: pprHsConDeclFieldWith :: forall (p :: Pass). OutputableBndrId p => (HsMultAnn (GhcPass p) -> SDoc -> SDoc) -> HsConDeclField (GhcPass p) -> SDoc
+ GHC.Hs.Type: pprHsConDeclRecFields :: forall (p :: Pass). OutputableBndrId p => [LHsConDeclRecField (GhcPass p)] -> SDoc
+ GHC.Hs.Type: pprHsForAllTelescope :: forall (p :: Pass). OutputableBndrId p => HsForAllTelescope (GhcPass p) -> SDoc
+ GHC.Hs.Type: pprHsMultAnn :: forall (id :: Pass). OutputableBndrId id => HsMultAnn (GhcPass id) -> SDoc
+ GHC.Hs.Type: type HsMultAnn pass = HsMultAnnOf LHsType NoGhcTc pass pass
+ GHC.Hs.Type: type LHsConDeclRecField pass = XRec pass HsConDeclRecField pass
+ GHC.Hs.Utils: forgetUserRdr :: forall (p :: Pass). IsPass p => IdOccP (GhcPass p) -> IdP (GhcPass p)
+ GHC.Hs.Utils: noUserRdr :: Name -> WithUserRdr Name
+ GHC.HsToCore.Binds: dsImpSpecs :: [LTcSpecPrag] -> DsM (OrdList (Id, CoreExpr), [CoreRule])
+ GHC.HsToCore.Breakpoints: BreakpointId :: Module -> BreakTickIndex -> BreakpointId
+ GHC.HsToCore.Breakpoints: ModBreaks :: Array BreakTickIndex SrcSpan -> Array BreakTickIndex [OccName] -> Array BreakTickIndex [String] -> Array BreakTickIndex (String, String) -> Module -> ModBreaks
+ GHC.HsToCore.Breakpoints: [bi_tick_index] :: BreakpointId -> BreakTickIndex
+ GHC.HsToCore.Breakpoints: [bi_tick_mod] :: BreakpointId -> Module
+ GHC.HsToCore.Breakpoints: [modBreaks_ccs] :: ModBreaks -> Array BreakTickIndex (String, String)
+ GHC.HsToCore.Breakpoints: [modBreaks_decls] :: ModBreaks -> Array BreakTickIndex [String]
+ GHC.HsToCore.Breakpoints: [modBreaks_locs] :: ModBreaks -> Array BreakTickIndex SrcSpan
+ GHC.HsToCore.Breakpoints: [modBreaks_module] :: ModBreaks -> Module
+ GHC.HsToCore.Breakpoints: [modBreaks_vars] :: ModBreaks -> Array BreakTickIndex [OccName]
+ GHC.HsToCore.Breakpoints: data BreakpointId
+ GHC.HsToCore.Breakpoints: data ModBreaks
+ GHC.HsToCore.Breakpoints: type BreakTickIndex = Int
+ GHC.HsToCore.Errors.Types: DsUselessSpecialisePragma :: Name -> Bool -> UselessSpecialisePragmaReason -> DsMessage
+ GHC.HsToCore.Errors.Types: ThDataConVisibleForall :: ThRejectionReason
+ GHC.HsToCore.Errors.Types: UselessSpecialiseForClassMethodSelector :: UselessSpecialisePragmaReason
+ GHC.HsToCore.Errors.Types: UselessSpecialiseForNoInlineFunction :: UselessSpecialisePragmaReason
+ GHC.HsToCore.Errors.Types: UselessSpecialiseNoSpecialisation :: UselessSpecialisePragmaReason
+ GHC.HsToCore.Errors.Types: data UselessSpecialisePragmaReason
+ GHC.HsToCore.Errors.Types: instance GHC.Internal.Generics.Generic GHC.HsToCore.Errors.Types.UselessSpecialisePragmaReason
+ GHC.HsToCore.Errors.Types: uselessSpecialisePragmaKeepAnyway :: UselessSpecialisePragmaReason -> Bool
+ GHC.HsToCore.Foreign.Wasm: instance GHC.Internal.Classes.Eq GHC.HsToCore.Foreign.Wasm.Synchronicity
+ GHC.HsToCore.Match.Literal: numericConversionNames :: [Name]
+ GHC.HsToCore.Monad: dsGetGlobalRdrEnv :: DsM GlobalRdrEnv
+ GHC.HsToCore.Monad: infixl 4 <$>
+ GHC.HsToCore.Monad: zapUnspecables :: DsM a -> DsM a
+ GHC.HsToCore.Pmc: instance GHC.Internal.Classes.Eq (GHC.HsToCore.Pmc.FormatReportWarningsMode ann)
+ GHC.HsToCore.Pmc.Solver: instance GHC.Internal.Classes.Eq GHC.HsToCore.Pmc.Solver.GenerateInhabitingPatternsMode
+ GHC.HsToCore.Pmc.Solver.Types: instance GHC.Internal.Classes.Eq GHC.HsToCore.Pmc.Solver.Types.BotInfo
+ GHC.HsToCore.Pmc.Solver.Types: instance GHC.Internal.Classes.Eq GHC.HsToCore.Pmc.Solver.Types.PmAltCon
+ GHC.HsToCore.Pmc.Solver.Types: instance GHC.Internal.Classes.Eq GHC.HsToCore.Pmc.Solver.Types.PmEquality
+ GHC.HsToCore.Pmc.Solver.Types: instance GHC.Internal.Classes.Eq GHC.HsToCore.Pmc.Solver.Types.PmLit
+ GHC.HsToCore.Pmc.Types: instance GHC.Internal.Classes.Eq GHC.HsToCore.Pmc.Types.Precision
+ GHC.HsToCore.Ticks: instance GHC.HsToCore.Ticks.CollectBinders (GHC.Parser.Annotation.LocatedA (Language.Haskell.Syntax.Pat.Pat GHC.Hs.Extension.GhcTc))
+ GHC.HsToCore.Ticks: instance GHC.HsToCore.Ticks.CollectBinders (Language.Haskell.Syntax.Binds.HsLocalBinds GHC.Hs.Extension.GhcTc)
+ GHC.HsToCore.Ticks: instance GHC.HsToCore.Ticks.CollectBinders [GHC.Parser.Annotation.LocatedA (Language.Haskell.Syntax.Expr.Stmt GHC.Hs.Extension.GhcTc (GHC.Parser.Annotation.LocatedA (Language.Haskell.Syntax.Expr.HsCmd GHC.Hs.Extension.GhcTc)))]
+ GHC.HsToCore.Ticks: instance GHC.HsToCore.Ticks.CollectBinders [GHC.Parser.Annotation.LocatedA (Language.Haskell.Syntax.Expr.Stmt GHC.Hs.Extension.GhcTc (GHC.Parser.Annotation.LocatedA (Language.Haskell.Syntax.Expr.HsExpr GHC.Hs.Extension.GhcTc)))]
+ GHC.HsToCore.Ticks: instance GHC.HsToCore.Ticks.CollectBinders [GHC.Parser.Annotation.LocatedA (Language.Haskell.Syntax.Pat.Pat GHC.Hs.Extension.GhcTc)]
+ GHC.HsToCore.Ticks: instance GHC.HsToCore.Ticks.CollectFldBinders (GHC.Hs.Expr.ApplicativeArg GHC.Hs.Extension.GhcTc)
+ GHC.HsToCore.Ticks: instance GHC.HsToCore.Ticks.CollectFldBinders (Language.Haskell.Syntax.Binds.HsBind GHC.Hs.Extension.GhcTc)
+ GHC.HsToCore.Ticks: instance GHC.HsToCore.Ticks.CollectFldBinders (Language.Haskell.Syntax.Binds.HsLocalBinds GHC.Hs.Extension.GhcTc)
+ GHC.HsToCore.Ticks: instance GHC.HsToCore.Ticks.CollectFldBinders (Language.Haskell.Syntax.Binds.HsValBinds GHC.Hs.Extension.GhcTc)
+ GHC.HsToCore.Ticks: instance GHC.HsToCore.Ticks.CollectFldBinders (Language.Haskell.Syntax.Expr.Stmt GHC.Hs.Extension.GhcTc e)
+ GHC.HsToCore.Ticks: instance GHC.HsToCore.Ticks.CollectFldBinders (Language.Haskell.Syntax.Pat.Pat GHC.Hs.Extension.GhcTc)
+ GHC.HsToCore.Ticks: instance GHC.HsToCore.Ticks.CollectFldBinders GHC.Hs.Pat.XXPatGhcTc
+ GHC.HsToCore.Ticks: instance GHC.HsToCore.Ticks.CollectFldBinders a => GHC.HsToCore.Ticks.CollectFldBinders [a]
+ GHC.HsToCore.Ticks: instance GHC.HsToCore.Ticks.CollectFldBinders e => GHC.HsToCore.Ticks.CollectFldBinders (GHC.Types.SrcLoc.GenLocated l e)
+ GHC.HsToCore.Ticks: instance GHC.HsToCore.Ticks.CollectFldBinders r => GHC.HsToCore.Ticks.CollectFldBinders (Language.Haskell.Syntax.Pat.HsFieldBind l r)
+ GHC.HsToCore.Ticks: instance GHC.Internal.Classes.Eq GHC.HsToCore.Ticks.TickDensity
+ GHC.HsToCore.Ticks: instance GHC.Internal.Classes.Eq GHC.HsToCore.Ticks.TickishType
+ GHC.Iface.Binary: instance GHC.Internal.Classes.Eq GHC.Iface.Binary.CheckHiWay
+ GHC.Iface.Binary: instance GHC.Internal.Classes.Eq GHC.Iface.Binary.CompressionIFace
+ GHC.Iface.Binary: instance GHC.Internal.Classes.Ord GHC.Iface.Binary.CompressionIFace
+ GHC.Iface.Env: trace_hi_diffs_io :: Logger -> IO SDoc -> IO ()
+ GHC.Iface.Errors.Types: instance GHC.Internal.Classes.Eq GHC.Iface.Errors.Types.BuildingCabalPackage
+ GHC.Iface.Ext.Ast: instance (GHC.Iface.Ext.Ast.HiePass p, GHC.Internal.Data.Data.Data (GHC.Hs.Extension.IdGhcP p)) => GHC.Iface.Ext.Ast.ToHie (GHC.Types.SrcLoc.GenLocated GHC.Parser.Annotation.SrcSpanAnnL (Language.Haskell.Syntax.BooleanFormula.BooleanFormula (GHC.Hs.Extension.GhcPass p)))
+ GHC.Iface.Ext.Ast: instance (GHC.Iface.Ext.Ast.ToHie arg, GHC.Iface.Ext.Ast.ToHie rec) => GHC.Iface.Ext.Ast.ToHie (Language.Haskell.Syntax.Type.HsConDetails arg rec)
+ GHC.Iface.Ext.Ast: instance GHC.Iface.Ext.Ast.HiePass p => GHC.Iface.Ext.Ast.ToHie (GHC.Parser.Annotation.LocatedA (Language.Haskell.Syntax.Expr.HsTypedSplice (GHC.Hs.Extension.GhcPass p)))
+ GHC.Iface.Ext.Ast: instance GHC.Iface.Ext.Ast.HiePass pass => GHC.Iface.Ext.Ast.ToHie (Language.Haskell.Syntax.Expr.HsUntypedSplice (GHC.Hs.Extension.GhcPass pass))
+ GHC.Iface.Ext.Ast: instance GHC.Iface.Ext.Ast.ToHie (GHC.Iface.Ext.Ast.Context (GHC.Types.SrcLoc.Located (GHC.Types.Name.Reader.WithUserRdr GHC.Types.Name.Name)))
+ GHC.Iface.Ext.Ast: instance GHC.Iface.Ext.Ast.ToHie (GHC.Iface.Ext.Ast.RScoped (GHC.Parser.Annotation.LocatedAn GHC.Parser.Annotation.NoEpAnns (Language.Haskell.Syntax.Binds.RuleBndr GHC.Hs.Extension.GhcRn)))
+ GHC.Iface.Ext.Ast: instance GHC.Iface.Ext.Ast.ToHie (GHC.Parser.Annotation.LocatedA (Language.Haskell.Syntax.Type.HsConDeclRecField GHC.Hs.Extension.GhcRn))
+ GHC.Iface.Ext.Ast: instance GHC.Iface.Ext.Ast.ToHie (GHC.Parser.Annotation.LocatedL [GHC.Parser.Annotation.LocatedA (Language.Haskell.Syntax.Type.HsConDeclRecField GHC.Hs.Extension.GhcRn)])
+ GHC.Iface.Ext.Ast: instance GHC.Iface.Ext.Ast.ToHie (Language.Haskell.Syntax.Type.HsConDeclField GHC.Hs.Extension.GhcRn)
+ GHC.Iface.Ext.Ast: instance GHC.Iface.Ext.Ast.ToHie a => GHC.Iface.Ext.Ast.ToHie (GHC.Types.Name.Reader.WithUserRdr a)
+ GHC.Iface.Ext.Types: instance GHC.Internal.Classes.Eq GHC.Iface.Ext.Types.BindType
+ GHC.Iface.Ext.Types: instance GHC.Internal.Classes.Eq GHC.Iface.Ext.Types.ContextInfo
+ GHC.Iface.Ext.Types: instance GHC.Internal.Classes.Eq GHC.Iface.Ext.Types.DeclType
+ GHC.Iface.Ext.Types: instance GHC.Internal.Classes.Eq GHC.Iface.Ext.Types.EntityInfo
+ GHC.Iface.Ext.Types: instance GHC.Internal.Classes.Eq GHC.Iface.Ext.Types.EvBindDeps
+ GHC.Iface.Ext.Types: instance GHC.Internal.Classes.Eq GHC.Iface.Ext.Types.EvVarSource
+ GHC.Iface.Ext.Types: instance GHC.Internal.Classes.Eq GHC.Iface.Ext.Types.HieName
+ GHC.Iface.Ext.Types: instance GHC.Internal.Classes.Eq GHC.Iface.Ext.Types.HieTypeFix
+ GHC.Iface.Ext.Types: instance GHC.Internal.Classes.Eq GHC.Iface.Ext.Types.IEType
+ GHC.Iface.Ext.Types: instance GHC.Internal.Classes.Eq GHC.Iface.Ext.Types.NodeAnnotation
+ GHC.Iface.Ext.Types: instance GHC.Internal.Classes.Eq GHC.Iface.Ext.Types.NodeOrigin
+ GHC.Iface.Ext.Types: instance GHC.Internal.Classes.Eq GHC.Iface.Ext.Types.RecFieldContext
+ GHC.Iface.Ext.Types: instance GHC.Internal.Classes.Eq GHC.Iface.Ext.Types.Scope
+ GHC.Iface.Ext.Types: instance GHC.Internal.Classes.Eq GHC.Iface.Ext.Types.TyVarScope
+ GHC.Iface.Ext.Types: instance GHC.Internal.Classes.Eq a => GHC.Internal.Classes.Eq (GHC.Iface.Ext.Types.HieArgs a)
+ GHC.Iface.Ext.Types: instance GHC.Internal.Classes.Eq a => GHC.Internal.Classes.Eq (GHC.Iface.Ext.Types.HieType a)
+ GHC.Iface.Ext.Types: instance GHC.Internal.Classes.Eq a => GHC.Internal.Classes.Eq (GHC.Iface.Ext.Types.IdentifierDetails a)
+ GHC.Iface.Ext.Types: instance GHC.Internal.Classes.Ord GHC.Iface.Ext.Types.BindType
+ GHC.Iface.Ext.Types: instance GHC.Internal.Classes.Ord GHC.Iface.Ext.Types.ContextInfo
+ GHC.Iface.Ext.Types: instance GHC.Internal.Classes.Ord GHC.Iface.Ext.Types.DeclType
+ GHC.Iface.Ext.Types: instance GHC.Internal.Classes.Ord GHC.Iface.Ext.Types.EntityInfo
+ GHC.Iface.Ext.Types: instance GHC.Internal.Classes.Ord GHC.Iface.Ext.Types.EvBindDeps
+ GHC.Iface.Ext.Types: instance GHC.Internal.Classes.Ord GHC.Iface.Ext.Types.EvVarSource
+ GHC.Iface.Ext.Types: instance GHC.Internal.Classes.Ord GHC.Iface.Ext.Types.HieName
+ GHC.Iface.Ext.Types: instance GHC.Internal.Classes.Ord GHC.Iface.Ext.Types.IEType
+ GHC.Iface.Ext.Types: instance GHC.Internal.Classes.Ord GHC.Iface.Ext.Types.NodeAnnotation
+ GHC.Iface.Ext.Types: instance GHC.Internal.Classes.Ord GHC.Iface.Ext.Types.NodeOrigin
+ GHC.Iface.Ext.Types: instance GHC.Internal.Classes.Ord GHC.Iface.Ext.Types.RecFieldContext
+ GHC.Iface.Ext.Types: instance GHC.Internal.Classes.Ord GHC.Iface.Ext.Types.Scope
+ GHC.Iface.Ext.Types: instance GHC.Internal.Classes.Ord GHC.Iface.Ext.Types.TyVarScope
+ GHC.Iface.Ext.Utils: instance GHC.Internal.Classes.Eq a => GHC.Internal.Classes.Eq (GHC.Iface.Ext.Utils.EvidenceInfo a)
+ GHC.Iface.Ext.Utils: instance GHC.Internal.Classes.Ord a => GHC.Internal.Classes.Ord (GHC.Iface.Ext.Utils.EvidenceInfo a)
+ GHC.Iface.Flags: IfaceCppOptions :: [FilePath] -> [String] -> ([String], Fingerprint) -> IfaceCppOptions
+ GHC.Iface.Flags: IfaceDynFlags :: Maybe (Maybe String) -> IfaceTrustInfo -> Maybe IfaceLanguage -> [IfaceExtension] -> IfaceCppOptions -> IfaceCppOptions -> IfaceCppOptions -> [String] -> Maybe IfaceProfAuto -> [IfaceGeneralFlag] -> [IfaceGeneralFlag] -> Bool -> Int -> [CallerCcFilter] -> IfaceDynFlags
+ GHC.Iface.Flags: IfaceExtension :: Extension -> IfaceExtension
+ GHC.Iface.Flags: IfaceGeneralFlag :: GeneralFlag -> IfaceGeneralFlag
+ GHC.Iface.Flags: IfaceLanguage :: Language -> IfaceLanguage
+ GHC.Iface.Flags: IfaceProfAuto :: ProfAuto -> IfaceProfAuto
+ GHC.Iface.Flags: [ifaceCallerCCFilters] :: IfaceDynFlags -> [CallerCcFilter]
+ GHC.Iface.Flags: [ifaceCmmOptions] :: IfaceDynFlags -> IfaceCppOptions
+ GHC.Iface.Flags: [ifaceCodeGen] :: IfaceDynFlags -> [IfaceGeneralFlag]
+ GHC.Iface.Flags: [ifaceCppIncludes] :: IfaceCppOptions -> [FilePath]
+ GHC.Iface.Flags: [ifaceCppOptions] :: IfaceDynFlags -> IfaceCppOptions
+ GHC.Iface.Flags: [ifaceCppOpts] :: IfaceCppOptions -> [String]
+ GHC.Iface.Flags: [ifaceCppSig] :: IfaceCppOptions -> ([String], Fingerprint)
+ GHC.Iface.Flags: [ifaceDebugLevel] :: IfaceDynFlags -> Int
+ GHC.Iface.Flags: [ifaceExts] :: IfaceDynFlags -> [IfaceExtension]
+ GHC.Iface.Flags: [ifaceFatIface] :: IfaceDynFlags -> Bool
+ GHC.Iface.Flags: [ifaceJsOptions] :: IfaceDynFlags -> IfaceCppOptions
+ GHC.Iface.Flags: [ifaceLang] :: IfaceDynFlags -> Maybe IfaceLanguage
+ GHC.Iface.Flags: [ifaceMainIs] :: IfaceDynFlags -> Maybe (Maybe String)
+ GHC.Iface.Flags: [ifacePaths] :: IfaceDynFlags -> [String]
+ GHC.Iface.Flags: [ifaceProf] :: IfaceDynFlags -> Maybe IfaceProfAuto
+ GHC.Iface.Flags: [ifaceSafeMode] :: IfaceDynFlags -> IfaceTrustInfo
+ GHC.Iface.Flags: [ifaceTicky] :: IfaceDynFlags -> [IfaceGeneralFlag]
+ GHC.Iface.Flags: data IfaceCppOptions
+ GHC.Iface.Flags: data IfaceDynFlags
+ GHC.Iface.Flags: instance Control.DeepSeq.NFData GHC.Iface.Flags.IfaceCppOptions
+ GHC.Iface.Flags: instance Control.DeepSeq.NFData GHC.Iface.Flags.IfaceDynFlags
+ GHC.Iface.Flags: instance Control.DeepSeq.NFData GHC.Iface.Flags.IfaceExtension
+ GHC.Iface.Flags: instance Control.DeepSeq.NFData GHC.Iface.Flags.IfaceGeneralFlag
+ GHC.Iface.Flags: instance Control.DeepSeq.NFData GHC.Iface.Flags.IfaceLanguage
+ GHC.Iface.Flags: instance Control.DeepSeq.NFData GHC.Iface.Flags.IfaceProfAuto
+ GHC.Iface.Flags: instance GHC.Utils.Binary.Binary GHC.Iface.Flags.IfaceCppOptions
+ GHC.Iface.Flags: instance GHC.Utils.Binary.Binary GHC.Iface.Flags.IfaceDynFlags
+ GHC.Iface.Flags: instance GHC.Utils.Binary.Binary GHC.Iface.Flags.IfaceExtension
+ GHC.Iface.Flags: instance GHC.Utils.Binary.Binary GHC.Iface.Flags.IfaceGeneralFlag
+ GHC.Iface.Flags: instance GHC.Utils.Binary.Binary GHC.Iface.Flags.IfaceLanguage
+ GHC.Iface.Flags: instance GHC.Utils.Binary.Binary GHC.Iface.Flags.IfaceProfAuto
+ GHC.Iface.Flags: instance GHC.Utils.Outputable.Outputable GHC.Iface.Flags.IfaceCppOptions
+ GHC.Iface.Flags: instance GHC.Utils.Outputable.Outputable GHC.Iface.Flags.IfaceExtension
+ GHC.Iface.Flags: instance GHC.Utils.Outputable.Outputable GHC.Iface.Flags.IfaceGeneralFlag
+ GHC.Iface.Flags: instance GHC.Utils.Outputable.Outputable GHC.Iface.Flags.IfaceLanguage
+ GHC.Iface.Flags: instance GHC.Utils.Outputable.Outputable GHC.Iface.Flags.IfaceProfAuto
+ GHC.Iface.Flags: missingExtraFlagInfo :: SDoc
+ GHC.Iface.Flags: newtype IfaceExtension
+ GHC.Iface.Flags: newtype IfaceGeneralFlag
+ GHC.Iface.Flags: newtype IfaceLanguage
+ GHC.Iface.Flags: newtype IfaceProfAuto
+ GHC.Iface.Flags: pprIfaceDynFlags :: IfaceDynFlags -> SDoc
+ GHC.Iface.Load: getGhcPrimIface :: Hooks -> ModIface
+ GHC.Iface.Make: mkRecompUsageInfo :: HscEnv -> TcGblEnv -> IO (Maybe [Usage])
+ GHC.Iface.Recomp: LinkFlagsChanged :: RecompReason
+ GHC.Iface.Recomp: NoSelfRecompInfo :: RecompReason
+ GHC.Iface.Recomp: instance GHC.Internal.Classes.Eq GHC.Iface.Recomp.CompileReason
+ GHC.Iface.Recomp: instance GHC.Internal.Classes.Eq GHC.Iface.Recomp.RecompReason
+ GHC.Iface.Recomp: instance GHC.Internal.Classes.Eq GHC.Iface.Recomp.RecompileRequired
+ GHC.Iface.Recomp: mkSelfRecomp :: HscEnv -> Module -> Fingerprint -> [Usage] -> IO IfaceSelfRecomp
+ GHC.Iface.Recomp.Types: IfaceDynFlags :: Maybe (Maybe String) -> IfaceTrustInfo -> Maybe IfaceLanguage -> [IfaceExtension] -> IfaceCppOptions -> IfaceCppOptions -> IfaceCppOptions -> [String] -> Maybe IfaceProfAuto -> [IfaceGeneralFlag] -> [IfaceGeneralFlag] -> Bool -> Int -> [CallerCcFilter] -> IfaceDynFlags
+ GHC.Iface.Recomp.Types: IfaceSelfRecomp :: Fingerprint -> [Usage] -> FingerprintWithValue IfaceDynFlags -> Fingerprint -> Fingerprint -> Fingerprint -> IfaceSelfRecomp
+ GHC.Iface.Recomp.Types: [ifaceCallerCCFilters] :: IfaceDynFlags -> [CallerCcFilter]
+ GHC.Iface.Recomp.Types: [ifaceCmmOptions] :: IfaceDynFlags -> IfaceCppOptions
+ GHC.Iface.Recomp.Types: [ifaceCodeGen] :: IfaceDynFlags -> [IfaceGeneralFlag]
+ GHC.Iface.Recomp.Types: [ifaceCppOptions] :: IfaceDynFlags -> IfaceCppOptions
+ GHC.Iface.Recomp.Types: [ifaceDebugLevel] :: IfaceDynFlags -> Int
+ GHC.Iface.Recomp.Types: [ifaceExts] :: IfaceDynFlags -> [IfaceExtension]
+ GHC.Iface.Recomp.Types: [ifaceFatIface] :: IfaceDynFlags -> Bool
+ GHC.Iface.Recomp.Types: [ifaceJsOptions] :: IfaceDynFlags -> IfaceCppOptions
+ GHC.Iface.Recomp.Types: [ifaceLang] :: IfaceDynFlags -> Maybe IfaceLanguage
+ GHC.Iface.Recomp.Types: [ifaceMainIs] :: IfaceDynFlags -> Maybe (Maybe String)
+ GHC.Iface.Recomp.Types: [ifacePaths] :: IfaceDynFlags -> [String]
+ GHC.Iface.Recomp.Types: [ifaceProf] :: IfaceDynFlags -> Maybe IfaceProfAuto
+ GHC.Iface.Recomp.Types: [ifaceSafeMode] :: IfaceDynFlags -> IfaceTrustInfo
+ GHC.Iface.Recomp.Types: [ifaceTicky] :: IfaceDynFlags -> [IfaceGeneralFlag]
+ GHC.Iface.Recomp.Types: [mi_sr_flag_hash] :: IfaceSelfRecomp -> FingerprintWithValue IfaceDynFlags
+ GHC.Iface.Recomp.Types: [mi_sr_hpc_hash] :: IfaceSelfRecomp -> Fingerprint
+ GHC.Iface.Recomp.Types: [mi_sr_opt_hash] :: IfaceSelfRecomp -> Fingerprint
+ GHC.Iface.Recomp.Types: [mi_sr_plugin_hash] :: IfaceSelfRecomp -> Fingerprint
+ GHC.Iface.Recomp.Types: [mi_sr_src_hash] :: IfaceSelfRecomp -> Fingerprint
+ GHC.Iface.Recomp.Types: [mi_sr_usages] :: IfaceSelfRecomp -> [Usage]
+ GHC.Iface.Recomp.Types: data IfaceDynFlags
+ GHC.Iface.Recomp.Types: data IfaceSelfRecomp
+ GHC.Iface.Recomp.Types: instance Control.DeepSeq.NFData GHC.Iface.Recomp.Types.IfaceSelfRecomp
+ GHC.Iface.Recomp.Types: instance GHC.Utils.Binary.Binary GHC.Iface.Recomp.Types.IfaceSelfRecomp
+ GHC.Iface.Recomp.Types: instance GHC.Utils.Outputable.Outputable GHC.Iface.Recomp.Types.IfaceSelfRecomp
+ GHC.Iface.Recomp.Types: missingExtraFlagInfo :: SDoc
+ GHC.Iface.Recomp.Types: pprIfaceDynFlags :: IfaceDynFlags -> SDoc
+ GHC.Iface.Syntax: [ifUnary] :: IfaceClassBody -> Bool
+ GHC.Iface.Syntax: [iil_avails] :: ImpIfaceList -> DetOrdAvails
+ GHC.Iface.Syntax: [iil_non_explicit_parents] :: ImpIfaceList -> [Name]
+ GHC.Iface.Syntax: ifImpModule :: IfaceImport -> Module
+ GHC.Iface.Syntax: instance (GHC.Internal.Classes.Eq b, GHC.Internal.Classes.Eq r) => GHC.Internal.Classes.Eq (GHC.Iface.Syntax.IfaceBindingX r b)
+ GHC.Iface.Syntax: instance (GHC.Internal.Classes.Ord b, GHC.Internal.Classes.Ord r) => GHC.Internal.Classes.Ord (GHC.Iface.Syntax.IfaceBindingX r b)
+ GHC.Iface.Syntax: instance Control.DeepSeq.NFData GHC.Iface.Syntax.IfaceLFInfo
+ GHC.Iface.Syntax: instance GHC.Internal.Classes.Eq GHC.Iface.Syntax.IfaceBooleanFormula
+ GHC.Iface.Syntax: instance GHC.Utils.Binary.Binary GHC.Iface.Syntax.IfaceImport
+ GHC.Iface.Syntax: instance GHC.Utils.Binary.Binary GHC.Iface.Syntax.ImpIfaceList
+ GHC.Iface.Syntax: type IfaceExport = AvailInfo
+ GHC.Iface.Tidy: instance GHC.Internal.Classes.Eq GHC.Iface.Tidy.UnfoldingExposure
+ GHC.Iface.Tidy: instance GHC.Internal.Classes.Ord GHC.Iface.Tidy.UnfoldingExposure
+ GHC.Iface.Type: MkPrintArityInvisibles :: Bool -> PrintArityInvisibles
+ GHC.Iface.Type: instance Control.DeepSeq.NFData (GHC.Types.Basic.DefMethSpec GHC.Iface.Type.IfaceType)
+ GHC.Iface.Type: instance GHC.Internal.Classes.Eq GHC.Iface.Type.IfLclName
+ GHC.Iface.Type: instance GHC.Internal.Classes.Eq GHC.Iface.Type.IfaceAppArgs
+ GHC.Iface.Type: instance GHC.Internal.Classes.Eq GHC.Iface.Type.IfaceAxiomRule
+ GHC.Iface.Type: instance GHC.Internal.Classes.Eq GHC.Iface.Type.IfaceBndr
+ GHC.Iface.Type: instance GHC.Internal.Classes.Eq GHC.Iface.Type.IfaceCoercion
+ GHC.Iface.Type: instance GHC.Internal.Classes.Eq GHC.Iface.Type.IfaceMCoercion
+ GHC.Iface.Type: instance GHC.Internal.Classes.Eq GHC.Iface.Type.IfaceTyCon
+ GHC.Iface.Type: instance GHC.Internal.Classes.Eq GHC.Iface.Type.IfaceTyConInfo
+ GHC.Iface.Type: instance GHC.Internal.Classes.Eq GHC.Iface.Type.IfaceTyConSort
+ GHC.Iface.Type: instance GHC.Internal.Classes.Eq GHC.Iface.Type.IfaceTyLit
+ GHC.Iface.Type: instance GHC.Internal.Classes.Eq GHC.Iface.Type.IfaceType
+ GHC.Iface.Type: instance GHC.Internal.Classes.Eq GHC.Iface.Type.TupleOrSum
+ GHC.Iface.Type: instance GHC.Internal.Classes.Ord GHC.Iface.Type.IfLclName
+ GHC.Iface.Type: instance GHC.Internal.Classes.Ord GHC.Iface.Type.IfaceAppArgs
+ GHC.Iface.Type: instance GHC.Internal.Classes.Ord GHC.Iface.Type.IfaceAxiomRule
+ GHC.Iface.Type: instance GHC.Internal.Classes.Ord GHC.Iface.Type.IfaceBndr
+ GHC.Iface.Type: instance GHC.Internal.Classes.Ord GHC.Iface.Type.IfaceCoercion
+ GHC.Iface.Type: instance GHC.Internal.Classes.Ord GHC.Iface.Type.IfaceMCoercion
+ GHC.Iface.Type: instance GHC.Internal.Classes.Ord GHC.Iface.Type.IfaceTyCon
+ GHC.Iface.Type: instance GHC.Internal.Classes.Ord GHC.Iface.Type.IfaceTyConInfo
+ GHC.Iface.Type: instance GHC.Internal.Classes.Ord GHC.Iface.Type.IfaceTyConSort
+ GHC.Iface.Type: instance GHC.Internal.Classes.Ord GHC.Iface.Type.IfaceTyLit
+ GHC.Iface.Type: instance GHC.Internal.Classes.Ord GHC.Iface.Type.IfaceType
+ GHC.Iface.Type: newtype PrintArityInvisibles
+ GHC.Iface.Type: visibleTypeVarOccurencies :: IfaceType -> Set IfLclName
+ GHC.JS.Ident: instance GHC.Internal.Classes.Eq GHC.JS.Ident.Ident
+ GHC.JS.JStg.Syntax: instance GHC.Internal.Classes.Eq GHC.JS.JStg.Syntax.AOp
+ GHC.JS.JStg.Syntax: instance GHC.Internal.Classes.Eq GHC.JS.JStg.Syntax.JStgExpr
+ GHC.JS.JStg.Syntax: instance GHC.Internal.Classes.Eq GHC.JS.JStg.Syntax.JStgStat
+ GHC.JS.JStg.Syntax: instance GHC.Internal.Classes.Eq GHC.JS.JStg.Syntax.JVal
+ GHC.JS.JStg.Syntax: instance GHC.Internal.Classes.Eq GHC.JS.JStg.Syntax.Op
+ GHC.JS.JStg.Syntax: instance GHC.Internal.Classes.Eq GHC.JS.JStg.Syntax.UOp
+ GHC.JS.JStg.Syntax: instance GHC.Internal.Classes.Ord GHC.JS.JStg.Syntax.AOp
+ GHC.JS.JStg.Syntax: instance GHC.Internal.Classes.Ord GHC.JS.JStg.Syntax.Op
+ GHC.JS.JStg.Syntax: instance GHC.Internal.Classes.Ord GHC.JS.JStg.Syntax.UOp
+ GHC.JS.Make: instance (GHC.JS.Make.JVarMagic a, GHC.JS.Make.ToJExpr a) => GHC.JS.Make.JSArgument (GHC.Internal.Tuple.Solo a)
+ GHC.JS.Make: instance GHC.JS.Make.ToJExpr GHC.Internal.Bignum.Integer.Integer
+ GHC.JS.Make: instance GHC.JS.Make.ToJExpr GHC.Internal.Types.Bool
+ GHC.JS.Make: instance GHC.JS.Make.ToJExpr GHC.Internal.Types.Char
+ GHC.JS.Make: instance GHC.JS.Make.ToJExpr GHC.Internal.Types.Double
+ GHC.JS.Make: instance GHC.JS.Make.ToJExpr GHC.Internal.Types.Int
+ GHC.JS.Opt.Simple: instance GHC.Internal.Classes.Eq GHC.JS.Opt.Simple.Multiplicity
+ GHC.JS.Opt.Simple: instance GHC.Internal.Classes.Eq GHC.JS.Opt.Simple.VarDecl
+ GHC.JS.Opt.Simple: instance GHC.Internal.Classes.Ord GHC.JS.Opt.Simple.Multiplicity
+ GHC.JS.Opt.Simple: instance GHC.Internal.Classes.Ord GHC.JS.Opt.Simple.VarDecl
+ GHC.JS.Syntax: instance GHC.Internal.Classes.Eq GHC.JS.Syntax.AOp
+ GHC.JS.Syntax: instance GHC.Internal.Classes.Eq GHC.JS.Syntax.JExpr
+ GHC.JS.Syntax: instance GHC.Internal.Classes.Eq GHC.JS.Syntax.JStat
+ GHC.JS.Syntax: instance GHC.Internal.Classes.Eq GHC.JS.Syntax.JVal
+ GHC.JS.Syntax: instance GHC.Internal.Classes.Eq GHC.JS.Syntax.Op
+ GHC.JS.Syntax: instance GHC.Internal.Classes.Eq GHC.JS.Syntax.UOp
+ GHC.JS.Syntax: instance GHC.Internal.Classes.Ord GHC.JS.Syntax.AOp
+ GHC.JS.Syntax: instance GHC.Internal.Classes.Ord GHC.JS.Syntax.Op
+ GHC.JS.Syntax: instance GHC.Internal.Classes.Ord GHC.JS.Syntax.UOp
+ GHC.Linker.Deps: [ldGetDependencies] :: LinkDepsOpts -> [Module] -> IO ([Module], UniqDSet UnitId)
+ GHC.Linker.Loader: [linked_breaks] :: LoaderState -> LinkedBreaks
+ GHC.Linker.Loader: allocateBreakArrays :: Interp -> ModuleEnv (ForeignRef BreakArray) -> [InternalModBreaks] -> IO (ModuleEnv (ForeignRef BreakArray))
+ GHC.Linker.Types: LinkedBreaks :: ModuleEnv (ForeignRef BreakArray) -> ModuleEnv (Array BreakTickIndex (RemotePtr CostCentre)) -> LinkedBreaks
+ GHC.Linker.Types: [breakarray_env] :: LinkedBreaks -> ModuleEnv (ForeignRef BreakArray)
+ GHC.Linker.Types: [ccs_env] :: LinkedBreaks -> ModuleEnv (Array BreakTickIndex (RemotePtr CostCentre))
+ GHC.Linker.Types: [linked_breaks] :: LoaderState -> LinkedBreaks
+ GHC.Linker.Types: data LinkedBreaks
+ GHC.Linker.Types: filterLinkedBreaks :: (Module -> Bool) -> LinkedBreaks -> LinkedBreaks
+ GHC.Llvm.MetaData: instance GHC.Internal.Classes.Eq GHC.Llvm.MetaData.MetaAnnot
+ GHC.Llvm.MetaData: instance GHC.Internal.Classes.Eq GHC.Llvm.MetaData.MetaExpr
+ GHC.Llvm.MetaData: instance GHC.Internal.Classes.Eq GHC.Llvm.MetaData.MetaId
+ GHC.Llvm.MetaData: instance GHC.Internal.Classes.Ord GHC.Llvm.MetaData.MetaId
+ GHC.Llvm.Syntax: instance GHC.Internal.Classes.Eq GHC.Llvm.Syntax.LlvmAtomicOp
+ GHC.Llvm.Syntax: instance GHC.Internal.Classes.Eq GHC.Llvm.Syntax.LlvmExpression
+ GHC.Llvm.Syntax: instance GHC.Internal.Classes.Eq GHC.Llvm.Syntax.LlvmStatement
+ GHC.Llvm.Syntax: instance GHC.Internal.Classes.Eq GHC.Llvm.Syntax.LlvmSyncOrdering
+ GHC.Llvm.Types: instance GHC.Internal.Classes.Eq GHC.Llvm.Types.LMConst
+ GHC.Llvm.Types: instance GHC.Internal.Classes.Eq GHC.Llvm.Types.LlvmCallConvention
+ GHC.Llvm.Types: instance GHC.Internal.Classes.Eq GHC.Llvm.Types.LlvmCallType
+ GHC.Llvm.Types: instance GHC.Internal.Classes.Eq GHC.Llvm.Types.LlvmCastOp
+ GHC.Llvm.Types: instance GHC.Internal.Classes.Eq GHC.Llvm.Types.LlvmCmpOp
+ GHC.Llvm.Types: instance GHC.Internal.Classes.Eq GHC.Llvm.Types.LlvmFuncAttr
+ GHC.Llvm.Types: instance GHC.Internal.Classes.Eq GHC.Llvm.Types.LlvmFunctionDecl
+ GHC.Llvm.Types: instance GHC.Internal.Classes.Eq GHC.Llvm.Types.LlvmLinkageType
+ GHC.Llvm.Types: instance GHC.Internal.Classes.Eq GHC.Llvm.Types.LlvmLit
+ GHC.Llvm.Types: instance GHC.Internal.Classes.Eq GHC.Llvm.Types.LlvmMachOp
+ GHC.Llvm.Types: instance GHC.Internal.Classes.Eq GHC.Llvm.Types.LlvmParamAttr
+ GHC.Llvm.Types: instance GHC.Internal.Classes.Eq GHC.Llvm.Types.LlvmParameterListType
+ GHC.Llvm.Types: instance GHC.Internal.Classes.Eq GHC.Llvm.Types.LlvmType
+ GHC.Llvm.Types: instance GHC.Internal.Classes.Eq GHC.Llvm.Types.LlvmVar
+ GHC.Parser.Annotation: getEpTokenBufSpan :: forall (tok :: Symbol). EpToken tok -> Maybe BufSpan
+ GHC.Parser.Annotation: instance GHC.Internal.Classes.Eq (GHC.Parser.Annotation.EpToken tok)
+ GHC.Parser.Annotation: instance GHC.Internal.Classes.Eq (GHC.Parser.Annotation.EpUniToken tok utok)
+ GHC.Parser.Annotation: instance GHC.Internal.Classes.Eq GHC.Parser.Annotation.AnnListBrackets
+ GHC.Parser.Annotation: instance GHC.Internal.Classes.Eq GHC.Parser.Annotation.AnnListItem
+ GHC.Parser.Annotation: instance GHC.Internal.Classes.Eq GHC.Parser.Annotation.AnnPragma
+ GHC.Parser.Annotation: instance GHC.Internal.Classes.Eq GHC.Parser.Annotation.BindTag
+ GHC.Parser.Annotation: instance GHC.Internal.Classes.Eq GHC.Parser.Annotation.DeclTag
+ GHC.Parser.Annotation: instance GHC.Internal.Classes.Eq GHC.Parser.Annotation.EpAnnComments
+ GHC.Parser.Annotation: instance GHC.Internal.Classes.Eq GHC.Parser.Annotation.EpaComment
+ GHC.Parser.Annotation: instance GHC.Internal.Classes.Eq GHC.Parser.Annotation.EpaCommentTok
+ GHC.Parser.Annotation: instance GHC.Internal.Classes.Eq GHC.Parser.Annotation.HasE
+ GHC.Parser.Annotation: instance GHC.Internal.Classes.Eq GHC.Parser.Annotation.IsUnicodeSyntax
+ GHC.Parser.Annotation: instance GHC.Internal.Classes.Eq GHC.Parser.Annotation.NameAdornment
+ GHC.Parser.Annotation: instance GHC.Internal.Classes.Eq GHC.Parser.Annotation.NameAnn
+ GHC.Parser.Annotation: instance GHC.Internal.Classes.Eq GHC.Parser.Annotation.NoEpAnns
+ GHC.Parser.Annotation: instance GHC.Internal.Classes.Eq GHC.Parser.Annotation.TrailingAnn
+ GHC.Parser.Annotation: instance GHC.Internal.Classes.Eq a => GHC.Internal.Classes.Eq (GHC.Parser.Annotation.AnnList a)
+ GHC.Parser.Annotation: instance GHC.Internal.Classes.Eq ann => GHC.Internal.Classes.Eq (GHC.Parser.Annotation.EpAnn ann)
+ GHC.Parser.Annotation: instance GHC.Internal.Classes.Eq tag => GHC.Internal.Classes.Eq (GHC.Parser.Annotation.AnnSortKey tag)
+ GHC.Parser.Annotation: instance GHC.Internal.Classes.Ord GHC.Parser.Annotation.BindTag
+ GHC.Parser.Annotation: instance GHC.Internal.Classes.Ord GHC.Parser.Annotation.DeclTag
+ GHC.Parser.Annotation: instance GHC.Internal.Classes.Ord GHC.Parser.Annotation.HasE
+ GHC.Parser.Annotation: instance GHC.Internal.Classes.Ord GHC.Parser.Annotation.IsUnicodeSyntax
+ GHC.Parser.Annotation: instance GHC.Internal.Classes.Ord GHC.Parser.Annotation.NoEpAnns
+ GHC.Parser.Annotation: instance GHC.Parser.Annotation.NoAnn GHC.Internal.Types.Bool
+ GHC.Parser.Errors.Types: PsErrSpecExprMultipleTypeAscription :: PsMessage
+ GHC.Parser.Errors.Types: PsErrSpliceOrQuoteTwice :: PsMessage
+ GHC.Parser.Errors.Types: PsWarnPatternNamespaceSpecifier :: Bool -> PsMessage
+ GHC.Parser.Errors.Types: PsWarnSpecMultipleTypeAscription :: PsMessage
+ GHC.Parser.Errors.Types: instance GHC.Internal.Classes.Eq GHC.Parser.Errors.Types.LexErr
+ GHC.Parser.Errors.Types: instance GHC.Internal.Classes.Eq GHC.Parser.Errors.Types.LexErrKind
+ GHC.Parser.Errors.Types: instance GHC.Internal.Classes.Eq GHC.Parser.Errors.Types.NumUnderscoreReason
+ GHC.Parser.Errors.Types: instance GHC.Internal.Classes.Eq GHC.Parser.Errors.Types.ParseContext
+ GHC.Parser.Errors.Types: instance GHC.Internal.Classes.Eq GHC.Parser.Errors.Types.PatIncompleteDoBlock
+ GHC.Parser.Errors.Types: instance GHC.Internal.Classes.Ord GHC.Parser.Errors.Types.LexErr
+ GHC.Parser.Errors.Types: instance GHC.Internal.Classes.Ord GHC.Parser.Errors.Types.LexErrKind
+ GHC.Parser.Errors.Types: instance GHC.Internal.Classes.Ord GHC.Parser.Errors.Types.NumUnderscoreReason
+ GHC.Parser.Lexer: ITquote :: Token
+ GHC.Parser.Lexer: ITsplice :: Token
+ GHC.Parser.Lexer: LevelImportsBit :: ExtBits
+ GHC.Parser.PostProcess: failSpliceOrQuoteTwice :: EpAnnLevel -> P ()
+ GHC.Parser.PostProcess: mkConDeclField :: HsMultAnn GhcPs -> LHsType GhcPs -> HsConDeclField GhcPs
+ GHC.Parser.PostProcess: mkDataImpExp :: EpToken "data" -> LocatedN RdrName -> P ImpExpQcSpec
+ GHC.Parser.PostProcess: mkMultField :: EpToken "%" -> LHsType GhcPs -> TokDcolon -> LHsType GhcPs -> HsConDeclField GhcPs
+ GHC.Parser.PostProcess: mkPlainImpExp :: LocatedN RdrName -> ImpExpQcSpec
+ GHC.Parser.PostProcess: mkSpecSig :: InlinePragma -> AnnSpecSig -> Maybe (RuleBndrs GhcPs) -> LHsExpr GhcPs -> Maybe (Located (TokDcolon, OrdList (LHsSigType GhcPs))) -> P (Sig GhcPs)
+ GHC.Parser.PostProcess: ruleBndrsOrDef :: Maybe (RuleBndrs GhcPs) -> RuleBndrs GhcPs
+ GHC.Parser.PostProcess: warnPatternNamespaceSpecifier :: MonadP m => SrcSpan -> m ()
+ GHC.Parser.PostProcess.Haddock: instance GHC.Parser.PostProcess.Haddock.HasHaddock (GHC.Parser.Annotation.LocatedA (Language.Haskell.Syntax.Type.HsConDeclRecField GHC.Hs.Extension.GhcPs))
+ GHC.Parser.PostProcess.Haddock: instance GHC.Parser.PostProcess.Haddock.HasHaddock (Language.Haskell.Syntax.Type.HsConDeclField GHC.Hs.Extension.GhcPs)
+ GHC.Parser.String: instance GHC.Internal.Classes.Eq GHC.Parser.String.StringLexError
+ GHC.Parser.String: instance GHC.Parser.String.HasChar (GHC.Internal.Types.Char, x)
+ GHC.Parser.String: instance GHC.Parser.String.HasChar GHC.Internal.Types.Char
+ GHC.Parser.Types: ExplicitDataNamespace :: EpToken "data" -> ExplicitNamespaceKeyword
+ GHC.Parser.Types: ExplicitTypeNamespace :: EpToken "type" -> ExplicitNamespaceKeyword
+ GHC.Parser.Types: data ExplicitNamespaceKeyword
+ GHC.Platform: SSSE3 :: SseVersion
+ GHC.Platform: [pc_SIZEOF_StgAnnFrame_NoHdr] :: PlatformConstants -> Int
+ GHC.Platform: instance GHC.Internal.Classes.Eq GHC.Platform.BmiVersion
+ GHC.Platform: instance GHC.Internal.Classes.Eq GHC.Platform.Platform
+ GHC.Platform: instance GHC.Internal.Classes.Eq GHC.Platform.PlatformWordSize
+ GHC.Platform: instance GHC.Internal.Classes.Eq GHC.Platform.SseVersion
+ GHC.Platform: instance GHC.Internal.Classes.Ord GHC.Platform.BmiVersion
+ GHC.Platform: instance GHC.Internal.Classes.Ord GHC.Platform.Platform
+ GHC.Platform: instance GHC.Internal.Classes.Ord GHC.Platform.PlatformWordSize
+ GHC.Platform: instance GHC.Internal.Classes.Ord GHC.Platform.SseVersion
+ GHC.Platform.Constants: [pc_SIZEOF_StgAnnFrame_NoHdr] :: PlatformConstants -> Int
+ GHC.Platform.Constants: instance GHC.Internal.Classes.Eq GHC.Platform.Constants.PlatformConstants
+ GHC.Platform.Constants: instance GHC.Internal.Classes.Ord GHC.Platform.Constants.PlatformConstants
+ GHC.Platform.LA64: activeStgRegs :: [GlobalReg]
+ GHC.Platform.LA64: callerSaves :: GlobalReg -> Bool
+ GHC.Platform.LA64: freeReg :: RegNo -> Bool
+ GHC.Platform.LA64: globalRegMaybe :: GlobalReg -> Maybe RealReg
+ GHC.Platform.LA64: haveRegBase :: Bool
+ GHC.Platform.Profile: instance GHC.Internal.Classes.Eq GHC.Platform.Profile.Profile
+ GHC.Platform.Profile: instance GHC.Internal.Classes.Ord GHC.Platform.Profile.Profile
+ GHC.Platform.Reg: instance GHC.Internal.Classes.Eq GHC.Platform.Reg.RealReg
+ GHC.Platform.Reg: instance GHC.Internal.Classes.Eq GHC.Platform.Reg.Reg
+ GHC.Platform.Reg: instance GHC.Internal.Classes.Eq GHC.Platform.Reg.VirtualReg
+ GHC.Platform.Reg: instance GHC.Internal.Classes.Ord GHC.Platform.Reg.RealReg
+ GHC.Platform.Reg: instance GHC.Internal.Classes.Ord GHC.Platform.Reg.Reg
+ GHC.Platform.Reg: instance GHC.Internal.Classes.Ord GHC.Platform.Reg.VirtualReg
+ GHC.Platform.Reg.Class: instance GHC.Internal.Classes.Eq GHC.Platform.Reg.Class.RegArch
+ GHC.Platform.Reg.Class: instance GHC.Internal.Classes.Eq GHC.Platform.Reg.Class.RegClass
+ GHC.Platform.Reg.Class: instance GHC.Internal.Classes.Ord GHC.Platform.Reg.Class.RegArch
+ GHC.Platform.Reg.Class: instance GHC.Internal.Classes.Ord GHC.Platform.Reg.Class.RegClass
+ GHC.Platform.Ways: instance GHC.Internal.Classes.Eq GHC.Platform.Ways.Way
+ GHC.Platform.Ways: instance GHC.Internal.Classes.Ord GHC.Platform.Ways.Way
+ GHC.Plugins: cloneBndrsM :: MonadUnique m => Subst -> [Var] -> m (Subst, [Var])
+ GHC.Plugins: cloneRecIdBndrsM :: MonadUnique m => Subst -> [Id] -> m (Subst, [Id])
+ GHC.Plugins: collectPiTyBinders :: Type -> [PiTyBinder]
+ GHC.Plugins: dataConWrapUnfolding_maybe :: Id -> Maybe CoreExpr
+ GHC.Plugins: demoteOccTcClsName :: OccName -> Maybe OccName
+ GHC.Plugins: hasCoercionHole :: Type -> Bool
+ GHC.Plugins: invisibleBndrCount :: Type -> Int
+ GHC.Plugins: isDataFamilyApp :: Type -> Bool
+ GHC.Plugins: isSatTyFamApp :: Type -> Maybe (TyCon, [Type])
+ GHC.Plugins: liftedTypeOrConstraintKind :: TypeOrConstraint -> Kind
+ GHC.Plugins: mkForAllVisCos :: HasDebugCallStack => [ForAllTyBinder] -> Coercion -> Coercion
+ GHC.Plugins: pprFullNameWithUnique :: Module -> Name -> SDoc
+ GHC.Plugins: pprName_userQual :: IsLine doc => Maybe ModuleName -> Name -> doc
+ GHC.Plugins: sizeOccEnv :: OccEnv a -> Int
+ GHC.Plugins: splitVisibleFunTy_maybe :: Type -> Maybe (Type, Type)
+ GHC.Plugins: substInScopeSet :: Subst -> InScopeSet
+ GHC.Plugins: updateLCSubst :: LiftingContext -> (Subst -> (Subst, a)) -> (LiftingContext, a)
+ GHC.Prelude.Basic: class Foldable t => Foldable1 (t :: Type -> Type)
+ GHC.Prelude.Basic: fold1 :: (Foldable1 t, Semigroup m) => t m -> m
+ GHC.Prelude.Basic: foldMap1 :: (Foldable1 t, Semigroup m) => (a -> m) -> t a -> m
+ GHC.Prelude.Basic: foldMap1' :: (Foldable1 t, Semigroup m) => (a -> m) -> t a -> m
+ GHC.Prelude.Basic: foldl1' :: Foldable1 t => (a -> a -> a) -> t a -> a
+ GHC.Prelude.Basic: foldlM1 :: (Foldable1 t, Monad m) => (a -> a -> m a) -> t a -> m a
+ GHC.Prelude.Basic: foldlMap1 :: Foldable1 t => (a -> b) -> (b -> a -> b) -> t a -> b
+ GHC.Prelude.Basic: foldlMap1' :: Foldable1 t => (a -> b) -> (b -> a -> b) -> t a -> b
+ GHC.Prelude.Basic: foldlMapM1 :: (Foldable1 t, Monad m) => (a -> m b) -> (b -> a -> m b) -> t a -> m b
+ GHC.Prelude.Basic: foldr1' :: Foldable1 t => (a -> a -> a) -> t a -> a
+ GHC.Prelude.Basic: foldrM1 :: (Foldable1 t, Monad m) => (a -> a -> m a) -> t a -> m a
+ GHC.Prelude.Basic: foldrMap1 :: Foldable1 t => (a -> b) -> (a -> b -> b) -> t a -> b
+ GHC.Prelude.Basic: foldrMap1' :: Foldable1 t => (a -> b) -> (a -> b -> b) -> t a -> b
+ GHC.Prelude.Basic: foldrMapM1 :: (Foldable1 t, Monad m) => (a -> m b) -> (a -> b -> m b) -> t a -> m b
+ GHC.Prelude.Basic: infix 4 ~
+ GHC.Prelude.Basic: infixl 1 >>
+ GHC.Prelude.Basic: infixl 4 <*
+ GHC.Prelude.Basic: infixl 5 .|.
+ GHC.Prelude.Basic: infixl 6 `xor`
+ GHC.Prelude.Basic: infixl 7 .&.
+ GHC.Prelude.Basic: infixl 8 `rotateR`
+ GHC.Prelude.Basic: infixl 9 !!
+ GHC.Prelude.Basic: infixr 0 `seq`
+ GHC.Prelude.Basic: infixr 1 =<<
+ GHC.Prelude.Basic: infixr 2 ||
+ GHC.Prelude.Basic: infixr 3 &&
+ GHC.Prelude.Basic: infixr 5 ++
+ GHC.Prelude.Basic: infixr 8 **
+ GHC.Prelude.Basic: infixr 9 .
+ GHC.Prelude.Basic: intercalate1 :: (Foldable1 t, Semigroup m) => m -> t m -> m
+ GHC.Prelude.Basic: maximumBy :: Foldable1 t => (a -> a -> Ordering) -> t a -> a
+ GHC.Prelude.Basic: minimumBy :: Foldable1 t => (a -> a -> Ordering) -> t a -> a
+ GHC.Prelude.Basic: strictGenericLength :: Num a => [x] -> a
+ GHC.Prelude.Basic: toNonEmpty :: Foldable1 t => t a -> NonEmpty a
+ GHC.Rename.Bind: bindRuleBndrs :: HsDocContext -> RuleBndrs GhcPs -> ([Name] -> RuleBndrs GhcRn -> RnM (a, FreeVars)) -> RnM (a, FreeVars)
+ GHC.Rename.HsType: bindHsForAllTelescopes :: HsDocContext -> [HsForAllTelescope GhcPs] -> ([HsForAllTelescope GhcRn] -> RnM (a, FreeVars)) -> RnM (a, FreeVars)
+ GHC.Rename.HsType: extractHsForAllTelescopes :: [HsForAllTelescope GhcPs] -> FreeKiTyVars -> FreeKiTyVars
+ GHC.Rename.HsType: rnHsConDeclField :: HsDocContext -> HsConDeclField GhcPs -> RnM (HsConDeclField GhcRn, FreeVars)
+ GHC.Rename.HsType: rnHsConDeclRecFields :: HsDocContext -> [FieldLabel] -> [LHsConDeclRecField GhcPs] -> RnM ([LHsConDeclRecField GhcRn], FreeVars)
+ GHC.Rename.HsType: rnHsMultAnnWith :: (LocatedA (mult GhcPs) -> RnM (LocatedA (mult GhcRn), FreeVars)) -> HsMultAnnOf (LocatedA (mult GhcPs)) GhcPs -> RnM (HsMultAnnOf (LocatedA (mult GhcRn)) GhcRn, FreeVars)
+ GHC.Rename.Splice: checkThLocalNameNoLift :: LIdOccP GhcRn -> RnM ()
+ GHC.Rename.Splice: checkThLocalNameWithLift :: LIdOccP GhcRn -> RnM (HsExpr GhcRn)
+ GHC.Rename.Unbound: WL_ConLike :: WhatLooking
+ GHC.Rename.Unbound: WL_Term :: WhatLooking
+ GHC.Rename.Unbound: WL_TermVariable :: WhatLooking
+ GHC.Rename.Unbound: WL_TyCon :: WhatLooking
+ GHC.Rename.Unbound: WL_TyCon_or_TermVar :: WhatLooking
+ GHC.Rename.Unbound: WL_TyVar :: WhatLooking
+ GHC.Rename.Unbound: WL_Type :: WhatLooking
+ GHC.Rename.Unbound: relevantNameSpace :: Bool -> WhatLooking -> NameSpace -> Bool
+ GHC.Rename.Unbound: suggestionIsRelevant :: DynFlags -> WhatLooking -> OccName -> Bool
+ GHC.Rename.Unbound: unknownNameSuggestionsMessage :: TcRnMessage -> [ImportError] -> [GhcHint] -> RnM TcRnMessage
+ GHC.Rename.Utils: mkRnSyntaxExpr :: Name -> SyntaxExprRn
+ GHC.Runtime.Debugger.Breakpoints: enclosingTickSpan :: TickArray -> SrcSpan -> RealSrcSpan
+ GHC.Runtime.Debugger.Breakpoints: findBreakByCoord :: (Int, Int) -> TickArray -> Maybe (BreakTickIndex, RealSrcSpan)
+ GHC.Runtime.Debugger.Breakpoints: findBreakByLine :: Int -> TickArray -> Maybe (BreakTickIndex, RealSrcSpan)
+ GHC.Runtime.Debugger.Breakpoints: findBreakForBind :: String -> ModBreaks -> [(BreakTickIndex, RealSrcSpan)]
+ GHC.Runtime.Debugger.Breakpoints: getCurrentBreakModule :: GhcMonad m => m (Maybe Module)
+ GHC.Runtime.Debugger.Breakpoints: getCurrentBreakSpan :: GhcMonad m => m (Maybe SrcSpan)
+ GHC.Runtime.Debugger.Breakpoints: getModBreak :: GhcMonad m => Module -> m (Maybe ModBreaks)
+ GHC.Runtime.Debugger.Breakpoints: leftmostLargestRealSrcSpan :: RealSrcSpan -> RealSrcSpan -> Ordering
+ GHC.Runtime.Debugger.Breakpoints: lookupBreakpointOccurrences :: BreakpointOccurrences -> BreakpointId -> Maybe [InternalBreakpointId]
+ GHC.Runtime.Debugger.Breakpoints: makeModuleLineMap :: GhcMonad m => Module -> m (Maybe TickArray)
+ GHC.Runtime.Debugger.Breakpoints: mkBreakpointOccurrences :: GhcMonad m => m BreakpointOccurrences
+ GHC.Runtime.Debugger.Breakpoints: resolveFunctionBreakpoint :: GhcMonad m => String -> m (Either SDoc (Module, ModuleInfo, String))
+ GHC.Runtime.Debugger.Breakpoints: type BreakpointOccurrences = ModuleEnv IntMap [InternalBreakpointId]
+ GHC.Runtime.Debugger.Breakpoints: type TickArray = Array Int [(BreakTickIndex, RealSrcSpan)]
+ GHC.Runtime.Eval: LocalStep :: SrcSpan -> SingleStep
+ GHC.Runtime.Eval: ModuleStep :: SrcSpan -> SingleStep
+ GHC.Runtime.Eval: StepOut :: Maybe SrcSpan -> SingleStep
+ GHC.Runtime.Eval: [breakAt] :: SingleStep -> SrcSpan
+ GHC.Runtime.Eval: [infoprov] :: Term -> Maybe InfoProv
+ GHC.Runtime.Eval: [initiatedFrom] :: SingleStep -> Maybe SrcSpan
+ GHC.Runtime.Eval: mkTopLevImportedEnv :: HscEnv -> HomeModInfo -> IO GlobalRdrEnv
+ GHC.Runtime.Eval: readIModBreaks :: HomeUnitGraph -> InternalBreakpointId -> IO InternalModBreaks
+ GHC.Runtime.Eval: readIModModBreaks :: HomeUnitGraph -> Module -> IO ModBreaks
+ GHC.Runtime.Eval.Types: LocalStep :: SrcSpan -> SingleStep
+ GHC.Runtime.Eval.Types: ModuleStep :: SrcSpan -> SingleStep
+ GHC.Runtime.Eval.Types: StepOut :: Maybe SrcSpan -> SingleStep
+ GHC.Runtime.Eval.Types: [breakAt] :: SingleStep -> SrcSpan
+ GHC.Runtime.Eval.Types: [initiatedFrom] :: SingleStep -> Maybe SrcSpan
+ GHC.Runtime.Eval.Types: breakHere :: Bool -> SingleStep -> SrcSpan -> Bool
+ GHC.Runtime.Eval.Types: enableGhcStepMode :: SingleStep -> EvalStep
+ GHC.Runtime.Eval.Utils: combineModIdent :: String -> String -> String
+ GHC.Runtime.Eval.Utils: splitIdent :: String -> (String, String, String)
+ GHC.Runtime.Heap.Inspect: [infoprov] :: Term -> Maybe InfoProv
+ GHC.Runtime.Heap.Layout: instance GHC.Internal.Classes.Eq GHC.Runtime.Heap.Layout.ArgDescr
+ GHC.Runtime.Heap.Layout: instance GHC.Internal.Classes.Eq GHC.Runtime.Heap.Layout.ClosureTypeInfo
+ GHC.Runtime.Heap.Layout: instance GHC.Internal.Classes.Eq GHC.Runtime.Heap.Layout.SMRep
+ GHC.Runtime.Heap.Layout: instance GHC.Internal.Classes.Eq GHC.Runtime.Heap.Layout.StgHalfWord
+ GHC.Runtime.Heap.Layout: instance GHC.Internal.Classes.Eq GHC.Runtime.Heap.Layout.StgWord
+ GHC.Runtime.Heap.Layout: instance GHC.Internal.Classes.Ord GHC.Runtime.Heap.Layout.ArgDescr
+ GHC.Runtime.Heap.Layout: instance GHC.Internal.Classes.Ord GHC.Runtime.Heap.Layout.ClosureTypeInfo
+ GHC.Runtime.Heap.Layout: instance GHC.Internal.Classes.Ord GHC.Runtime.Heap.Layout.SMRep
+ GHC.Runtime.Interpreter: [WhereFrom] :: HValueRef -> Message (Maybe InfoProv)
+ GHC.Runtime.Interpreter: readIModBreaks :: HomeUnitGraph -> InternalBreakpointId -> IO InternalModBreaks
+ GHC.Runtime.Interpreter: readIModBreaksMaybe :: HomeUnitGraph -> Module -> IO (Maybe InternalModBreaks)
+ GHC.Runtime.Interpreter: readIModModBreaks :: HomeUnitGraph -> Module -> IO ModBreaks
+ GHC.Runtime.Interpreter: whereFrom :: Interp -> ForeignHValue -> IO (Maybe InfoProv)
+ GHC.Runtime.Interpreter.Process: [WhereFrom] :: HValueRef -> Message (Maybe InfoProv)
+ GHC.Runtime.Interpreter.Types: InterpSymbolCache :: MVar (SymbolCache "closure") -> MVar (SymbolCache "con_info") -> MVar (SymbolCache "static_info") -> MVar (SymbolCache "bytes") -> MVar (UniqFM FastString (Ptr ())) -> InterpSymbolCache
+ GHC.Runtime.Interpreter.Types: Interpreted :: SuffixOrInterpreted
+ GHC.Runtime.Interpreter.Types: Suffix :: Symbol -> SuffixOrInterpreted
+ GHC.Runtime.Interpreter.Types: [IBytesSymbol] :: Name -> InterpSymbol ('Suffix "bytes")
+ GHC.Runtime.Interpreter.Types: [IClosureSymbol] :: Name -> InterpSymbol ('Suffix "closure")
+ GHC.Runtime.Interpreter.Types: [IConInfoSymbol] :: Name -> InterpSymbol ('Suffix "con_info")
+ GHC.Runtime.Interpreter.Types: [IFaststringSymbol] :: FastString -> InterpSymbol 'Interpreted
+ GHC.Runtime.Interpreter.Types: [IStaticInfoSymbol] :: Name -> InterpSymbol ('Suffix "static_info")
+ GHC.Runtime.Interpreter.Types: [interpBytesCache] :: InterpSymbolCache -> MVar (SymbolCache "bytes")
+ GHC.Runtime.Interpreter.Types: [interpClosureCache] :: InterpSymbolCache -> MVar (SymbolCache "closure")
+ GHC.Runtime.Interpreter.Types: [interpConInfoCache] :: InterpSymbolCache -> MVar (SymbolCache "con_info")
+ GHC.Runtime.Interpreter.Types: [interpFaststringCache] :: InterpSymbolCache -> MVar (UniqFM FastString (Ptr ()))
+ GHC.Runtime.Interpreter.Types: [interpStaticInfoCache] :: InterpSymbolCache -> MVar (SymbolCache "static_info")
+ GHC.Runtime.Interpreter.Types: [interpSymbolCache] :: Interp -> InterpSymbolCache
+ GHC.Runtime.Interpreter.Types: [wasmInterpBrowserHost] :: WasmInterpConfig -> String
+ GHC.Runtime.Interpreter.Types: [wasmInterpBrowserPlaywrightBrowserType] :: WasmInterpConfig -> Maybe String
+ GHC.Runtime.Interpreter.Types: [wasmInterpBrowserPlaywrightLaunchOpts] :: WasmInterpConfig -> Maybe String
+ GHC.Runtime.Interpreter.Types: [wasmInterpBrowserPort] :: WasmInterpConfig -> Int
+ GHC.Runtime.Interpreter.Types: [wasmInterpBrowserPuppeteerLaunchOpts] :: WasmInterpConfig -> Maybe String
+ GHC.Runtime.Interpreter.Types: [wasmInterpBrowserRedirectWasiConsole] :: WasmInterpConfig -> Bool
+ GHC.Runtime.Interpreter.Types: [wasmInterpBrowser] :: WasmInterpConfig -> Bool
+ GHC.Runtime.Interpreter.Types: data InterpSymbol (s :: SuffixOrInterpreted)
+ GHC.Runtime.Interpreter.Types: data InterpSymbolCache
+ GHC.Runtime.Interpreter.Types: data SuffixOrInterpreted
+ GHC.Runtime.Interpreter.Types: eliminateInterpSymbol :: forall (s :: SuffixOrInterpreted) r. InterpSymbol s -> (InterpSymbol 'Interpreted -> r) -> (forall (x :: Symbol). () => InterpSymbol ('Suffix x) -> r) -> r
+ GHC.Runtime.Interpreter.Types: interpSymbolName :: forall (s :: Symbol). InterpSymbol ('Suffix s) -> Name
+ GHC.Runtime.Interpreter.Types: interpSymbolSuffix :: forall (s :: Symbol). InterpSymbol ('Suffix s) -> String
+ GHC.Runtime.Interpreter.Types: interpretedInterpSymbol :: InterpSymbol 'Interpreted -> FastString
+ GHC.Runtime.Interpreter.Types: interpreterDynamic :: Interp -> Bool
+ GHC.Runtime.Interpreter.Types: interpreterProfiled :: Interp -> Bool
+ GHC.Runtime.Interpreter.Types: lookupInterpSymbolCache :: forall (s :: SuffixOrInterpreted). InterpSymbol s -> InterpSymbolCache -> IO (Maybe (Ptr ()))
+ GHC.Runtime.Interpreter.Types: mkInterpSymbolCache :: IO InterpSymbolCache
+ GHC.Runtime.Interpreter.Types: purgeInterpSymbolCache :: InterpSymbolCache -> IO ()
+ GHC.Runtime.Interpreter.Types: updateInterpSymbolCache :: forall (s :: SuffixOrInterpreted). InterpSymbol s -> InterpSymbolCache -> Ptr () -> IO ()
+ GHC.Runtime.Interpreter.Types.SymbolCache: InterpSymbolCache :: MVar (SymbolCache "closure") -> MVar (SymbolCache "con_info") -> MVar (SymbolCache "static_info") -> MVar (SymbolCache "bytes") -> MVar (UniqFM FastString (Ptr ())) -> InterpSymbolCache
+ GHC.Runtime.Interpreter.Types.SymbolCache: Interpreted :: SuffixOrInterpreted
+ GHC.Runtime.Interpreter.Types.SymbolCache: Suffix :: Symbol -> SuffixOrInterpreted
+ GHC.Runtime.Interpreter.Types.SymbolCache: [IBytesSymbol] :: Name -> InterpSymbol ('Suffix "bytes")
+ GHC.Runtime.Interpreter.Types.SymbolCache: [IClosureSymbol] :: Name -> InterpSymbol ('Suffix "closure")
+ GHC.Runtime.Interpreter.Types.SymbolCache: [IConInfoSymbol] :: Name -> InterpSymbol ('Suffix "con_info")
+ GHC.Runtime.Interpreter.Types.SymbolCache: [IFaststringSymbol] :: FastString -> InterpSymbol 'Interpreted
+ GHC.Runtime.Interpreter.Types.SymbolCache: [IStaticInfoSymbol] :: Name -> InterpSymbol ('Suffix "static_info")
+ GHC.Runtime.Interpreter.Types.SymbolCache: [interpBytesCache] :: InterpSymbolCache -> MVar (SymbolCache "bytes")
+ GHC.Runtime.Interpreter.Types.SymbolCache: [interpClosureCache] :: InterpSymbolCache -> MVar (SymbolCache "closure")
+ GHC.Runtime.Interpreter.Types.SymbolCache: [interpConInfoCache] :: InterpSymbolCache -> MVar (SymbolCache "con_info")
+ GHC.Runtime.Interpreter.Types.SymbolCache: [interpFaststringCache] :: InterpSymbolCache -> MVar (UniqFM FastString (Ptr ()))
+ GHC.Runtime.Interpreter.Types.SymbolCache: [interpStaticInfoCache] :: InterpSymbolCache -> MVar (SymbolCache "static_info")
+ GHC.Runtime.Interpreter.Types.SymbolCache: data InterpSymbol (s :: SuffixOrInterpreted)
+ GHC.Runtime.Interpreter.Types.SymbolCache: data InterpSymbolCache
+ GHC.Runtime.Interpreter.Types.SymbolCache: data SuffixOrInterpreted
+ GHC.Runtime.Interpreter.Types.SymbolCache: eliminateInterpSymbol :: forall (s :: SuffixOrInterpreted) r. InterpSymbol s -> (InterpSymbol 'Interpreted -> r) -> (forall (x :: Symbol). () => InterpSymbol ('Suffix x) -> r) -> r
+ GHC.Runtime.Interpreter.Types.SymbolCache: instance GHC.Utils.Outputable.Outputable (GHC.Runtime.Interpreter.Types.SymbolCache.InterpSymbol s)
+ GHC.Runtime.Interpreter.Types.SymbolCache: interpSymbolName :: forall (s :: Symbol). InterpSymbol ('Suffix s) -> Name
+ GHC.Runtime.Interpreter.Types.SymbolCache: interpSymbolSuffix :: forall (s :: Symbol). InterpSymbol ('Suffix s) -> String
+ GHC.Runtime.Interpreter.Types.SymbolCache: interpretedInterpSymbol :: InterpSymbol 'Interpreted -> FastString
+ GHC.Runtime.Interpreter.Types.SymbolCache: lookupInterpSymbolCache :: forall (s :: SuffixOrInterpreted). InterpSymbol s -> InterpSymbolCache -> IO (Maybe (Ptr ()))
+ GHC.Runtime.Interpreter.Types.SymbolCache: mkInterpSymbolCache :: IO InterpSymbolCache
+ GHC.Runtime.Interpreter.Types.SymbolCache: purgeInterpSymbolCache :: InterpSymbolCache -> IO ()
+ GHC.Runtime.Interpreter.Types.SymbolCache: updateInterpSymbolCache :: forall (s :: SuffixOrInterpreted). InterpSymbol s -> InterpSymbolCache -> Ptr () -> IO ()
+ GHC.Settings: UnitSettings :: UnitId -> UnitSettings
+ GHC.Settings: [sUnitSettings] :: Settings -> UnitSettings
+ GHC.Settings: [unitSettings_baseUnitId] :: UnitSettings -> UnitId
+ GHC.Settings: data UnitSettings
+ GHC.Settings.Config: cGhcInternalUnitId :: String
+ GHC.Stg.EnforceEpt: enforceEpt :: StgPprOpts -> Bool -> Logger -> Module -> [CgStgTopBinding] -> IO ([TgStgTopBinding], NameEnv TagSig)
+ GHC.Stg.EnforceEpt.Rewrite: instance GHC.Internal.Base.Applicative GHC.Stg.EnforceEpt.Rewrite.RM
+ GHC.Stg.EnforceEpt.Rewrite: instance GHC.Internal.Base.Functor GHC.Stg.EnforceEpt.Rewrite.RM
+ GHC.Stg.EnforceEpt.Rewrite: instance GHC.Internal.Base.Monad GHC.Stg.EnforceEpt.Rewrite.RM
+ GHC.Stg.EnforceEpt.Rewrite: instance GHC.Types.Unique.Supply.MonadUnique GHC.Stg.EnforceEpt.Rewrite.RM
+ GHC.Stg.EnforceEpt.Rewrite: rewriteOpApp :: InferStgExpr -> RM TgStgExpr
+ GHC.Stg.EnforceEpt.Rewrite: rewriteTopBinds :: Module -> UniqSupply -> [GenStgTopBinding 'InferTaggedBinders] -> [TgStgTopBinding]
+ GHC.Stg.EnforceEpt.TagSig: TagDunno :: TagInfo
+ GHC.Stg.EnforceEpt.TagSig: TagProper :: TagInfo
+ GHC.Stg.EnforceEpt.TagSig: TagSig :: TagInfo -> TagSig
+ GHC.Stg.EnforceEpt.TagSig: TagTagged :: TagInfo
+ GHC.Stg.EnforceEpt.TagSig: TagTuple :: [TagInfo] -> TagInfo
+ GHC.Stg.EnforceEpt.TagSig: data TagInfo
+ GHC.Stg.EnforceEpt.TagSig: instance GHC.Internal.Classes.Eq GHC.Stg.EnforceEpt.TagSig.TagInfo
+ GHC.Stg.EnforceEpt.TagSig: instance GHC.Internal.Classes.Eq GHC.Stg.EnforceEpt.TagSig.TagSig
+ GHC.Stg.EnforceEpt.TagSig: instance GHC.Utils.Binary.Binary GHC.Stg.EnforceEpt.TagSig.TagInfo
+ GHC.Stg.EnforceEpt.TagSig: instance GHC.Utils.Binary.Binary GHC.Stg.EnforceEpt.TagSig.TagSig
+ GHC.Stg.EnforceEpt.TagSig: instance GHC.Utils.Outputable.Outputable GHC.Stg.EnforceEpt.TagSig.TagInfo
+ GHC.Stg.EnforceEpt.TagSig: instance GHC.Utils.Outputable.Outputable GHC.Stg.EnforceEpt.TagSig.TagSig
+ GHC.Stg.EnforceEpt.TagSig: instance GHC.Utils.Outputable.OutputableBndr (GHC.Types.Var.Id, GHC.Stg.EnforceEpt.TagSig.TagSig)
+ GHC.Stg.EnforceEpt.TagSig: isTaggedSig :: TagSig -> Bool
+ GHC.Stg.EnforceEpt.TagSig: newtype TagSig
+ GHC.Stg.EnforceEpt.TagSig: seqTagInfo :: TagInfo -> ()
+ GHC.Stg.EnforceEpt.TagSig: seqTagSig :: TagSig -> ()
+ GHC.Stg.EnforceEpt.TagSig: type StgCgInfos = NameEnv TagSig
+ GHC.Stg.EnforceEpt.Types: TE :: TagSigEnv -> (BinderP p -> Id) -> Bool -> TagEnv (p :: StgPass)
+ GHC.Stg.EnforceEpt.Types: [te_bytecode] :: TagEnv (p :: StgPass) -> Bool
+ GHC.Stg.EnforceEpt.Types: [te_env] :: TagEnv (p :: StgPass) -> TagSigEnv
+ GHC.Stg.EnforceEpt.Types: [te_get] :: TagEnv (p :: StgPass) -> BinderP p -> Id
+ GHC.Stg.EnforceEpt.Types: combineAltInfo :: TagInfo -> TagInfo -> TagInfo
+ GHC.Stg.EnforceEpt.Types: data TagEnv (p :: StgPass)
+ GHC.Stg.EnforceEpt.Types: extendSigEnv :: forall (p :: StgPass). TagEnv p -> [(Id, TagSig)] -> TagEnv p
+ GHC.Stg.EnforceEpt.Types: getBinderId :: forall (p :: StgPass). TagEnv p -> BinderP p -> Id
+ GHC.Stg.EnforceEpt.Types: initEnv :: Bool -> TagEnv 'CodeGen
+ GHC.Stg.EnforceEpt.Types: instance GHC.Utils.Outputable.Outputable (GHC.Stg.EnforceEpt.Types.TagEnv p)
+ GHC.Stg.EnforceEpt.Types: isDunnoSig :: TagSig -> Bool
+ GHC.Stg.EnforceEpt.Types: isTaggedInfo :: TagInfo -> Bool
+ GHC.Stg.EnforceEpt.Types: lookupInfo :: forall (p :: StgPass). TagEnv p -> StgArg -> TagInfo
+ GHC.Stg.EnforceEpt.Types: lookupSig :: forall (p :: StgPass). TagEnv p -> Id -> Maybe TagSig
+ GHC.Stg.EnforceEpt.Types: makeTagged :: forall (p :: StgPass). TagEnv p -> TagEnv 'InferTaggedBinders
+ GHC.Stg.EnforceEpt.Types: noSig :: forall (p :: StgPass). TagEnv p -> BinderP p -> (Id, TagSig)
+ GHC.Stg.EnforceEpt.Types: type InferStgAlt = GenStgAlt 'InferTaggedBinders
+ GHC.Stg.EnforceEpt.Types: type InferStgBinding = GenStgBinding 'InferTaggedBinders
+ GHC.Stg.EnforceEpt.Types: type InferStgExpr = GenStgExpr 'InferTaggedBinders
+ GHC.Stg.EnforceEpt.Types: type InferStgRhs = GenStgRhs 'InferTaggedBinders
+ GHC.Stg.EnforceEpt.Types: type InferStgTopBinding = GenStgTopBinding 'InferTaggedBinders
+ GHC.Stg.EnforceEpt.Types: type TagSigEnv = IdEnv TagSig
+ GHC.Stg.Lift.Config: instance GHC.Internal.Classes.Eq GHC.Stg.Lift.Config.StgLiftConfig
+ GHC.Stg.Lift.Config: instance GHC.Internal.Classes.Ord GHC.Stg.Lift.Config.StgLiftConfig
+ GHC.Stg.Pipeline: instance GHC.Internal.Classes.Eq GHC.Stg.Pipeline.StgToDo
+ GHC.Stg.Pipeline: instance GHC.Internal.Classes.Ord GHC.Stg.Pipeline.StgToDo
+ GHC.Stg.Stats: instance GHC.Internal.Classes.Eq GHC.Stg.Stats.CounterType
+ GHC.Stg.Stats: instance GHC.Internal.Classes.Ord GHC.Stg.Stats.CounterType
+ GHC.Stg.Syntax: instance GHC.Internal.Classes.Eq GHC.Stg.Syntax.NoExtFieldSilent
+ GHC.Stg.Syntax: instance GHC.Internal.Classes.Eq GHC.Stg.Syntax.UpdateFlag
+ GHC.Stg.Syntax: instance GHC.Internal.Classes.Ord GHC.Stg.Syntax.NoExtFieldSilent
+ GHC.StgToByteCode: instance GHC.Internal.Classes.Eq GHC.StgToByteCode.Discr
+ GHC.StgToByteCode: instance GHC.Internal.Classes.Ord GHC.StgToByteCode.Discr
+ GHC.StgToByteCode: instance GHC.Internal.Control.Monad.IO.Class.MonadIO GHC.StgToByteCode.BcM
+ GHC.StgToCmm.ArgRep: instance GHC.Internal.Classes.Eq GHC.StgToCmm.ArgRep.ArgRep
+ GHC.StgToCmm.ArgRep: instance GHC.Internal.Classes.Ord GHC.StgToCmm.ArgRep.ArgRep
+ GHC.StgToCmm.Closure: instance GHC.Internal.Classes.Eq a => GHC.Internal.Classes.Eq (GHC.StgToCmm.Closure.NonVoid a)
+ GHC.StgToCmm.Config: [stgToCmmAllowIntWord64X2MinMax] :: StgToCmmConfig -> Bool
+ GHC.StgToCmm.Monad: [stgToCmmAllowIntWord64X2MinMax] :: StgToCmmConfig -> Bool
+ GHC.StgToCmm.Types: instance GHC.Internal.Classes.Eq GHC.StgToCmm.Types.StandardFormInfo
+ GHC.StgToJS.Apply: instance GHC.Internal.Classes.Eq GHC.StgToJS.Apply.ApplyConv
+ GHC.StgToJS.Apply: instance GHC.Internal.Classes.Eq GHC.StgToJS.Apply.ApplySpec
+ GHC.StgToJS.Apply: instance GHC.Internal.Classes.Ord GHC.StgToJS.Apply.ApplyConv
+ GHC.StgToJS.Apply: instance GHC.Internal.Classes.Ord GHC.StgToJS.Apply.ApplySpec
+ GHC.StgToJS.Expr: instance GHC.Internal.Classes.Eq a => GHC.Internal.Classes.Eq (GHC.StgToJS.Expr.Branch a)
+ GHC.StgToJS.ExprCtx: instance GHC.Utils.Outputable.Outputable GHC.StgToJS.ExprCtx.ExprCtx
+ GHC.StgToJS.Linker.Linker: instance GHC.Utils.Outputable.Outputable GHC.StgToJS.Linker.Linker.ModuleCode
+ GHC.StgToJS.Monad: instance GHC.Utils.Outputable.Outputable GHC.StgToJS.Monad.GlobalOcc
+ GHC.StgToJS.Object: instance GHC.Internal.Classes.Eq GHC.StgToJS.Object.BlockRef
+ GHC.StgToJS.Object: instance GHC.Internal.Classes.Eq GHC.StgToJS.Object.ExportedFun
+ GHC.StgToJS.Object: instance GHC.Internal.Classes.Eq GHC.StgToJS.Object.JSOptions
+ GHC.StgToJS.Object: instance GHC.Internal.Classes.Eq GHC.StgToJS.Object.ObjectKind
+ GHC.StgToJS.Object: instance GHC.Internal.Classes.Ord GHC.StgToJS.Object.BlockRef
+ GHC.StgToJS.Object: instance GHC.Internal.Classes.Ord GHC.StgToJS.Object.ExportedFun
+ GHC.StgToJS.Object: instance GHC.Internal.Classes.Ord GHC.StgToJS.Object.JSOptions
+ GHC.StgToJS.Object: instance GHC.Internal.Classes.Ord GHC.StgToJS.Object.ObjectKind
+ GHC.StgToJS.Regs: instance GHC.Internal.Classes.Eq GHC.StgToJS.Regs.Special
+ GHC.StgToJS.Regs: instance GHC.Internal.Classes.Eq GHC.StgToJS.Regs.StgReg
+ GHC.StgToJS.Regs: instance GHC.Internal.Classes.Eq GHC.StgToJS.Regs.StgRet
+ GHC.StgToJS.Regs: instance GHC.Internal.Classes.Ord GHC.StgToJS.Regs.StgReg
+ GHC.StgToJS.Regs: instance GHC.Internal.Classes.Ord GHC.StgToJS.Regs.StgRet
+ GHC.StgToJS.Sinker.Collect: collectArgs :: CgStgBinding -> [Id]
+ GHC.StgToJS.Sinker.Collect: collectArgsTop :: CgStgBinding -> [Id]
+ GHC.StgToJS.Sinker.Collect: selectUsedOnce :: (Foldable t, Uniquable a) => t a -> UniqSet a
+ GHC.StgToJS.Sinker.Sinker: sinkPgm :: Module -> [CgStgTopBinding] -> (UniqFM Id CgStgExpr, [CgStgTopBinding])
+ GHC.StgToJS.Sinker.StringsUnfloat: unfloatStringLits :: UniqSet Name -> UniqFM Name ByteString -> [CgStgBinding] -> ([CgStgBinding], UniqSet Name)
+ GHC.StgToJS.Symbols: hdDecodeUtf8Z :: FastString
+ GHC.StgToJS.Types: SAKData :: StaticAppKind
+ GHC.StgToJS.Types: SAKFun :: StaticAppKind
+ GHC.StgToJS.Types: SAKThunk :: StaticAppKind
+ GHC.StgToJS.Types: StaticApp :: StaticAppKind -> FastString -> [StaticArg] -> StaticVal
+ GHC.StgToJS.Types: data StaticAppKind
+ GHC.StgToJS.Types: instance GHC.Internal.Classes.Eq GHC.StgToJS.Types.CILayout
+ GHC.StgToJS.Types: instance GHC.Internal.Classes.Eq GHC.StgToJS.Types.CIRegs
+ GHC.StgToJS.Types: instance GHC.Internal.Classes.Eq GHC.StgToJS.Types.CIStatic
+ GHC.StgToJS.Types: instance GHC.Internal.Classes.Eq GHC.StgToJS.Types.CIType
+ GHC.StgToJS.Types: instance GHC.Internal.Classes.Eq GHC.StgToJS.Types.ClosureInfo
+ GHC.StgToJS.Types: instance GHC.Internal.Classes.Eq GHC.StgToJS.Types.ClosureType
+ GHC.StgToJS.Types: instance GHC.Internal.Classes.Eq GHC.StgToJS.Types.ExpFun
+ GHC.StgToJS.Types: instance GHC.Internal.Classes.Eq GHC.StgToJS.Types.ExprResult
+ GHC.StgToJS.Types: instance GHC.Internal.Classes.Eq GHC.StgToJS.Types.ExprValData
+ GHC.StgToJS.Types: instance GHC.Internal.Classes.Eq GHC.StgToJS.Types.IdKey
+ GHC.StgToJS.Types: instance GHC.Internal.Classes.Eq GHC.StgToJS.Types.IdType
+ GHC.StgToJS.Types: instance GHC.Internal.Classes.Eq GHC.StgToJS.Types.JSFFIType
+ GHC.StgToJS.Types: instance GHC.Internal.Classes.Eq GHC.StgToJS.Types.JSRep
+ GHC.StgToJS.Types: instance GHC.Internal.Classes.Eq GHC.StgToJS.Types.OtherSymb
+ GHC.StgToJS.Types: instance GHC.Internal.Classes.Eq GHC.StgToJS.Types.StackSlot
+ GHC.StgToJS.Types: instance GHC.Internal.Classes.Eq GHC.StgToJS.Types.StaticAppKind
+ GHC.StgToJS.Types: instance GHC.Internal.Classes.Eq GHC.StgToJS.Types.StaticArg
+ GHC.StgToJS.Types: instance GHC.Internal.Classes.Eq GHC.StgToJS.Types.StaticInfo
+ GHC.StgToJS.Types: instance GHC.Internal.Classes.Eq GHC.StgToJS.Types.StaticLit
+ GHC.StgToJS.Types: instance GHC.Internal.Classes.Eq GHC.StgToJS.Types.StaticUnboxed
+ GHC.StgToJS.Types: instance GHC.Internal.Classes.Eq GHC.StgToJS.Types.StaticVal
+ GHC.StgToJS.Types: instance GHC.Internal.Classes.Eq GHC.StgToJS.Types.ThreadStatus
+ GHC.StgToJS.Types: instance GHC.Internal.Classes.Ord GHC.StgToJS.Types.CILayout
+ GHC.StgToJS.Types: instance GHC.Internal.Classes.Ord GHC.StgToJS.Types.CIRegs
+ GHC.StgToJS.Types: instance GHC.Internal.Classes.Ord GHC.StgToJS.Types.CIType
+ GHC.StgToJS.Types: instance GHC.Internal.Classes.Ord GHC.StgToJS.Types.ClosureType
+ GHC.StgToJS.Types: instance GHC.Internal.Classes.Ord GHC.StgToJS.Types.ExpFun
+ GHC.StgToJS.Types: instance GHC.Internal.Classes.Ord GHC.StgToJS.Types.IdKey
+ GHC.StgToJS.Types: instance GHC.Internal.Classes.Ord GHC.StgToJS.Types.IdType
+ GHC.StgToJS.Types: instance GHC.Internal.Classes.Ord GHC.StgToJS.Types.JSFFIType
+ GHC.StgToJS.Types: instance GHC.Internal.Classes.Ord GHC.StgToJS.Types.JSRep
+ GHC.StgToJS.Types: instance GHC.Internal.Classes.Ord GHC.StgToJS.Types.OtherSymb
+ GHC.StgToJS.Types: instance GHC.Internal.Classes.Ord GHC.StgToJS.Types.StackSlot
+ GHC.StgToJS.Types: instance GHC.Internal.Classes.Ord GHC.StgToJS.Types.StaticUnboxed
+ GHC.StgToJS.Types: instance GHC.Internal.Classes.Ord GHC.StgToJS.Types.ThreadStatus
+ GHC.StgToJS.Types: instance GHC.Internal.Show.Show GHC.StgToJS.Types.ForeignJSRef
+ GHC.StgToJS.Types: instance GHC.Internal.Show.Show GHC.StgToJS.Types.StaticAppKind
+ GHC.StgToJS.Utils: instance GHC.Internal.Classes.Eq GHC.StgToJS.Utils.SlotCount
+ GHC.StgToJS.Utils: instance GHC.Internal.Classes.Ord GHC.StgToJS.Utils.SlotCount
+ GHC.SysTools.Ar: instance GHC.Internal.Classes.Eq GHC.SysTools.Ar.Archive
+ GHC.SysTools.Ar: instance GHC.Internal.Classes.Eq GHC.SysTools.Ar.ArchiveEntry
+ GHC.SysTools.Cpp: getGhcVersionIncludeFlags :: DynFlags -> UnitEnv -> IO [String]
+ GHC.SysTools.Tasks: instance GHC.Internal.Classes.Eq GHC.SysTools.Tasks.SourceCodePreprocessor
+ GHC.Tc.Errors.Hole: instance GHC.Internal.Classes.Eq GHC.Tc.Errors.Hole.HoleFitSortingAlg
+ GHC.Tc.Errors.Hole: instance GHC.Internal.Classes.Ord GHC.Tc.Errors.Hole.HoleFitSortingAlg
+ GHC.Tc.Errors.Hole.FitTypes: TcHoleFit :: TcHoleFit -> HoleFit
+ GHC.Tc.Errors.Hole.FitTypes: data TcHoleFit
+ GHC.Tc.Errors.Hole.FitTypes: instance GHC.Internal.Classes.Eq GHC.Tc.Errors.Hole.FitTypes.HoleFitCandidate
+ GHC.Tc.Errors.Hole.FitTypes: instance GHC.Internal.Classes.Eq GHC.Tc.Errors.Hole.FitTypes.TcHoleFit
+ GHC.Tc.Errors.Hole.FitTypes: instance GHC.Internal.Classes.Ord GHC.Tc.Errors.Hole.FitTypes.HoleFitCandidate
+ GHC.Tc.Errors.Hole.FitTypes: instance GHC.Internal.Classes.Ord GHC.Tc.Errors.Hole.FitTypes.TcHoleFit
+ GHC.Tc.Errors.Hole.FitTypes: instance GHC.Utils.Outputable.Outputable GHC.Tc.Errors.Hole.FitTypes.TcHoleFit
+ GHC.Tc.Errors.Ppr: pprErrCtxtMsg :: ErrCtxtMsg -> SDoc
+ GHC.Tc.Errors.Types: AmbiguityCheckCtxt :: UserTypeCtxt -> Bool -> ErrCtxtMsg
+ GHC.Tc.Errors.Types: AnnCtxt :: AnnDecl (GhcPass p) -> ErrCtxtMsg
+ GHC.Tc.Errors.Types: AssociatedTypeOfClass :: Subordinate
+ GHC.Tc.Errors.Types: BadImportNonDataSubordinates :: GlobalRdrElt -> NonEmpty GlobalRdrElt -> BadImportKind
+ GHC.Tc.Errors.Types: BadImportNonTypeSubordinates :: GlobalRdrElt -> NonEmpty GlobalRdrElt -> BadImportKind
+ GHC.Tc.Errors.Types: CheckImplementsCtxt :: UnitState -> Module -> InstantiatedModule -> ErrCtxtMsg
+ GHC.Tc.Errors.Types: ClassMethodSigCtx :: LocatedN RdrName -> HsDocContext
+ GHC.Tc.Errors.Types: ClassOpCtxt :: Id -> Type -> ErrCtxtMsg
+ GHC.Tc.Errors.Types: ClosedFamEqnCtxt :: TyCon -> ErrCtxtMsg
+ GHC.Tc.Errors.Types: CmdCtxt :: HsCmd GhcRn -> ErrCtxtMsg
+ GHC.Tc.Errors.Types: DataConDefCtxt :: NonEmpty (LocatedN Name) -> ErrCtxtMsg
+ GHC.Tc.Errors.Types: DataConResTyCtxt :: NonEmpty (LocatedN Name) -> ErrCtxtMsg
+ GHC.Tc.Errors.Types: DataConVisibleForall :: UnrepresentableTypeDescr
+ GHC.Tc.Errors.Types: DefaultDeclErrCtxt :: Bool -> ErrCtxtMsg
+ GHC.Tc.Errors.Types: DerivBindCtxt :: Id -> Class -> [Type] -> ErrCtxtMsg
+ GHC.Tc.Errors.Types: DerivInstCtxt :: PredType -> ErrCtxtMsg
+ GHC.Tc.Errors.Types: EmptyGuard :: ConversionFailReason
+ GHC.Tc.Errors.Types: EmptyParStmt :: ConversionFailReason
+ GHC.Tc.Errors.Types: ExportCtxt :: IE (GhcPass p) -> ErrCtxtMsg
+ GHC.Tc.Errors.Types: ExprCtxt :: HsExpr GhcRn -> ErrCtxtMsg
+ GHC.Tc.Errors.Types: FieldCtxt :: FieldLabelString -> ErrCtxtMsg
+ GHC.Tc.Errors.Types: FieldOfConstructor :: Subordinate
+ GHC.Tc.Errors.Types: ForeignDeclCtxt :: ForeignDecl GhcRn -> ErrCtxtMsg
+ GHC.Tc.Errors.Types: FunAppCtxt :: FunAppCtxtFunArg -> Int -> ErrCtxtMsg
+ GHC.Tc.Errors.Types: FunResCtxt :: HsExpr GhcTc -> Int -> Type -> Type -> Int -> Int -> ErrCtxtMsg
+ GHC.Tc.Errors.Types: FunTysCtxt :: ExpectedFunTyOrigin -> Type -> Int -> Int -> ErrCtxtMsg
+ GHC.Tc.Errors.Types: ImportLookupExtensions :: Bool -> Bool -> ImportLookupExtensions
+ GHC.Tc.Errors.Types: InferredTypeCtxt :: Name -> TcType -> ErrCtxtMsg
+ GHC.Tc.Errors.Types: InstDeclErrCtxt :: Either (LHsType GhcRn) PredType -> ErrCtxtMsg
+ GHC.Tc.Errors.Types: InstHeadNonClassHead :: InstHeadNonClassHead -> IllegalInstanceHeadReason
+ GHC.Tc.Errors.Types: InstNonClassTyCon :: WithUserRdr Name -> TyConFlavour Name -> InstHeadNonClassHead
+ GHC.Tc.Errors.Types: InstNonTyCon :: InstHeadNonClassHead
+ GHC.Tc.Errors.Types: InvisPatMisplaced :: BadInvisPatReason
+ GHC.Tc.Errors.Types: InvisPatNoForall :: BadInvisPatReason
+ GHC.Tc.Errors.Types: InvisPatWithoutFlag :: BadInvisPatReason
+ GHC.Tc.Errors.Types: KindCtxt :: LHsKind GhcRn -> ErrCtxtMsg
+ GHC.Tc.Errors.Types: LevelCheckInstance :: InstanceWhat -> PredType -> LevelCheckReason
+ GHC.Tc.Errors.Types: LevelCheckSplice :: Name -> Maybe GlobalRdrElt -> LevelCheckReason
+ GHC.Tc.Errors.Types: MainCtxt :: Name -> ErrCtxtMsg
+ GHC.Tc.Errors.Types: MatchCtxt :: HsMatchContextRn -> ErrCtxtMsg
+ GHC.Tc.Errors.Types: MatchInCtxt :: Match GhcRn body -> ErrCtxtMsg
+ GHC.Tc.Errors.Types: MergeSignaturesCtxt :: UnitState -> ModuleName -> [InstantiatedModule] -> ErrCtxtMsg
+ GHC.Tc.Errors.Types: MethSigCtxt :: Name -> TcType -> TcType -> ErrCtxtMsg
+ GHC.Tc.Errors.Types: MethodOfClass :: Subordinate
+ GHC.Tc.Errors.Types: MultiplicityCoercionsNotSupported :: TcSolverReportMsg
+ GHC.Tc.Errors.Types: PatCtxt :: Pat GhcRn -> ErrCtxtMsg
+ GHC.Tc.Errors.Types: PatMonoBindsCtxt :: LPat (GhcPass p) -> GRHSs GhcRn (LHsExpr GhcRn) -> ErrCtxtMsg
+ GHC.Tc.Errors.Types: PatSigErrCtxt :: TcType -> TcType -> ErrCtxtMsg
+ GHC.Tc.Errors.Types: PatSynDeclCtxt :: Name -> ErrCtxtMsg
+ GHC.Tc.Errors.Types: PatSynExportCtxt :: PatSyn -> ErrCtxtMsg
+ GHC.Tc.Errors.Types: PatSynRecSelExportCtxt :: PatSyn -> Name -> ErrCtxtMsg
+ GHC.Tc.Errors.Types: PatSynSigCtx :: [LocatedN RdrName] -> HsDocContext
+ GHC.Tc.Errors.Types: QuantifiedCtCtxt :: PredType -> ErrCtxtMsg
+ GHC.Tc.Errors.Types: RecordUpdCtxt :: NonEmpty ConLike -> [Name] -> [TyCoVar] -> ErrCtxtMsg
+ GHC.Tc.Errors.Types: ReifyInstancesCtx :: HsDocContext
+ GHC.Tc.Errors.Types: ReifyInstancesCtxt :: Name -> [Type] -> ErrCtxtMsg
+ GHC.Tc.Errors.Types: ResolvedNameInfo :: [GlobalRdrElt] -> RdrName -> Name -> ResolvedNameInfo
+ GHC.Tc.Errors.Types: RoleAnnotErrCtxt :: Name -> ErrCtxtMsg
+ GHC.Tc.Errors.Types: RuleCtxt :: FastString -> ErrCtxtMsg
+ GHC.Tc.Errors.Types: SigCtxt :: Sig GhcRn -> ErrCtxtMsg
+ GHC.Tc.Errors.Types: SpecECtx :: RdrName -> HsDocContext
+ GHC.Tc.Errors.Types: SpecPragmaCtxt :: Sig GhcRn -> ErrCtxtMsg
+ GHC.Tc.Errors.Types: SpecialiseSigCtx :: LocatedN RdrName -> HsDocContext
+ GHC.Tc.Errors.Types: StandaloneDerivCtxt :: LHsSigWcType GhcRn -> ErrCtxtMsg
+ GHC.Tc.Errors.Types: StaticFormCtxt :: LHsExpr GhcRn -> ErrCtxtMsg
+ GHC.Tc.Errors.Types: StmtErrCtxt :: HsStmtContextRn -> StmtLR GhcRn GhcRn body -> ErrCtxtMsg
+ GHC.Tc.Errors.Types: SubTypeCtxt :: TcType -> TcType -> ErrCtxtMsg
+ GHC.Tc.Errors.Types: SupplementaryImportErrors :: NonEmpty ImportError -> SupplementaryInfo
+ GHC.Tc.Errors.Types: SyntaxNameCtxt :: HsExpr GhcRn -> CtOrigin -> TcType -> SrcSpan -> ErrCtxtMsg
+ GHC.Tc.Errors.Types: TermLevelUseCtxt :: Name -> TermLevelUseCtxt -> ErrCtxtMsg
+ GHC.Tc.Errors.Types: ThetaCtxt :: UserTypeCtxt -> ThetaType -> ErrCtxtMsg
+ GHC.Tc.Errors.Types: TyConDeclCtxt :: Name -> TyConFlavour TyCon -> ErrCtxtMsg
+ GHC.Tc.Errors.Types: TyConInstCtxt :: Name -> TyConInstFlavour -> ErrCtxtMsg
+ GHC.Tc.Errors.Types: TySynErrCtxt :: TyCon -> ErrCtxtMsg
+ GHC.Tc.Errors.Types: TypeCtxt :: LHsType GhcRn -> ErrCtxtMsg
+ GHC.Tc.Errors.Types: TypedSpliceCtxt :: Maybe SplicePointName -> HsTypedSplice (GhcPass p) -> ErrCtxtMsg
+ GHC.Tc.Errors.Types: TypedSpliceResultCtxt :: LHsExpr GhcTc -> ErrCtxtMsg
+ GHC.Tc.Errors.Types: TypedTHBracketCtxt :: LHsExpr (GhcPass p) -> ErrCtxtMsg
+ GHC.Tc.Errors.Types: UntypedSpliceCtxt :: HsUntypedSplice GhcPs -> ErrCtxtMsg
+ GHC.Tc.Errors.Types: UntypedTHBracketCtxt :: HsQuote GhcPs -> ErrCtxtMsg
+ GHC.Tc.Errors.Types: UserSigCtxt :: UserTypeCtxt -> UserSigType GhcRn -> ErrCtxtMsg
+ GHC.Tc.Errors.Types: VDQWarningCtxt :: TcTyCon -> ErrCtxtMsg
+ GHC.Tc.Errors.Types: WL_Anything :: WhatLooking
+ GHC.Tc.Errors.Types: WL_ConLike :: WhatLooking
+ GHC.Tc.Errors.Types: WL_Constructor :: WhatLooking
+ GHC.Tc.Errors.Types: WL_None :: WhatLooking
+ GHC.Tc.Errors.Types: WL_RecField :: WhatLooking
+ GHC.Tc.Errors.Types: WL_Term :: WhatLooking
+ GHC.Tc.Errors.Types: WL_TermVariable :: WhatLooking
+ GHC.Tc.Errors.Types: WL_TyCon :: WhatLooking
+ GHC.Tc.Errors.Types: WL_TyCon_or_TermVar :: WhatLooking
+ GHC.Tc.Errors.Types: WL_TyVar :: WhatLooking
+ GHC.Tc.Errors.Types: WL_Type :: WhatLooking
+ GHC.Tc.Errors.Types: [TcRnBadlyLevelledType] :: Name -> Set ThLevelIndex -> ThLevelIndex -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnBadlyLevelled] :: LevelCheckReason -> Set ThLevelIndex -> ThLevelIndex -> Maybe ErrorItem -> DiagnosticReason -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnDuplicateNamedDefaultExport] :: TyCon -> IE GhcPs -> IE GhcPs -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnIllegalPunnedVarOccInTypeArgument] :: ResolvedNameInfo -> ResolvedNameInfo -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnRuleLhsEqualities] :: FastString -> LHsExpr GhcRn -> NonEmpty Ct -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnSpecSigShape] :: LHsExpr GhcPs -> TcRnMessage
+ GHC.Tc.Errors.Types: [UnusableUnpackPragma] :: BadFieldAnnotationReason
+ GHC.Tc.Errors.Types: [cannotResolve_relBinds] :: TcSolverReportMsg -> RelevantBindings
+ GHC.Tc.Errors.Types: [ddec_in_type_list] :: ErrCtxtMsg -> Bool
+ GHC.Tc.Errors.Types: [errInfoHints] :: ErrInfo -> [GhcHint]
+ GHC.Tc.Errors.Types: [frr_info_other_origin] :: FixedRuntimeRepErrorInfo -> Maybe CtOrigin
+ GHC.Tc.Errors.Types: [ile_explicit_namespaces] :: ImportLookupExtensions -> Bool
+ GHC.Tc.Errors.Types: [ile_pattern_synonyms] :: ImportLookupExtensions -> Bool
+ GHC.Tc.Errors.Types: [sr_hints] :: SolverReport -> [GhcHint]
+ GHC.Tc.Errors.Types: data BadInvisPatReason
+ GHC.Tc.Errors.Types: data ErrCtxtMsg
+ GHC.Tc.Errors.Types: data ImportLookupExtensions
+ GHC.Tc.Errors.Types: data InstHeadNonClassHead
+ GHC.Tc.Errors.Types: data LevelCheckReason
+ GHC.Tc.Errors.Types: data ResolvedNameInfo
+ GHC.Tc.Errors.Types: data Subordinate
+ GHC.Tc.Errors.Types: data SupplementaryInfo
+ GHC.Tc.Errors.Types: data WhatLooking
+ GHC.Tc.Errors.Types: instance GHC.Internal.Classes.Eq GHC.Tc.Errors.Types.AssociatedTyLastVarInKind
+ GHC.Tc.Errors.Types: instance GHC.Internal.Classes.Eq GHC.Tc.Errors.Types.AssociatedTyNotParamOverLastTyVar
+ GHC.Tc.Errors.Types: instance GHC.Internal.Classes.Eq GHC.Tc.Errors.Types.DeriveAnyClassEnabled
+ GHC.Tc.Errors.Types: instance GHC.Internal.Classes.Eq GHC.Tc.Errors.Types.Exported
+ GHC.Tc.Errors.Types: instance GHC.Internal.Classes.Eq GHC.Tc.Errors.Types.HasAssociatedDataFamInsts
+ GHC.Tc.Errors.Types: instance GHC.Internal.Classes.Eq GHC.Tc.Errors.Types.HasKinds
+ GHC.Tc.Errors.Types: instance GHC.Internal.Classes.Eq GHC.Tc.Errors.Types.HasWildcard
+ GHC.Tc.Errors.Types: instance GHC.Internal.Classes.Eq GHC.Tc.Errors.Types.SuggestPartialTypeSignatures
+ GHC.Tc.Errors.Types: instance GHC.Internal.Classes.Eq GHC.Tc.Errors.Types.SuggestUndecidableInstances
+ GHC.Tc.Errors.Types: instance GHC.Internal.Classes.Eq GHC.Tc.Errors.Types.UnsupportedCallConvention
+ GHC.Tc.Errors.Types: instance GHC.Internal.Classes.Eq GHC.Tc.Errors.Types.UsingGeneralizedNewtypeDeriving
+ GHC.Tc.Errors.Types: instance GHC.Internal.Classes.Eq GHC.Tc.Errors.Types.WhatLooking
+ GHC.Tc.Errors.Types: instance GHC.Internal.Generics.Generic GHC.Tc.Errors.Types.BadInvisPatReason
+ GHC.Tc.Errors.Types: instance GHC.Internal.Generics.Generic GHC.Tc.Errors.Types.ImportLookupExtensions
+ GHC.Tc.Errors.Types: instance GHC.Internal.Generics.Generic GHC.Tc.Errors.Types.Subordinate
+ GHC.Tc.Errors.Types: instance GHC.Internal.Show.Show GHC.Tc.Errors.Types.WhatLooking
+ GHC.Tc.Errors.Types: instance GHC.Utils.Outputable.Outputable GHC.Tc.Errors.Types.ResolvedNameInfo
+ GHC.Tc.Errors.Types: lookingForSubordinate :: GlobalRdrElt -> WhatLooking
+ GHC.Tc.Errors.Types: pprResolvedNameProvenance :: ResolvedNameInfo -> SDoc
+ GHC.Tc.Errors.Types: pprSubordinate :: Name -> Subordinate -> SDoc
+ GHC.Tc.Errors.Types.PromotionErr: TermLevelUseGRE :: GlobalRdrElt -> TermLevelUseCtxt
+ GHC.Tc.Errors.Types.PromotionErr: TermLevelUseTyVar :: TermLevelUseCtxt
+ GHC.Tc.Errors.Types.PromotionErr: data TermLevelUseCtxt
+ GHC.Tc.Errors.Types.PromotionErr: instance GHC.Internal.Generics.Generic GHC.Tc.Errors.Types.PromotionErr.TermLevelUseCtxt
+ GHC.Tc.Errors.Types.PromotionErr: pprTermLevelUseCtxt :: Name -> TermLevelUseCtxt -> SDoc
+ GHC.Tc.Gen.Default: extendDefaultEnvWithLocalDefaults :: [LocatedA ClassDefaults] -> TcM a -> TcM a
+ GHC.Tc.Gen.Default: tcDefaultDecls :: [LDefaultDecl GhcRn] -> TcM [LocatedA ClassDefaults]
+ GHC.Tc.Gen.Expr: tcInferExpr :: InferInstFlag -> LHsExpr GhcRn -> TcM (LHsExpr GhcTc, TcType)
+ GHC.Tc.Gen.Expr: tcInferSigma :: LHsExpr GhcRn -> TcM (LHsExpr GhcTc, TcSigmaType)
+ GHC.Tc.Gen.Head: tcInferConLike :: ConLike -> TcM (HsExpr GhcTc, TcSigmaType)
+ GHC.Tc.Gen.HsType: RuleBndrTypeCtxt :: Name -> UserTypeCtxt
+ GHC.Tc.Gen.HsType: maybeEtaExpandAlgTyCon :: TyConFlavour tc -> SkolemInfo -> [TcTyConBinder] -> Kind -> TcM ([TcTyConBinder], Kind)
+ GHC.Tc.Gen.HsType: tcGadtConTyVarBndrs :: SkolemInfo -> HsOuterSigTyVarBndrs GhcRn -> [HsForAllTelescope GhcRn] -> TcM a -> TcM ([TcTyVarBinder], a)
+ GHC.Tc.Gen.HsType: tcRuleBndrSig :: Name -> SkolemInfo -> HsPatSigType GhcRn -> TcM ([(Name, TcTyVar)], [(Name, TcTyVar)], TcType)
+ GHC.Tc.Gen.Match: tcGRHSNE :: AnnoBody body => HsMatchContextRn -> TcMatchAltChecker body -> NonEmpty (LGRHS GhcRn (LocatedA (body GhcRn))) -> ExpRhoType -> TcM (NonEmpty (LGRHS GhcTc (LocatedA (body GhcTc))))
+ GHC.Tc.Gen.Sig: tcRules :: [LRuleDecls GhcRn] -> TcM [LRuleDecls GhcTc]
+ GHC.Tc.Instance.Class: lookupHasFieldLabel :: FamInstEnvs -> GlobalRdrEnv -> [Type] -> Maybe (Name, GlobalRdrElt, Type, Type)
+ GHC.Tc.Module: tcRnTypeSkolemising :: HscEnv -> LHsType GhcPs -> IO (Messages TcRnMessage, Maybe (Type, Kind))
+ GHC.Tc.Plugin: lookupTHName :: Name -> TcPluginM (Maybe Name)
+ GHC.Tc.Solver: emitResidualConstraints :: TcLevel -> SkolemInfoAnon -> EvBindsVar -> CoVarSet -> [TcTyVar] -> [EvVar] -> WantedConstraints -> TcM ()
+ GHC.Tc.Solver.Default: instance GHC.Utils.Outputable.Outputable GHC.Tc.Solver.Default.Proposal
+ GHC.Tc.Solver.Default: instance GHC.Utils.Outputable.Outputable GHC.Tc.Solver.Default.ProposalSequence
+ GHC.Tc.Solver.Default: isInteractiveClass :: Bool -> Class -> Bool
+ GHC.Tc.Solver.Default: isNumClass :: Bool -> Class -> Bool
+ GHC.Tc.Solver.Default: tryDefaulting :: WantedConstraints -> TcS WantedConstraints
+ GHC.Tc.Solver.Default: tryDefaultingForAmbiguityCheck :: WantedConstraints -> TcS WantedConstraints
+ GHC.Tc.Solver.InertSet: [inert_givens] :: InertSet -> InertCans
+ GHC.Tc.Solver.InertSet: [inert_qcis] :: InertCans -> [QCInst]
+ GHC.Tc.Solver.InertSet: emptyInertCans :: TcLevel -> InertCans
+ GHC.Tc.Solver.InertSet: emptyInertSet :: TcLevel -> InertSet
+ GHC.Tc.Solver.InertSet: extendWorkListChildEqs :: CtEvidence -> Bag Ct -> WorkList -> WorkList
+ GHC.Tc.Solver.InertSet: extendWorkListRewrittenEqs :: [EqCt] -> WorkList -> WorkList
+ GHC.Tc.Solver.InertSet: filterFunEqs :: (EqCt -> Bool) -> InertFunEqs -> InertFunEqs
+ GHC.Tc.Solver.InertSet: filterInertEqs :: (EqCt -> Bool) -> InertEqs -> InertEqs
+ GHC.Tc.Solver.InertSet: instance GHC.Internal.Classes.Eq GHC.Tc.Solver.InertSet.WhereToLook
+ GHC.Tc.Solver.InertSet: lookupInertDict :: InertCans -> Class -> [Type] -> Maybe DictCt
+ GHC.Tc.Solver.InertSet: lookupSolvedDict :: InertSet -> Class -> [Type] -> Maybe CtEvidence
+ GHC.Tc.Solver.Monad: TcS :: (TcSEnv -> TcM a) -> TcS a
+ GHC.Tc.Solver.Monad: TcSEnv :: EvBindsVar -> IORef Int -> IORef (Maybe TcLevel) -> IORef Int -> IORef InertSet -> TcSMode -> IORef WorkList -> TcSEnv
+ GHC.Tc.Solver.Monad: TcSMode :: Bool -> Bool -> Bool -> Bool -> TcSMode
+ GHC.Tc.Solver.Monad: [qci_body] :: QCInst -> TcPredType
+ GHC.Tc.Solver.Monad: [qci_theta] :: QCInst -> TcThetaType
+ GHC.Tc.Solver.Monad: [tcs_count] :: TcSEnv -> IORef Int
+ GHC.Tc.Solver.Monad: [tcs_ev_binds] :: TcSEnv -> EvBindsVar
+ GHC.Tc.Solver.Monad: [tcs_inerts] :: TcSEnv -> IORef InertSet
+ GHC.Tc.Solver.Monad: [tcs_mode] :: TcSEnv -> TcSMode
+ GHC.Tc.Solver.Monad: [tcs_unif_lvl] :: TcSEnv -> IORef (Maybe TcLevel)
+ GHC.Tc.Solver.Monad: [tcs_unified] :: TcSEnv -> IORef Int
+ GHC.Tc.Solver.Monad: [tcs_worklist] :: TcSEnv -> IORef WorkList
+ GHC.Tc.Solver.Monad: [tcsmEarlyAbort] :: TcSMode -> Bool
+ GHC.Tc.Solver.Monad: [tcsmFullySolveQCIs] :: TcSMode -> Bool
+ GHC.Tc.Solver.Monad: [tcsmResumable] :: TcSMode -> Bool
+ GHC.Tc.Solver.Monad: [tcsmSkipOverlappable] :: TcSMode -> Bool
+ GHC.Tc.Solver.Monad: [unTcS] :: TcS a -> TcSEnv -> TcM a
+ GHC.Tc.Solver.Monad: addInertQCI :: QCInst -> TcS ()
+ GHC.Tc.Solver.Monad: checkWellLevelledDFun :: CtLoc -> InstanceWhat -> PredType -> TcS ()
+ GHC.Tc.Solver.Monad: data TcSEnv
+ GHC.Tc.Solver.Monad: data TcSMode
+ GHC.Tc.Solver.Monad: getTcSMode :: TcS TcSMode
+ GHC.Tc.Solver.Monad: getUnifiedRef :: TcS (IORef Int)
+ GHC.Tc.Solver.Monad: instance GHC.Utils.Outputable.Outputable GHC.Tc.Solver.Monad.TcSMode
+ GHC.Tc.Solver.Monad: newtype TcS a
+ GHC.Tc.Solver.Monad: setTcLevelTcS :: TcLevel -> TcS a -> TcS a
+ GHC.Tc.Solver.Monad: setTcSMode :: TcSMode -> TcS a -> TcS a
+ GHC.Tc.Solver.Monad: tryShortCutTcS :: TcS Bool -> TcS Bool
+ GHC.Tc.Solver.Monad: updInertDicts :: DictCt -> TcS ()
+ GHC.Tc.Solver.Monad: updInertIrreds :: IrredCt -> TcS ()
+ GHC.Tc.Solver.Monad: vanillaTcSMode :: TcSMode
+ GHC.Tc.Solver.Monad: wrapUnifierX :: CtEvidence -> Role -> (UnifyEnv -> TcM a) -> TcS (a, Bag Ct, [TcTyVar])
+ GHC.Tc.Solver.Solve: setImplicationStatus :: Implication -> TcS Implication
+ GHC.Tc.Solver.Solve: simplifyWantedsTcM :: [CtEvidence] -> TcM WantedConstraints
+ GHC.Tc.Solver.Solve: solveWanteds :: WantedConstraints -> TcS WantedConstraints
+ GHC.Tc.Solver.Solve: trySolveImplication :: Implication -> TcS Bool
+ GHC.Tc.Solver.Types: mapMaybeTcAppMap :: (a -> Maybe b) -> TcAppMap a -> TcAppMap b
+ GHC.Tc.TyCl: IsNotPrefixConGADT :: IsPrefixConGADT
+ GHC.Tc.TyCl: IsPrefixConGADT :: IsPrefixConGADT
+ GHC.Tc.TyCl: data IsPrefixConGADT
+ GHC.Tc.TyCl: instance GHC.Internal.Base.Monoid GHC.Tc.TyCl.TcTyClGroupsAccum
+ GHC.Tc.TyCl: instance GHC.Internal.Base.Semigroup GHC.Tc.TyCl.TcTyClGroupsAccum
+ GHC.Tc.TyCl: instance GHC.Internal.Classes.Eq GHC.Tc.TyCl.IsPrefixConGADT
+ GHC.Tc.TyCl: instance GHC.Utils.Outputable.Outputable GHC.Tc.TyCl.TcTyClGroupsStats
+ GHC.Tc.TyCl: tcAddOpenTyFamInstCtxt :: AssocInstInfo -> TyFamInstDecl GhcRn -> TcM a -> TcM a
+ GHC.Tc.TyCl: unannotatedMultIsLinear :: IsPrefixConGADT -> TcRnIf gbl lcl Bool
+ GHC.Tc.TyCl.Build: buildAbstractClass :: Name -> [TyConBinder] -> [Role] -> [FunDep TyVar] -> TcRnIf m n Class
+ GHC.Tc.Types: RnPending :: TcRef [PendingRnSplice] -> PendingStuff
+ GHC.Tc.Types: [iul_avails] :: ImpUserList -> [AvailInfo]
+ GHC.Tc.Types: [iul_non_explicit_parents] :: ImpUserList -> NameSet
+ GHC.Tc.Types: [tcg_complete_match_env] :: TcGblEnv -> CompleteMatches
+ GHC.Tc.Types: data ThLevel
+ GHC.Tc.Types: data ThLevelIndex
+ GHC.Tc.Types: instance GHC.Internal.Classes.Eq GHC.Tc.Types.DocLoc
+ GHC.Tc.Types: instance GHC.Internal.Classes.Ord GHC.Tc.Types.DocLoc
+ GHC.Tc.Types: pattern TypedBrack :: ThLevel -> ThLevel
+ GHC.Tc.Types: pattern UntypedBrack :: ThLevel -> TcRef [PendingRnSplice] -> ThLevel
+ GHC.Tc.Types: quoteLevelIndex :: ThLevelIndex
+ GHC.Tc.Types: spliceLevelIndex :: ThLevelIndex
+ GHC.Tc.Types: thLevelIndex :: ThLevel -> ThLevelIndex
+ GHC.Tc.Types: topAnnLevel :: ThLevel
+ GHC.Tc.Types: topLevel :: ThLevel
+ GHC.Tc.Types: topLevelIndex :: ThLevelIndex
+ GHC.Tc.Types: topSpliceLevel :: ThLevel
+ GHC.Tc.Types.Constraint: DE_Multiplicity :: TcCoercion -> CtLoc -> DelayedError
+ GHC.Tc.Types.Constraint: ENS :: VarSet -> VarSet -> EvNeedSet
+ GHC.Tc.Types.Constraint: GivenCt :: TcPredType -> EvVar -> CtLoc -> GivenCtEvidence
+ GHC.Tc.Types.Constraint: WantedCt :: TcPredType -> TcEvDest -> CtLoc -> RewriterSet -> WantedCtEvidence
+ GHC.Tc.Types.Constraint: [ens_dms] :: EvNeedSet -> VarSet
+ GHC.Tc.Types.Constraint: [ens_fvs] :: EvNeedSet -> VarSet
+ GHC.Tc.Types.Constraint: [ic_need] :: Implication -> EvNeedSet
+ GHC.Tc.Types.Constraint: [ic_need_implic] :: Implication -> EvNeedSet
+ GHC.Tc.Types.Constraint: [qci_body] :: QCInst -> TcPredType
+ GHC.Tc.Types.Constraint: [qci_theta] :: QCInst -> TcThetaType
+ GHC.Tc.Types.Constraint: addMultiplicityCoercionError :: WantedConstraints -> TcCoercion -> CtLoc -> WantedConstraints
+ GHC.Tc.Types.Constraint: approximateWC :: Bool -> WantedConstraints -> Bag Ct
+ GHC.Tc.Types.Constraint: approximateWCX :: Bool -> WantedConstraints -> ApproxWC
+ GHC.Tc.Types.Constraint: ctHasNoRewriters :: Ct -> Bool
+ GHC.Tc.Types.Constraint: data EvNeedSet
+ GHC.Tc.Types.Constraint: data GivenCtEvidence
+ GHC.Tc.Types.Constraint: data WantedCtEvidence
+ GHC.Tc.Types.Constraint: delGivensFromEvNeedSet :: EvNeedSet -> [Var] -> EvNeedSet
+ GHC.Tc.Types.Constraint: emptyEvNeedSet :: EvNeedSet
+ GHC.Tc.Types.Constraint: extendEvNeedSet :: EvNeedSet -> Var -> EvNeedSet
+ GHC.Tc.Types.Constraint: givenCtEvCoercion :: GivenCtEvidence -> TcCoercion
+ GHC.Tc.Types.Constraint: instance GHC.Internal.Classes.Eq GHC.Tc.Types.Constraint.CheckTyEqProblem
+ GHC.Tc.Types.Constraint: instance GHC.Internal.Classes.Eq GHC.Tc.Types.Constraint.CtFlavour
+ GHC.Tc.Types.Constraint: instance GHC.Internal.Classes.Eq GHC.Tc.Types.Constraint.HasGivenEqs
+ GHC.Tc.Types.Constraint: instance GHC.Utils.Outputable.Outputable GHC.Tc.Types.Constraint.EvNeedSet
+ GHC.Tc.Types.Constraint: instance GHC.Utils.Outputable.Outputable GHC.Tc.Types.Constraint.GivenCtEvidence
+ GHC.Tc.Types.Constraint: instance GHC.Utils.Outputable.Outputable GHC.Tc.Types.Constraint.WantedCtEvidence
+ GHC.Tc.Types.Constraint: setWantedCtEvRewriters :: WantedCtEvidence -> RewriterSet -> WantedCtEvidence
+ GHC.Tc.Types.Constraint: unionEvNeedSet :: EvNeedSet -> EvNeedSet -> EvNeedSet
+ GHC.Tc.Types.Constraint: wantedCtEvEvId :: WantedCtEvidence -> EvVar
+ GHC.Tc.Types.Constraint: wantedCtHasNoRewriters :: WantedCtEvidence -> Bool
+ GHC.Tc.Types.CtLoc: instance GHC.Internal.Classes.Eq GHC.Tc.Types.CtLoc.SubGoalDepth
+ GHC.Tc.Types.CtLoc: instance GHC.Internal.Classes.Ord GHC.Tc.Types.CtLoc.SubGoalDepth
+ GHC.Tc.Types.ErrCtxt: AmbiguityCheckCtxt :: UserTypeCtxt -> Bool -> ErrCtxtMsg
+ GHC.Tc.Types.ErrCtxt: AnnCtxt :: AnnDecl (GhcPass p) -> ErrCtxtMsg
+ GHC.Tc.Types.ErrCtxt: CheckImplementsCtxt :: UnitState -> Module -> InstantiatedModule -> ErrCtxtMsg
+ GHC.Tc.Types.ErrCtxt: ClassOpCtxt :: Id -> Type -> ErrCtxtMsg
+ GHC.Tc.Types.ErrCtxt: ClosedFamEqnCtxt :: TyCon -> ErrCtxtMsg
+ GHC.Tc.Types.ErrCtxt: CmdCtxt :: HsCmd GhcRn -> ErrCtxtMsg
+ GHC.Tc.Types.ErrCtxt: DataConDefCtxt :: NonEmpty (LocatedN Name) -> ErrCtxtMsg
+ GHC.Tc.Types.ErrCtxt: DataConResTyCtxt :: NonEmpty (LocatedN Name) -> ErrCtxtMsg
+ GHC.Tc.Types.ErrCtxt: DefaultDeclErrCtxt :: Bool -> ErrCtxtMsg
+ GHC.Tc.Types.ErrCtxt: DerivBindCtxt :: Id -> Class -> [Type] -> ErrCtxtMsg
+ GHC.Tc.Types.ErrCtxt: DerivInstCtxt :: PredType -> ErrCtxtMsg
+ GHC.Tc.Types.ErrCtxt: ExportCtxt :: IE (GhcPass p) -> ErrCtxtMsg
+ GHC.Tc.Types.ErrCtxt: ExprCtxt :: HsExpr GhcRn -> ErrCtxtMsg
+ GHC.Tc.Types.ErrCtxt: FieldCtxt :: FieldLabelString -> ErrCtxtMsg
+ GHC.Tc.Types.ErrCtxt: ForeignDeclCtxt :: ForeignDecl GhcRn -> ErrCtxtMsg
+ GHC.Tc.Types.ErrCtxt: FunAppCtxt :: FunAppCtxtFunArg -> Int -> ErrCtxtMsg
+ GHC.Tc.Types.ErrCtxt: FunAppCtxtExpr :: HsExpr GhcRn -> HsExpr GhcRn -> FunAppCtxtFunArg
+ GHC.Tc.Types.ErrCtxt: FunAppCtxtTy :: LHsType GhcRn -> LHsType GhcRn -> FunAppCtxtFunArg
+ GHC.Tc.Types.ErrCtxt: FunResCtxt :: HsExpr GhcTc -> Int -> Type -> Type -> Int -> Int -> ErrCtxtMsg
+ GHC.Tc.Types.ErrCtxt: FunTysCtxt :: ExpectedFunTyOrigin -> Type -> Int -> Int -> ErrCtxtMsg
+ GHC.Tc.Types.ErrCtxt: InferredTypeCtxt :: Name -> TcType -> ErrCtxtMsg
+ GHC.Tc.Types.ErrCtxt: InstDeclErrCtxt :: Either (LHsType GhcRn) PredType -> ErrCtxtMsg
+ GHC.Tc.Types.ErrCtxt: KindCtxt :: LHsKind GhcRn -> ErrCtxtMsg
+ GHC.Tc.Types.ErrCtxt: MainCtxt :: Name -> ErrCtxtMsg
+ GHC.Tc.Types.ErrCtxt: MatchCtxt :: HsMatchContextRn -> ErrCtxtMsg
+ GHC.Tc.Types.ErrCtxt: MatchInCtxt :: Match GhcRn body -> ErrCtxtMsg
+ GHC.Tc.Types.ErrCtxt: MergeSignaturesCtxt :: UnitState -> ModuleName -> [InstantiatedModule] -> ErrCtxtMsg
+ GHC.Tc.Types.ErrCtxt: MethSigCtxt :: Name -> TcType -> TcType -> ErrCtxtMsg
+ GHC.Tc.Types.ErrCtxt: PatCtxt :: Pat GhcRn -> ErrCtxtMsg
+ GHC.Tc.Types.ErrCtxt: PatMonoBindsCtxt :: LPat (GhcPass p) -> GRHSs GhcRn (LHsExpr GhcRn) -> ErrCtxtMsg
+ GHC.Tc.Types.ErrCtxt: PatSigErrCtxt :: TcType -> TcType -> ErrCtxtMsg
+ GHC.Tc.Types.ErrCtxt: PatSynDeclCtxt :: Name -> ErrCtxtMsg
+ GHC.Tc.Types.ErrCtxt: PatSynExportCtxt :: PatSyn -> ErrCtxtMsg
+ GHC.Tc.Types.ErrCtxt: PatSynRecSelExportCtxt :: PatSyn -> Name -> ErrCtxtMsg
+ GHC.Tc.Types.ErrCtxt: QuantifiedCtCtxt :: PredType -> ErrCtxtMsg
+ GHC.Tc.Types.ErrCtxt: RecordUpdCtxt :: NonEmpty ConLike -> [Name] -> [TyCoVar] -> ErrCtxtMsg
+ GHC.Tc.Types.ErrCtxt: ReifyInstancesCtxt :: Name -> [Type] -> ErrCtxtMsg
+ GHC.Tc.Types.ErrCtxt: RoleAnnotErrCtxt :: Name -> ErrCtxtMsg
+ GHC.Tc.Types.ErrCtxt: RuleCtxt :: FastString -> ErrCtxtMsg
+ GHC.Tc.Types.ErrCtxt: SigCtxt :: Sig GhcRn -> ErrCtxtMsg
+ GHC.Tc.Types.ErrCtxt: SpecPragmaCtxt :: Sig GhcRn -> ErrCtxtMsg
+ GHC.Tc.Types.ErrCtxt: StandaloneDerivCtxt :: LHsSigWcType GhcRn -> ErrCtxtMsg
+ GHC.Tc.Types.ErrCtxt: StaticFormCtxt :: LHsExpr GhcRn -> ErrCtxtMsg
+ GHC.Tc.Types.ErrCtxt: StmtErrCtxt :: HsStmtContextRn -> StmtLR GhcRn GhcRn body -> ErrCtxtMsg
+ GHC.Tc.Types.ErrCtxt: SubTypeCtxt :: TcType -> TcType -> ErrCtxtMsg
+ GHC.Tc.Types.ErrCtxt: SyntaxNameCtxt :: HsExpr GhcRn -> CtOrigin -> TcType -> SrcSpan -> ErrCtxtMsg
+ GHC.Tc.Types.ErrCtxt: TermLevelUseCtxt :: Name -> TermLevelUseCtxt -> ErrCtxtMsg
+ GHC.Tc.Types.ErrCtxt: ThetaCtxt :: UserTypeCtxt -> ThetaType -> ErrCtxtMsg
+ GHC.Tc.Types.ErrCtxt: TyConDeclCtxt :: Name -> TyConFlavour TyCon -> ErrCtxtMsg
+ GHC.Tc.Types.ErrCtxt: TyConInstCtxt :: Name -> TyConInstFlavour -> ErrCtxtMsg
+ GHC.Tc.Types.ErrCtxt: TyConInstFlavour :: TyConFlavour TyCon -> Bool -> TyConInstFlavour
+ GHC.Tc.Types.ErrCtxt: TySynErrCtxt :: TyCon -> ErrCtxtMsg
+ GHC.Tc.Types.ErrCtxt: TypeCtxt :: LHsType GhcRn -> ErrCtxtMsg
+ GHC.Tc.Types.ErrCtxt: TypedSpliceCtxt :: Maybe SplicePointName -> HsTypedSplice (GhcPass p) -> ErrCtxtMsg
+ GHC.Tc.Types.ErrCtxt: TypedSpliceResultCtxt :: LHsExpr GhcTc -> ErrCtxtMsg
+ GHC.Tc.Types.ErrCtxt: TypedTHBracketCtxt :: LHsExpr (GhcPass p) -> ErrCtxtMsg
+ GHC.Tc.Types.ErrCtxt: UntypedSpliceCtxt :: HsUntypedSplice GhcPs -> ErrCtxtMsg
+ GHC.Tc.Types.ErrCtxt: UntypedTHBracketCtxt :: HsQuote GhcPs -> ErrCtxtMsg
+ GHC.Tc.Types.ErrCtxt: UserLHsSigType :: LHsSigType p -> UserSigType p
+ GHC.Tc.Types.ErrCtxt: UserLHsType :: LHsType p -> UserSigType p
+ GHC.Tc.Types.ErrCtxt: UserSigCtxt :: UserTypeCtxt -> UserSigType GhcRn -> ErrCtxtMsg
+ GHC.Tc.Types.ErrCtxt: VDQWarningCtxt :: TcTyCon -> ErrCtxtMsg
+ GHC.Tc.Types.ErrCtxt: [ddec_in_type_list] :: ErrCtxtMsg -> Bool
+ GHC.Tc.Types.ErrCtxt: [tyConInstFlavour] :: TyConInstFlavour -> TyConFlavour TyCon
+ GHC.Tc.Types.ErrCtxt: [tyConInstIsDefault] :: TyConInstFlavour -> Bool
+ GHC.Tc.Types.ErrCtxt: data ErrCtxtMsg
+ GHC.Tc.Types.ErrCtxt: data FunAppCtxtFunArg
+ GHC.Tc.Types.ErrCtxt: data TyConInstFlavour
+ GHC.Tc.Types.ErrCtxt: data UserSigType p
+ GHC.Tc.Types.ErrCtxt: instance GHC.Hs.Extension.OutputableBndrId p => GHC.Utils.Outputable.Outputable (GHC.Tc.Types.ErrCtxt.UserSigType (GHC.Hs.Extension.GhcPass p))
+ GHC.Tc.Types.Evidence: evCastE :: EvExpr -> TcCoercion -> EvExpr
+ GHC.Tc.Types.Evidence: evDelayedError :: Type -> String -> EvTerm
+ GHC.Tc.Types.Evidence: evDictApp :: Class -> [Type] -> [EvExpr] -> EvTerm
+ GHC.Tc.Types.Evidence: evExprCoercion :: EvExpr -> TcCoercion
+ GHC.Tc.Types.Evidence: evExprCoercion_maybe :: EvExpr -> Maybe TcCoercion
+ GHC.Tc.Types.Evidence: evTermFVs :: EvTerm -> FV
+ GHC.Tc.Types.Evidence: evUnaryDictAppE :: Class -> [Type] -> EvExpr -> EvExpr
+ GHC.Tc.Types.Evidence: evUnwrapIPE :: PredType -> EvExpr -> EvExpr
+ GHC.Tc.Types.Evidence: evWrapIPE :: PredType -> EvExpr -> EvExpr
+ GHC.Tc.Types.Evidence: instance GHC.Internal.Data.Data.Data GHC.Tc.Types.Evidence.EvBind
+ GHC.Tc.Types.Evidence: nestedEvIdsOfTerm :: EvTerm -> VarSet
+ GHC.Tc.Types.Evidence: unionEvBindMap :: EvBindMap -> EvBindMap -> EvBindMap
+ GHC.Tc.Types.LclEnv: getLclEnvThLevel :: TcLclEnv -> ThLevel
+ GHC.Tc.Types.LclEnv: setLclEnvThLevel :: ThLevel -> TcLclEnv -> TcLclEnv
+ GHC.Tc.Types.Origin: DerivOrigin :: StandaloneDeriv -> CtOrigin
+ GHC.Tc.Types.Origin: FRRDeepSubsumption :: Bool -> Position p -> FixedRuntimeRepContext
+ GHC.Tc.Types.Origin: GetFieldOrigin :: FastString -> CtOrigin
+ GHC.Tc.Types.Origin: HsImplicitLiftSplice :: Set ThLevelIndex -> ThLevelIndex -> Maybe GlobalRdrElt -> LIdOccP GhcRn -> HsImplicitLiftSplice
+ GHC.Tc.Types.Origin: ImplicitLiftOrigin :: HsImplicitLiftSplice -> CtOrigin
+ GHC.Tc.Types.Origin: MethSkol :: Name -> Bool -> SkolemInfoAnon
+ GHC.Tc.Types.Origin: RuleBndrTypeCtxt :: Name -> UserTypeCtxt
+ GHC.Tc.Types.Origin: SpecESkol :: Name -> SkolemInfoAnon
+ GHC.Tc.Types.Origin: [frrDSExpected] :: FixedRuntimeRepContext -> Bool
+ GHC.Tc.Types.Origin: [frrDSPosition] :: FixedRuntimeRepContext -> Position p
+ GHC.Tc.Types.Origin: [implicit_lift_bind_lvl] :: HsImplicitLiftSplice -> Set ThLevelIndex
+ GHC.Tc.Types.Origin: [implicit_lift_gre] :: HsImplicitLiftSplice -> Maybe GlobalRdrElt
+ GHC.Tc.Types.Origin: [implicit_lift_lid] :: HsImplicitLiftSplice -> LIdOccP GhcRn
+ GHC.Tc.Types.Origin: [implicit_lift_used_lvl] :: HsImplicitLiftSplice -> ThLevelIndex
+ GHC.Tc.Types.Origin: data HsImplicitLiftSplice
+ GHC.Tc.Types.Origin: instance GHC.Internal.Classes.Eq GHC.Tc.Types.Origin.ReportRedundantConstraints
+ GHC.Tc.Types.Origin: instance GHC.Internal.Classes.Eq GHC.Tc.Types.Origin.UserTypeCtxt
+ GHC.Tc.Types.Origin: instance GHC.Internal.Show.Show (GHC.Tc.Types.Origin.Position p)
+ GHC.Tc.Types.Origin: instance GHC.Utils.Outputable.Outputable (GHC.Tc.Types.Origin.Position p)
+ GHC.Tc.Types.Origin: isPushCallStackOrigin_maybe :: CtOrigin -> Maybe FastString
+ GHC.Tc.Types.Origin: mkArgPos :: forall (p :: Polarity). Int -> Position p -> Position (FlipPolarity p)
+ GHC.Tc.Types.Origin: pprCtOriginBriefly :: CtOrigin -> SDoc
+ GHC.Tc.Types.Origin: type StandaloneDeriv = Bool
+ GHC.Tc.Types.TH: RnPending :: TcRef [PendingRnSplice] -> PendingStuff
+ GHC.Tc.Types.TH: data ThLevel
+ GHC.Tc.Types.TH: data ThLevelIndex
+ GHC.Tc.Types.TH: instance GHC.Utils.Outputable.Outputable GHC.Tc.Types.TH.ThLevel
+ GHC.Tc.Types.TH: pattern TypedBrack :: ThLevel -> ThLevel
+ GHC.Tc.Types.TH: pattern UntypedBrack :: ThLevel -> TcRef [PendingRnSplice] -> ThLevel
+ GHC.Tc.Types.TH: quoteLevelIndex :: ThLevelIndex
+ GHC.Tc.Types.TH: spliceLevelIndex :: ThLevelIndex
+ GHC.Tc.Types.TH: thLevelIndex :: ThLevel -> ThLevelIndex
+ GHC.Tc.Types.TH: thLevelIndexFromImportLevel :: ImportLevel -> ThLevelIndex
+ GHC.Tc.Types.TH: topAnnLevel :: ThLevel
+ GHC.Tc.Types.TH: topLevel :: ThLevel
+ GHC.Tc.Types.TH: topLevelIndex :: ThLevelIndex
+ GHC.Tc.Types.TH: topSpliceLevel :: ThLevel
+ GHC.Tc.Utils.Env: LevelCheckInstance :: InstanceWhat -> PredType -> LevelCheckReason
+ GHC.Tc.Utils.Env: LevelCheckSplice :: Name -> Maybe GlobalRdrElt -> LevelCheckReason
+ GHC.Tc.Utils.Env: data LevelCheckReason
+ GHC.Tc.Utils.Env: failIllegalTyVar :: WithUserRdr Name -> TcM a
+ GHC.Tc.Utils.Env: isBrackLevel :: ThLevel -> Bool
+ GHC.Tc.Utils.Env: thLevelIndex :: ThLevel -> ThLevelIndex
+ GHC.Tc.Utils.Monad: addTcEvBinds :: EvBindsVar -> EvBindMap -> TcM ()
+ GHC.Tc.Utils.Monad: checkJustTc :: TcRnMessage -> Maybe a -> TcM a
+ GHC.Tc.Utils.Monad: checkJustTcM :: (TidyEnv, TcRnMessage) -> Maybe a -> TcM a
+ GHC.Tc.Utils.Monad: ensureReflMultiplicityCo :: TcCoercion -> CtOrigin -> TcM ()
+ GHC.Tc.Utils.Monad: getCurrentAndBindLevel :: Name -> TcRn (Maybe (TopLevelFlag, Set ThLevelIndex, ThLevel))
+ GHC.Tc.Utils.Monad: getThLevel :: TcM ThLevel
+ GHC.Tc.Utils.Monad: mkErrCtxt :: TidyEnv -> [ErrCtxt] -> TcM [ErrCtxtMsg]
+ GHC.Tc.Utils.Monad: setThLevel :: ThLevel -> TcM a -> TcRn a
+ GHC.Tc.Utils.Monad: setWOptM :: WarningFlag -> TcRnIf gbl lcl a -> TcRnIf gbl lcl a
+ GHC.Tc.Utils.Monad: tryTcDiscardingErrs' :: (WantedConstraints -> Messages TcRnMessage -> r -> Bool) -> TcM r -> TcM r -> TcM r -> TcM r
+ GHC.Tc.Utils.Monad: updTcEvBinds :: EvBindsVar -> EvBindsVar -> TcM ()
+ GHC.Tc.Utils.Monad: updTopEnvIO :: (HscEnv -> IO HscEnv) -> TcRnIf gbl lcl a -> TcRnIf gbl lcl a
+ GHC.Tc.Utils.TcMType: runInfer :: InferInstFlag -> InferFRRFlag -> (ExpSigmaType -> TcM a) -> TcM (a, TcSigmaType)
+ GHC.Tc.Utils.TcMType: runInferKind :: (ExpSigmaType -> TcM a) -> TcM (a, TcSigmaType)
+ GHC.Tc.Utils.TcMType: runInferRho :: (ExpRhoType -> TcM a) -> TcM (a, TcRhoType)
+ GHC.Tc.Utils.TcMType: runInferRhoFRR :: FixedRuntimeRepContext -> (ExpRhoTypeFRR -> TcM a) -> TcM (a, TcRhoTypeFRR)
+ GHC.Tc.Utils.TcMType: runInferSigma :: (ExpSigmaType -> TcM a) -> TcM (a, TcSigmaType)
+ GHC.Tc.Utils.TcMType: runInferSigmaFRR :: FixedRuntimeRepContext -> (ExpSigmaTypeFRR -> TcM a) -> TcM (a, TcSigmaTypeFRR)
+ GHC.Tc.Utils.TcMType: weedOutCandidates :: (DTyVarSet -> DTyVarSet) -> CandidatesQTvs -> CandidatesQTvs
+ GHC.Tc.Utils.TcType: IFRR_Any :: InferFRRFlag
+ GHC.Tc.Utils.TcType: IFRR_Check :: FixedRuntimeRepContext -> InferFRRFlag
+ GHC.Tc.Utils.TcType: IIF_DeepRho :: InferInstFlag
+ GHC.Tc.Utils.TcType: IIF_ShallowRho :: InferInstFlag
+ GHC.Tc.Utils.TcType: IIF_Sigma :: InferInstFlag
+ GHC.Tc.Utils.TcType: [ir_inst] :: InferResult -> InferInstFlag
+ GHC.Tc.Utils.TcType: concreteInfo_maybe :: MetaInfo -> Maybe ConcreteTvOrigin
+ GHC.Tc.Utils.TcType: couldBeIPLike :: Type -> Bool
+ GHC.Tc.Utils.TcType: data InferFRRFlag
+ GHC.Tc.Utils.TcType: data InferInstFlag
+ GHC.Tc.Utils.TcType: isAnyTy :: Type -> Bool
+ GHC.Tc.Utils.TcType: isEqClassPred :: PredType -> Bool
+ GHC.Tc.Utils.TcType: isSimplePredTy :: HasDebugCallStack => Type -> Bool
+ GHC.Tc.Utils.TcType: isZonkAnyTy :: Type -> Bool
+ GHC.Tc.Utils.TcType: pSizeHead :: PredType -> PatersonSize
+ GHC.Tc.Utils.TcType: substInScopeSet :: Subst -> InScopeSet
+ GHC.Tc.Utils.TcType: type ExpRhoTypeFRR = ExpTypeFRR
+ GHC.Tc.Utils.TcType: type TcRhoTypeFRR = TcRhoType
+ GHC.Tc.Utils.Unify: SUC_CanUnify :: SimpleUnifyResult
+ GHC.Tc.Utils.Unify: SUC_CannotUnify :: SimpleUnifyResult
+ GHC.Tc.Utils.Unify: SUC_NotSure :: SimpleUnifyResult
+ GHC.Tc.Utils.Unify: TEFTyFam :: CheckTyEqProblem -> TyCon -> [Type] -> TyEqFamApp m a -> TyEqFlags (m :: Type -> Type) a
+ GHC.Tc.Utils.Unify: TEFTyVar :: OccursCheck -> LevelCheck m -> ConcreteCheck m -> TyEqFamApp m a -> TyEqFlags (m :: Type -> Type) a
+ GHC.Tc.Utils.Unify: [BreakGiven] :: FamAppBreaker (TcTyVar, TcType)
+ GHC.Tc.Utils.Unify: [BreakWanted] :: CtEvidence -> TcTyVar -> FamAppBreaker Ct
+ GHC.Tc.Utils.Unify: [CC_Check] :: forall (m :: Type -> Type). ConcreteCheck m
+ GHC.Tc.Utils.Unify: [CC_None] :: forall (m :: Type -> Type). ConcreteCheck m
+ GHC.Tc.Utils.Unify: [CC_Promote] :: ConcreteTvOrigin -> ConcreteCheck (IOEnv (Env TcGblEnv TcLclEnv))
+ GHC.Tc.Utils.Unify: [LC_Check] :: forall (m :: Type -> Type). TcLevel -> Bool -> LevelCheck m
+ GHC.Tc.Utils.Unify: [LC_None] :: forall (m :: Type -> Type). LevelCheck m
+ GHC.Tc.Utils.Unify: [LC_Promote] :: TcLevel -> Bool -> LevelCheck (IOEnv (Env TcGblEnv TcLclEnv))
+ GHC.Tc.Utils.Unify: [OC_Check] :: Name -> CheckTyEqProblem -> OccursCheck
+ GHC.Tc.Utils.Unify: [OC_None] :: OccursCheck
+ GHC.Tc.Utils.Unify: [TEFA_Break] :: forall a. FamAppBreaker a -> TyEqFamApp (IOEnv (Env TcGblEnv TcLclEnv)) a
+ GHC.Tc.Utils.Unify: [TEFA_Recurse] :: forall (m :: Type -> Type) a. TyEqFamApp m a
+ GHC.Tc.Utils.Unify: [tefTyFam_args] :: TyEqFlags (m :: Type -> Type) a -> [Type]
+ GHC.Tc.Utils.Unify: [tefTyFam_occursCheck] :: TyEqFlags (m :: Type -> Type) a -> CheckTyEqProblem
+ GHC.Tc.Utils.Unify: [tefTyFam_tyCon] :: TyEqFlags (m :: Type -> Type) a -> TyCon
+ GHC.Tc.Utils.Unify: [tefTyVar_concreteCheck] :: TyEqFlags (m :: Type -> Type) a -> ConcreteCheck m
+ GHC.Tc.Utils.Unify: [tefTyVar_levelCheck] :: TyEqFlags (m :: Type -> Type) a -> LevelCheck m
+ GHC.Tc.Utils.Unify: [tefTyVar_occursCheck] :: TyEqFlags (m :: Type -> Type) a -> OccursCheck
+ GHC.Tc.Utils.Unify: addSubTypeCtxt :: TcType -> ExpType -> TcM a -> TcM a
+ GHC.Tc.Utils.Unify: data ConcreteCheck (m :: Type -> Type)
+ GHC.Tc.Utils.Unify: data FamAppBreaker a
+ GHC.Tc.Utils.Unify: data OccursCheck
+ GHC.Tc.Utils.Unify: data SimpleUnifyResult
+ GHC.Tc.Utils.Unify: defaulting_TEFTask :: TcTyVar -> TyEqFlags TcM a
+ GHC.Tc.Utils.Unify: dsInstantiate :: CtOrigin -> TcType -> TcM (HsWrapper, Type)
+ GHC.Tc.Utils.Unify: fillInferResultNoInst :: TcType -> InferResult -> TcM TcCoercionN
+ GHC.Tc.Utils.Unify: instance GHC.Internal.Base.Monoid (GHC.Tc.Utils.Unify.TyVarCheckResult m)
+ GHC.Tc.Utils.Unify: instance GHC.Internal.Base.Semigroup (GHC.Tc.Utils.Unify.TyVarCheckResult m)
+ GHC.Tc.Utils.Unify: instance GHC.Internal.Base.Semigroup GHC.Tc.Utils.Unify.SimpleUnifyResult
+ GHC.Tc.Utils.Unify: instance GHC.Internal.Classes.Eq GHC.Tc.Utils.Unify.SimpleUnifyResult
+ GHC.Tc.Utils.Unify: instance GHC.Internal.Classes.Ord GHC.Tc.Utils.Unify.SimpleUnifyResult
+ GHC.Tc.Utils.Unify: instance GHC.Internal.Data.Foldable.Foldable (GHC.Tc.Utils.Unify.PuResult a)
+ GHC.Tc.Utils.Unify: instance GHC.Internal.Data.Traversable.Traversable (GHC.Tc.Utils.Unify.PuResult a)
+ GHC.Tc.Utils.Unify: instance GHC.Internal.Show.Show GHC.Tc.Utils.Unify.SimpleUnifyResult
+ GHC.Tc.Utils.Unify: instance GHC.Utils.Outputable.Outputable (GHC.Tc.Utils.Unify.ConcreteCheck m)
+ GHC.Tc.Utils.Unify: instance GHC.Utils.Outputable.Outputable (GHC.Tc.Utils.Unify.FamAppBreaker a)
+ GHC.Tc.Utils.Unify: instance GHC.Utils.Outputable.Outputable (GHC.Tc.Utils.Unify.LevelCheck m)
+ GHC.Tc.Utils.Unify: instance GHC.Utils.Outputable.Outputable (GHC.Tc.Utils.Unify.TyEqFamApp m a)
+ GHC.Tc.Utils.Unify: instance GHC.Utils.Outputable.Outputable (GHC.Tc.Utils.Unify.TyEqFlags m a)
+ GHC.Tc.Utils.Unify: instance GHC.Utils.Outputable.Outputable GHC.Tc.Utils.Unify.OccursCheck
+ GHC.Tc.Utils.Unify: instance GHC.Utils.Outputable.Outputable GHC.Tc.Utils.Unify.SimpleUnifyResult
+ GHC.Tc.Utils.Unify: makeTypeConcrete :: FastString -> ConcreteTvOrigin -> TcType -> TcM (TcCoercion, Cts)
+ GHC.Tc.Utils.Unify: mightEqualLater :: InertSet -> TcPredType -> CtLoc -> TcPredType -> CtLoc -> Maybe Subst
+ GHC.Tc.Utils.Unify: mkTEFA_Break :: CtEvidence -> EqRel -> FamAppBreaker a -> TyEqFamApp TcM a
+ GHC.Tc.Utils.Unify: notUnifying_TEFTask :: forall (m :: Type -> Type) a. CheckTyEqProblem -> CanEqLHS -> TyEqFlags m a
+ GHC.Tc.Utils.Unify: pureTyEqFlags_LHSMetaTyVar :: TyVar -> TyEqFlags Identity ()
+ GHC.Tc.Utils.Unify: recurseIntoFamTyConApp :: Monad m => TyEqFlags m a -> TyCon -> [TcType] -> m (PuResult a Reduction)
+ GHC.Tc.Utils.Unify: touchabilityTest :: TcLevel -> TcTyVar -> Bool
+ GHC.Tc.Utils.Unify: unifyingLHSMetaTyVar_TEFTask :: CtEvidence -> TcTyVar -> TyEqFlags TcM Ct
+ GHC.Tc.Validity: RuleBndrTypeCtxt :: Name -> UserTypeCtxt
+ GHC.Tc.Validity: instance GHC.Internal.Classes.Eq GHC.Tc.Validity.TypeOrKindCtxt
+ GHC.Tc.Zonk.TcType: instance GHC.Internal.Base.Monoid GHC.Tc.Zonk.TcType.UnfilledCoercionHoleMonoid
+ GHC.Tc.Zonk.TcType: instance GHC.Internal.Base.Semigroup GHC.Tc.Zonk.TcType.UnfilledCoercionHoleMonoid
+ GHC.Tc.Zonk.TcType: isFilledCoercionHole :: CoercionHole -> ZonkM Bool
+ GHC.Tc.Zonk.TcType: unpackCoercionHole :: CoercionHole -> ZonkM Coercion
+ GHC.Tc.Zonk.TcType: unpackCoercionHole_maybe :: CoercionHole -> ZonkM (Maybe Coercion)
+ GHC.Tc.Zonk.TcType: zonkCtEvRewriterSet :: CtEvidence -> ZonkM CtEvidence
+ GHC.Tc.Zonk.TcType: zonkCtRewriterSet :: Ct -> ZonkM Ct
+ GHC.Tc.Zonk.TcType: zonkRewriterSet :: RewriterSet -> ZonkM RewriterSet
+ GHC.Types.Annotations: instance Control.DeepSeq.NFData name => Control.DeepSeq.NFData (GHC.Types.Annotations.AnnTarget name)
+ GHC.Types.Avail: [getDetOrdAvails] :: DetOrdAvails -> Avails
+ GHC.Types.Avail: emptyDetOrdAvails :: DetOrdAvails
+ GHC.Types.Avail: instance GHC.Internal.Classes.Eq GHC.Types.Avail.DetOrdAvails
+ GHC.Types.Avail: instance GHC.Internal.Classes.Ord GHC.Types.Avail.DetOrdAvails
+ GHC.Types.Basic: DataType :: NewOrData
+ GHC.Types.Basic: NewType :: NewOrData
+ GHC.Types.Basic: NormalLevel :: ImportLevel
+ GHC.Types.Basic: QuoteLevel :: ImportLevel
+ GHC.Types.Basic: SpliceLevel :: ImportLevel
+ GHC.Types.Basic: activeInInitialPhase :: Activation -> Bool
+ GHC.Types.Basic: allImportLevels :: [ImportLevel]
+ GHC.Types.Basic: convImportLevel :: ImportDeclLevelStyle -> ImportLevel
+ GHC.Types.Basic: convImportLevelSpec :: ImportDeclLevel -> ImportLevel
+ GHC.Types.Basic: data ImportLevel
+ GHC.Types.Basic: data NewOrData
+ GHC.Types.Basic: instance Control.DeepSeq.NFData GHC.Types.Basic.Activation
+ GHC.Types.Basic: instance Control.DeepSeq.NFData GHC.Types.Basic.CbvMark
+ GHC.Types.Basic: instance Control.DeepSeq.NFData GHC.Types.Basic.FunctionOrData
+ GHC.Types.Basic: instance Control.DeepSeq.NFData GHC.Types.Basic.InlinePragma
+ GHC.Types.Basic: instance Control.DeepSeq.NFData GHC.Types.Basic.InlineSpec
+ GHC.Types.Basic: instance Control.DeepSeq.NFData GHC.Types.Basic.LeftOrRight
+ GHC.Types.Basic: instance Control.DeepSeq.NFData GHC.Types.Basic.OverlapFlag
+ GHC.Types.Basic: instance Control.DeepSeq.NFData GHC.Types.Basic.OverlapMode
+ GHC.Types.Basic: instance Control.DeepSeq.NFData GHC.Types.Basic.RuleMatchInfo
+ GHC.Types.Basic: instance Control.DeepSeq.NFData GHC.Types.Basic.TupleSort
+ GHC.Types.Basic: instance Control.DeepSeq.NFData GHC.Types.Basic.TypeOrConstraint
+ GHC.Types.Basic: instance Control.DeepSeq.NFData GHC.Types.Basic.UnfoldingSource
+ GHC.Types.Basic: instance GHC.Internal.Classes.Eq GHC.Types.Basic.Activation
+ GHC.Types.Basic: instance GHC.Internal.Classes.Eq GHC.Types.Basic.Alignment
+ GHC.Types.Basic: instance GHC.Internal.Classes.Eq GHC.Types.Basic.CbvMark
+ GHC.Types.Basic: instance GHC.Internal.Classes.Eq GHC.Types.Basic.CompilerPhase
+ GHC.Types.Basic: instance GHC.Internal.Classes.Eq GHC.Types.Basic.DoPmc
+ GHC.Types.Basic: instance GHC.Internal.Classes.Eq GHC.Types.Basic.FunctionOrData
+ GHC.Types.Basic: instance GHC.Internal.Classes.Eq GHC.Types.Basic.GenReason
+ GHC.Types.Basic: instance GHC.Internal.Classes.Eq GHC.Types.Basic.ImportLevel
+ GHC.Types.Basic: instance GHC.Internal.Classes.Eq GHC.Types.Basic.InlinePragma
+ GHC.Types.Basic: instance GHC.Internal.Classes.Eq GHC.Types.Basic.InlineSpec
+ GHC.Types.Basic: instance GHC.Internal.Classes.Eq GHC.Types.Basic.InsideLam
+ GHC.Types.Basic: instance GHC.Internal.Classes.Eq GHC.Types.Basic.IntWithInf
+ GHC.Types.Basic: instance GHC.Internal.Classes.Eq GHC.Types.Basic.InterestingCxt
+ GHC.Types.Basic: instance GHC.Internal.Classes.Eq GHC.Types.Basic.LeftOrRight
+ GHC.Types.Basic: instance GHC.Internal.Classes.Eq GHC.Types.Basic.Levity
+ GHC.Types.Basic: instance GHC.Internal.Classes.Eq GHC.Types.Basic.NewOrData
+ GHC.Types.Basic: instance GHC.Internal.Classes.Eq GHC.Types.Basic.OccInfo
+ GHC.Types.Basic: instance GHC.Internal.Classes.Eq GHC.Types.Basic.OneShotInfo
+ GHC.Types.Basic: instance GHC.Internal.Classes.Eq GHC.Types.Basic.Origin
+ GHC.Types.Basic: instance GHC.Internal.Classes.Eq GHC.Types.Basic.OverlapFlag
+ GHC.Types.Basic: instance GHC.Internal.Classes.Eq GHC.Types.Basic.OverlapMode
+ GHC.Types.Basic: instance GHC.Internal.Classes.Eq GHC.Types.Basic.PprPrec
+ GHC.Types.Basic: instance GHC.Internal.Classes.Eq GHC.Types.Basic.RecFlag
+ GHC.Types.Basic: instance GHC.Internal.Classes.Eq GHC.Types.Basic.RuleMatchInfo
+ GHC.Types.Basic: instance GHC.Internal.Classes.Eq GHC.Types.Basic.SwapFlag
+ GHC.Types.Basic: instance GHC.Internal.Classes.Eq GHC.Types.Basic.TailCallInfo
+ GHC.Types.Basic: instance GHC.Internal.Classes.Eq GHC.Types.Basic.TupleSort
+ GHC.Types.Basic: instance GHC.Internal.Classes.Eq GHC.Types.Basic.TypeOrConstraint
+ GHC.Types.Basic: instance GHC.Internal.Classes.Eq GHC.Types.Basic.TypeOrData
+ GHC.Types.Basic: instance GHC.Internal.Classes.Eq GHC.Types.Basic.TypeOrKind
+ GHC.Types.Basic: instance GHC.Internal.Classes.Eq GHC.Types.Basic.UnboxedTupleOrSum
+ GHC.Types.Basic: instance GHC.Internal.Classes.Eq tc => GHC.Internal.Classes.Eq (GHC.Types.Basic.TyConFlavour tc)
+ GHC.Types.Basic: instance GHC.Internal.Classes.Ord GHC.Types.Basic.Alignment
+ GHC.Types.Basic: instance GHC.Internal.Classes.Ord GHC.Types.Basic.FunctionOrData
+ GHC.Types.Basic: instance GHC.Internal.Classes.Ord GHC.Types.Basic.ImportLevel
+ GHC.Types.Basic: instance GHC.Internal.Classes.Ord GHC.Types.Basic.IntWithInf
+ GHC.Types.Basic: instance GHC.Internal.Classes.Ord GHC.Types.Basic.LeftOrRight
+ GHC.Types.Basic: instance GHC.Internal.Classes.Ord GHC.Types.Basic.Levity
+ GHC.Types.Basic: instance GHC.Internal.Classes.Ord GHC.Types.Basic.PprPrec
+ GHC.Types.Basic: instance GHC.Internal.Classes.Ord GHC.Types.Basic.TupleSort
+ GHC.Types.Basic: instance GHC.Internal.Classes.Ord GHC.Types.Basic.TypeOrConstraint
+ GHC.Types.Basic: instance GHC.Internal.Data.Data.Data GHC.Types.Basic.ImportLevel
+ GHC.Types.Basic: instance GHC.Internal.Data.Data.Data GHC.Types.Basic.NewOrData
+ GHC.Types.Basic: instance GHC.Internal.Enum.Bounded GHC.Types.Basic.ImportLevel
+ GHC.Types.Basic: instance GHC.Internal.Enum.Enum GHC.Types.Basic.ImportLevel
+ GHC.Types.Basic: instance GHC.Internal.Show.Show GHC.Types.Basic.ImportLevel
+ GHC.Types.Basic: instance GHC.Utils.Binary.Binary GHC.Types.Basic.ImportLevel
+ GHC.Types.Basic: instance GHC.Utils.Binary.Binary GHC.Types.Basic.TypeOrConstraint
+ GHC.Types.Basic: instance GHC.Utils.Outputable.Outputable GHC.Types.Basic.ImportLevel
+ GHC.Types.Basic: instance GHC.Utils.Outputable.Outputable GHC.Types.Basic.NewOrData
+ GHC.Types.CompleteMatch: instance GHC.Internal.Classes.Eq (GHC.Types.CompleteMatch.CompleteMatchX con)
+ GHC.Types.CostCentre: instance Control.DeepSeq.NFData GHC.Types.CostCentre.CCFlavour
+ GHC.Types.CostCentre: instance Control.DeepSeq.NFData GHC.Types.CostCentre.CostCentre
+ GHC.Types.CostCentre: instance Control.DeepSeq.NFData GHC.Types.CostCentre.IndexedCCFlavour
+ GHC.Types.CostCentre: instance GHC.Internal.Classes.Eq GHC.Types.CostCentre.CCFlavour
+ GHC.Types.CostCentre: instance GHC.Internal.Classes.Eq GHC.Types.CostCentre.CostCentre
+ GHC.Types.CostCentre: instance GHC.Internal.Classes.Eq GHC.Types.CostCentre.CostCentreStack
+ GHC.Types.CostCentre: instance GHC.Internal.Classes.Eq GHC.Types.CostCentre.IndexedCCFlavour
+ GHC.Types.CostCentre: instance GHC.Internal.Classes.Ord GHC.Types.CostCentre.CCFlavour
+ GHC.Types.CostCentre: instance GHC.Internal.Classes.Ord GHC.Types.CostCentre.CostCentre
+ GHC.Types.CostCentre: instance GHC.Internal.Classes.Ord GHC.Types.CostCentre.CostCentreStack
+ GHC.Types.CostCentre: instance GHC.Internal.Classes.Ord GHC.Types.CostCentre.IndexedCCFlavour
+ GHC.Types.CostCentre.State: instance Control.DeepSeq.NFData GHC.Types.CostCentre.State.CostCentreIndex
+ GHC.Types.CostCentre.State: instance GHC.Internal.Classes.Eq GHC.Types.CostCentre.State.CostCentreIndex
+ GHC.Types.CostCentre.State: instance GHC.Internal.Classes.Ord GHC.Types.CostCentre.State.CostCentreIndex
+ GHC.Types.Cpr: instance GHC.Internal.Classes.Eq GHC.Types.Cpr.Cpr
+ GHC.Types.Cpr: instance GHC.Internal.Classes.Eq GHC.Types.Cpr.CprSig
+ GHC.Types.Cpr: instance GHC.Internal.Classes.Eq GHC.Types.Cpr.CprType
+ GHC.Types.DefaultEnv: DP_Builtin :: DefaultProvenance
+ GHC.Types.DefaultEnv: DP_Imported :: Module -> DefaultProvenance
+ GHC.Types.DefaultEnv: DP_Local :: SrcSpan -> Bool -> DefaultProvenance
+ GHC.Types.DefaultEnv: [cd_provenance] :: ClassDefaults -> DefaultProvenance
+ GHC.Types.DefaultEnv: [defaultDeclH98] :: DefaultProvenance -> Bool
+ GHC.Types.DefaultEnv: [defaultDeclLoc] :: DefaultProvenance -> SrcSpan
+ GHC.Types.DefaultEnv: data DefaultProvenance
+ GHC.Types.DefaultEnv: insertDefaultEnv :: ClassDefaults -> DefaultEnv -> DefaultEnv
+ GHC.Types.DefaultEnv: instance GHC.Internal.Classes.Eq GHC.Types.DefaultEnv.DefaultProvenance
+ GHC.Types.DefaultEnv: instance GHC.Internal.Data.Data.Data GHC.Types.DefaultEnv.DefaultProvenance
+ GHC.Types.DefaultEnv: instance GHC.Utils.Outputable.Outputable GHC.Types.DefaultEnv.DefaultProvenance
+ GHC.Types.DefaultEnv: isHaskell2010Default :: DefaultProvenance -> Bool
+ GHC.Types.Demand: instance GHC.Internal.Classes.Eq GHC.Types.Demand.Card
+ GHC.Types.Demand: instance GHC.Internal.Classes.Eq GHC.Types.Demand.Demand
+ GHC.Types.Demand: instance GHC.Internal.Classes.Eq GHC.Types.Demand.Divergence
+ GHC.Types.Demand: instance GHC.Internal.Classes.Eq GHC.Types.Demand.DmdEnv
+ GHC.Types.Demand: instance GHC.Internal.Classes.Eq GHC.Types.Demand.DmdSig
+ GHC.Types.Demand: instance GHC.Internal.Classes.Eq GHC.Types.Demand.DmdType
+ GHC.Types.Demand: instance GHC.Internal.Classes.Eq GHC.Types.Demand.SubDemand
+ GHC.Types.Error: -- <a>GhcHint</a>.
+ GHC.Types.Error: SuggestDataKeyword :: GhcHint
+ GHC.Types.Error: SuggestSplittingIntoSeveralSpecialisePragmas :: GhcHint
+ GHC.Types.Error: instance (GHC.Types.Error.HasDefaultDiagnosticOpts opts, GHC.Utils.Outputable.Outputable hint) => GHC.Types.Error.Diagnostic (GHC.Types.Error.UnknownDiagnostic opts hint)
+ GHC.Types.Error: instance GHC.Internal.Classes.Eq GHC.Types.Error.DiagnosticCode
+ GHC.Types.Error: instance GHC.Internal.Classes.Eq GHC.Types.Error.DiagnosticReason
+ GHC.Types.Error: instance GHC.Internal.Classes.Eq GHC.Types.Error.Severity
+ GHC.Types.Error: instance GHC.Internal.Classes.Ord GHC.Types.Error.DiagnosticCode
+ GHC.Types.Error: instance GHC.Internal.Classes.Ord GHC.Types.Error.Severity
+ GHC.Types.Error: type DiagnosticHint a = GhcHint;
+ GHC.Types.Error: type UnknownDiagnosticFor a = UnknownDiagnostic DiagnosticOpts a DiagnosticHint a
+ GHC.Types.Error.Codes: -- order to obtain a diagnostic code. See Note [Diagnostic codes].
+ GHC.Types.Error.Codes: -- | Specify that one should recur into an argument of a constructor in
+ GHC.Types.Error.Codes: class DiagnosticCodeNameSpace namespace where {
+ GHC.Types.Error.Codes: data GHC
+ GHC.Types.Error.Codes: instance (GHC.Types.Error.Codes.ConRecursIntoFor namespace con GHC.Internal.Types.~ 'GHC.Internal.Maybe.Just (GHC.Types.Error.UnknownDiagnostic opts hint)) => GHC.Types.Error.Codes.ConstructorCodes namespace con f seen ('GHC.Internal.Maybe.Just (GHC.Types.Error.UnknownDiagnostic opts hint))
+ GHC.Types.Error.Codes: instance (GHC.Types.Error.Codes.ConRecursIntoFor namespace con GHC.Internal.Types.~ 'GHC.Internal.Maybe.Just (GHC.Types.Error.UnknownDiagnostic opts hint), GHC.Types.Error.Codes.HasType namespace (GHC.Types.Error.UnknownDiagnostic opts hint) con f) => GHC.Types.Error.Codes.ConstructorCode namespace con f ('GHC.Internal.Maybe.Just (GHC.Types.Error.UnknownDiagnostic opts hint))
+ GHC.Types.Error.Codes: instance (GHC.Types.Error.Codes.ConRecursIntoFor namespace con GHC.Internal.Types.~ 'GHC.Internal.Maybe.Just ty, GHC.Types.Error.Codes.HasType namespace ty con f, GHC.Internal.Generics.Generic ty, GHC.Types.Error.Codes.GDiagnosticCode namespace (GHC.Internal.Generics.Rep ty)) => GHC.Types.Error.Codes.ConstructorCode namespace con f ('GHC.Internal.Maybe.Just ty)
+ GHC.Types.Error.Codes: instance (GHC.Types.Error.Codes.ConRecursIntoFor namespace con GHC.Internal.Types.~ 'GHC.Internal.Maybe.Just ty, GHC.Types.Error.Codes.HasType namespace ty con f, GHC.Internal.Generics.Generic ty, GHC.Types.Error.Codes.GDiagnosticCodes namespace (GHC.Types.Error.Codes.Insert ty seen) (GHC.Internal.Generics.Rep ty), GHC.Types.Error.Codes.Seen seen ty) => GHC.Types.Error.Codes.ConstructorCodes namespace con f seen ('GHC.Internal.Maybe.Just ty)
+ GHC.Types.Error.Codes: instance (GHC.Types.Error.Codes.ConstructorCode namespace con f recur, recur GHC.Internal.Types.~ GHC.Types.Error.Codes.ConRecursIntoFor namespace con, GHC.Internal.TypeLits.KnownSymbol con) => GHC.Types.Error.Codes.GDiagnosticCode namespace (GHC.Internal.Generics.M1 i ('GHC.Internal.Generics.MetaCons con x y) f)
+ GHC.Types.Error.Codes: instance (GHC.Types.Error.Codes.ConstructorCodes namespace con f seen recur, recur GHC.Internal.Types.~ GHC.Types.Error.Codes.ConRecursIntoFor namespace con, GHC.Internal.TypeLits.KnownSymbol con) => GHC.Types.Error.Codes.GDiagnosticCodes namespace seen (GHC.Internal.Generics.M1 i ('GHC.Internal.Generics.MetaCons con x y) f)
+ GHC.Types.Error.Codes: instance (GHC.Types.Error.Codes.GDiagnosticCode namespace f, GHC.Types.Error.Codes.GDiagnosticCode namespace g) => GHC.Types.Error.Codes.GDiagnosticCode namespace (f GHC.Internal.Generics.:+: g)
+ GHC.Types.Error.Codes: instance (GHC.Types.Error.Codes.GDiagnosticCodes namespace seen f, GHC.Types.Error.Codes.GDiagnosticCodes namespace seen g) => GHC.Types.Error.Codes.GDiagnosticCodes namespace seen (f GHC.Internal.Generics.:+: g)
+ GHC.Types.Error.Codes: instance (GHC.Types.Error.Codes.KnownNameSpace namespace, GHC.Types.Error.Codes.KnownConstructor namespace con, GHC.Internal.TypeLits.KnownSymbol con) => GHC.Types.Error.Codes.ConstructorCode namespace con f 'GHC.Internal.Maybe.Nothing
+ GHC.Types.Error.Codes: instance (GHC.Types.Error.Codes.KnownNameSpace namespace, GHC.Types.Error.Codes.KnownConstructor namespace con, GHC.Internal.TypeLits.KnownSymbol con) => GHC.Types.Error.Codes.ConstructorCodes namespace con f seen 'GHC.Internal.Maybe.Nothing
+ GHC.Types.Error.Codes: instance (TypeError ...) => GHC.Types.Error.Codes.HasType namespace ty orig f
+ GHC.Types.Error.Codes: instance GHC.Types.Error.Codes.DiagnosticCodeNameSpace GHC.Types.Error.Codes.GHC
+ GHC.Types.Error.Codes: instance GHC.Types.Error.Codes.GDiagnosticCode namespace f => GHC.Types.Error.Codes.GDiagnosticCode namespace (GHC.Internal.Generics.M1 i ('GHC.Internal.Generics.MetaData nm mod pkg nt) f)
+ GHC.Types.Error.Codes: instance GHC.Types.Error.Codes.GDiagnosticCodes namespace seen f => GHC.Types.Error.Codes.GDiagnosticCodes namespace seen (GHC.Internal.Generics.M1 i ('GHC.Internal.Generics.MetaData nm mod pkg nt) f)
+ GHC.Types.Error.Codes: instance GHC.Types.Error.Codes.HasType namespace ty orig (GHC.Internal.Generics.M1 i s (GHC.Internal.Generics.K1 x ty))
+ GHC.Types.Error.Codes: instance GHC.Types.Error.Codes.HasType namespace ty orig g => GHC.Types.Error.Codes.HasTypeProd namespace ty 'GHC.Internal.Maybe.Nothing orig f g
+ GHC.Types.Error.Codes: instance GHC.Types.Error.Codes.HasTypeProd namespace ty (GHC.Types.Error.Codes.HasTypeQ ty f) orig f g => GHC.Types.Error.Codes.HasType namespace ty orig (f GHC.Internal.Generics.:*: g)
+ GHC.Types.Error.Codes: instance forall a namespace ty (orig :: GHC.Internal.Types.Symbol) (f :: * -> *) (l :: a) (g :: * -> *). GHC.Types.Error.Codes.HasType namespace ty orig f => GHC.Types.Error.Codes.HasTypeProd namespace ty ('GHC.Internal.Maybe.Just l) orig f g
+ GHC.Types.Error.Codes: type ConRecursIntoFor namespace (c :: Symbol) :: Maybe Type;
+ GHC.Types.Error.Codes: type DiagnosticCodeFor namespace (c :: Symbol) :: Nat;
+ GHC.Types.Error.Codes: type NameSpaceTag namespace = (r :: Symbol) | r -> namespace;
+ GHC.Types.Error.Codes: type Outdated (a :: k) = a
+ GHC.Types.Error.Codes: }
+ GHC.Types.FieldLabel: instance GHC.Internal.Classes.Eq GHC.Types.FieldLabel.DuplicateRecordFields
+ GHC.Types.FieldLabel: instance GHC.Internal.Classes.Eq GHC.Types.FieldLabel.FieldLabel
+ GHC.Types.FieldLabel: instance GHC.Internal.Classes.Eq GHC.Types.FieldLabel.FieldSelectors
+ GHC.Types.ForeignCall: instance Control.DeepSeq.NFData GHC.Types.ForeignCall.CCallConv
+ GHC.Types.ForeignCall: instance Control.DeepSeq.NFData GHC.Types.ForeignCall.CCallSpec
+ GHC.Types.ForeignCall: instance Control.DeepSeq.NFData GHC.Types.ForeignCall.CCallTarget
+ GHC.Types.ForeignCall: instance Control.DeepSeq.NFData GHC.Types.ForeignCall.CType
+ GHC.Types.ForeignCall: instance Control.DeepSeq.NFData GHC.Types.ForeignCall.ForeignCall
+ GHC.Types.ForeignCall: instance Control.DeepSeq.NFData GHC.Types.ForeignCall.Header
+ GHC.Types.ForeignCall: instance Control.DeepSeq.NFData GHC.Types.ForeignCall.Safety
+ GHC.Types.ForeignCall: instance GHC.Internal.Classes.Eq GHC.Types.ForeignCall.CCallConv
+ GHC.Types.ForeignCall: instance GHC.Internal.Classes.Eq GHC.Types.ForeignCall.CCallSpec
+ GHC.Types.ForeignCall: instance GHC.Internal.Classes.Eq GHC.Types.ForeignCall.CCallTarget
+ GHC.Types.ForeignCall: instance GHC.Internal.Classes.Eq GHC.Types.ForeignCall.CType
+ GHC.Types.ForeignCall: instance GHC.Internal.Classes.Eq GHC.Types.ForeignCall.ForeignCall
+ GHC.Types.ForeignCall: instance GHC.Internal.Classes.Eq GHC.Types.ForeignCall.Header
+ GHC.Types.ForeignCall: instance GHC.Internal.Classes.Eq GHC.Types.ForeignCall.Safety
+ GHC.Types.ForeignCall: instance GHC.Internal.Show.Show GHC.Types.ForeignCall.CCallConv
+ GHC.Types.GREInfo: instance GHC.Internal.Classes.Eq GHC.Types.GREInfo.ConFieldInfo
+ GHC.Types.GREInfo: instance GHC.Internal.Classes.Eq GHC.Types.GREInfo.ConInfo
+ GHC.Types.GREInfo: instance GHC.Internal.Classes.Eq GHC.Types.GREInfo.ConLikeInfo
+ GHC.Types.GREInfo: instance GHC.Internal.Classes.Eq GHC.Types.GREInfo.ConLikeName
+ GHC.Types.GREInfo: instance GHC.Internal.Classes.Eq GHC.Types.GREInfo.RecFieldInfo
+ GHC.Types.GREInfo: instance GHC.Types.Name.NamedThing GHC.Types.GREInfo.ConLikeName
+ GHC.Types.Hint: CouldChangeImportItem :: ModuleName -> ImportItemSuggestion -> ImportSuggestion
+ GHC.Types.Hint: ImportItemAddType :: ImportItemSuggestion
+ GHC.Types.Hint: ImportItemRemoveData :: ImportItemSuggestion
+ GHC.Types.Hint: ImportItemRemovePattern :: ImportItemSuggestion
+ GHC.Types.Hint: ImportItemRemoveSubordinateData :: NonEmpty OccName -> ImportItemSuggestion
+ GHC.Types.Hint: ImportItemRemoveSubordinateType :: NonEmpty OccName -> ImportItemSuggestion
+ GHC.Types.Hint: ImportItemRemoveType :: ImportItemSuggestion
+ GHC.Types.Hint: SigLikeDeprecation :: SigLike
+ GHC.Types.Hint: SigLikeFixitySig :: SigLike
+ GHC.Types.Hint: SigLikeRoleAnnotation :: SigLike
+ GHC.Types.Hint: SigLikeSig :: Sig GhcPs -> SigLike
+ GHC.Types.Hint: SigLikeStandaloneKindSig :: SigLike
+ GHC.Types.Hint: SuggestDataKeyword :: GhcHint
+ GHC.Types.Hint: SuggestSplittingIntoSeveralSpecialisePragmas :: GhcHint
+ GHC.Types.Hint: [ies_suggest_data_keyword] :: ImportSuggestion -> Bool
+ GHC.Types.Hint: [ies_suggest_pattern_keyword] :: ImportSuggestion -> Bool
+ GHC.Types.Hint: data ImportItemSuggestion
+ GHC.Types.Hint: data SigLike
+ GHC.Types.Hint: instance GHC.Internal.Classes.Eq GHC.Types.Hint.AssumedDerivingStrategy
+ GHC.Types.Hint: instance GHC.Internal.Classes.Ord GHC.Types.Hint.AssumedDerivingStrategy
+ GHC.Types.Hint.Ppr: pprSigLike :: SigLike -> SDoc
+ GHC.Types.Id: dataConWrapUnfolding_maybe :: Id -> Maybe CoreExpr
+ GHC.Types.Id.Info: RSI :: [ConLike] -> [ConLike] -> RecSelInfo
+ GHC.Types.Id.Info: [rsi_def] :: RecSelInfo -> [ConLike]
+ GHC.Types.Id.Info: [rsi_undef] :: RecSelInfo -> [ConLike]
+ GHC.Types.Id.Info: conLikesRecSelInfo :: [ConLike] -> [FieldLabelString] -> RecSelInfo
+ GHC.Types.Id.Info: data RecSelInfo
+ GHC.Types.Id.Info: instance GHC.Internal.Classes.Eq GHC.Types.Id.Info.CafInfo
+ GHC.Types.Id.Info: instance GHC.Internal.Classes.Eq GHC.Types.Id.Info.RecSelParent
+ GHC.Types.Id.Info: instance GHC.Internal.Classes.Ord GHC.Types.Id.Info.CafInfo
+ GHC.Types.Id.Make: wrapNewTypeBody :: TyCon -> [Type] -> CoreExpr -> CoreExpr
+ GHC.Types.Literal: instance Control.DeepSeq.NFData GHC.Types.Literal.LitNumType
+ GHC.Types.Literal: instance Control.DeepSeq.NFData GHC.Types.Literal.Literal
+ GHC.Types.Literal: instance GHC.Internal.Classes.Eq GHC.Types.Literal.LitNumType
+ GHC.Types.Literal: instance GHC.Internal.Classes.Eq GHC.Types.Literal.Literal
+ GHC.Types.Literal: instance GHC.Internal.Classes.Ord GHC.Types.Literal.LitNumType
+ GHC.Types.Literal: instance GHC.Internal.Classes.Ord GHC.Types.Literal.Literal
+ GHC.Types.Meta: instance GHC.Utils.Outputable.Outputable GHC.Types.Meta.MetaResult
+ GHC.Types.Name: instance GHC.Internal.Classes.Eq GHC.Types.Name.Name
+ GHC.Types.Name: instance GHC.Internal.Classes.Ord GHC.Types.Name.Name
+ GHC.Types.Name: pprFullNameWithUnique :: Module -> Name -> SDoc
+ GHC.Types.Name: pprName_userQual :: IsLine doc => Maybe ModuleName -> Name -> doc
+ GHC.Types.Name.Cache: isKnownOrigName_maybe :: Module -> OccName -> Maybe Name
+ GHC.Types.Name.Cache: knownKeysOrigNameCache :: OrigNameCache
+ GHC.Types.Name.Cache: newNameCache :: IO NameCache
+ GHC.Types.Name.Cache: newNameCacheWith :: Char -> OrigNameCache -> IO NameCache
+ GHC.Types.Name.Occurrence: demoteOccTcClsName :: OccName -> Maybe OccName
+ GHC.Types.Name.Occurrence: instance GHC.Internal.Classes.Eq GHC.Types.Name.Occurrence.NameSpace
+ GHC.Types.Name.Occurrence: instance GHC.Internal.Classes.Eq GHC.Types.Name.Occurrence.OccName
+ GHC.Types.Name.Occurrence: instance GHC.Internal.Classes.Ord GHC.Types.Name.Occurrence.NameSpace
+ GHC.Types.Name.Occurrence: instance GHC.Internal.Classes.Ord GHC.Types.Name.Occurrence.OccName
+ GHC.Types.Name.Occurrence: sizeOccEnv :: OccEnv a -> Int
+ GHC.Types.Name.Reader: NormalLevel :: ImportLevel
+ GHC.Types.Name.Reader: ParentGRE :: Name -> GREInfo -> ParentGRE
+ GHC.Types.Name.Reader: QuoteLevel :: ImportLevel
+ GHC.Types.Name.Reader: SpliceLevel :: ImportLevel
+ GHC.Types.Name.Reader: WithUserRdr :: RdrName -> a -> WithUserRdr a
+ GHC.Types.Name.Reader: [is_level] :: ImpDeclSpec -> ImportLevel
+ GHC.Types.Name.Reader: [parentGRE_info] :: ParentGRE -> GREInfo
+ GHC.Types.Name.Reader: [parentGRE_name] :: ParentGRE -> Name
+ GHC.Types.Name.Reader: data ImportLevel
+ GHC.Types.Name.Reader: data ParentGRE
+ GHC.Types.Name.Reader: data WithUserRdr a
+ GHC.Types.Name.Reader: demoteRdrNameTcCls :: RdrName -> Maybe RdrName
+ GHC.Types.Name.Reader: greLevels :: GlobalRdrEltX info -> Set ImportLevel
+ GHC.Types.Name.Reader: importSpecLevel :: ImportSpec -> ImportLevel
+ GHC.Types.Name.Reader: instance GHC.Internal.Base.Functor GHC.Types.Name.Reader.WithUserRdr
+ GHC.Types.Name.Reader: instance GHC.Internal.Classes.Eq GHC.Types.Name.Reader.FieldsOrSelectors
+ GHC.Types.Name.Reader: instance GHC.Internal.Classes.Eq GHC.Types.Name.Reader.ImpDeclSpec
+ GHC.Types.Name.Reader: instance GHC.Internal.Classes.Eq GHC.Types.Name.Reader.ImpItemSpec
+ GHC.Types.Name.Reader: instance GHC.Internal.Classes.Eq GHC.Types.Name.Reader.ImportSpec
+ GHC.Types.Name.Reader: instance GHC.Internal.Classes.Eq GHC.Types.Name.Reader.Parent
+ GHC.Types.Name.Reader: instance GHC.Internal.Classes.Eq GHC.Types.Name.Reader.ParentGRE
+ GHC.Types.Name.Reader: instance GHC.Internal.Classes.Eq GHC.Types.Name.Reader.RdrName
+ GHC.Types.Name.Reader: instance GHC.Internal.Classes.Ord GHC.Types.Name.Reader.RdrName
+ GHC.Types.Name.Reader: instance GHC.Internal.Data.Foldable.Foldable GHC.Types.Name.Reader.WithUserRdr
+ GHC.Types.Name.Reader: instance GHC.Internal.Data.Traversable.Traversable GHC.Types.Name.Reader.WithUserRdr
+ GHC.Types.Name.Reader: instance GHC.Types.Name.NamedThing a => GHC.Types.Name.NamedThing (GHC.Types.Name.Reader.WithUserRdr a)
+ GHC.Types.Name.Reader: instance GHC.Utils.Binary.Binary GHC.Types.Name.Reader.ImpDeclSpec
+ GHC.Types.Name.Reader: instance GHC.Utils.Outputable.Outputable (GHC.Types.Name.Reader.WithUserRdr GHC.Types.Name.Name)
+ GHC.Types.Name.Reader: instance GHC.Utils.Outputable.Outputable GHC.Types.Name.Reader.ParentGRE
+ GHC.Types.Name.Reader: instance GHC.Utils.Outputable.OutputableBndr (GHC.Types.Name.Reader.WithUserRdr GHC.Types.Name.Name)
+ GHC.Types.Name.Reader: noUserRdr :: Name -> WithUserRdr Name
+ GHC.Types.Name.Reader: pickLevelZeroGRE :: GlobalRdrEltX info -> Maybe (GlobalRdrEltX info)
+ GHC.Types.Name.Reader: unLocWithUserRdr :: GenLocated l (WithUserRdr a) -> a
+ GHC.Types.Name.Reader: userRdrName :: WithUserRdr Name -> RdrName
+ GHC.Types.PkgQual: instance GHC.Internal.Classes.Eq GHC.Types.PkgQual.PkgQual
+ GHC.Types.PkgQual: instance GHC.Internal.Classes.Ord GHC.Types.PkgQual.PkgQual
+ GHC.Types.PkgQual: instance GHC.Utils.Binary.Binary GHC.Types.PkgQual.PkgQual
+ GHC.Types.ProfAuto: instance GHC.Internal.Classes.Eq GHC.Types.ProfAuto.ProfAuto
+ GHC.Types.ProfAuto: instance GHC.Internal.Show.Show GHC.Types.ProfAuto.ProfAuto
+ GHC.Types.RepType: instance GHC.Internal.Classes.Eq GHC.Types.RepType.SlotTy
+ GHC.Types.RepType: instance GHC.Internal.Classes.Ord GHC.Types.RepType.SlotTy
+ GHC.Types.SafeHaskell: instance Control.DeepSeq.NFData GHC.Types.SafeHaskell.IfaceTrustInfo
+ GHC.Types.SafeHaskell: instance Control.DeepSeq.NFData GHC.Types.SafeHaskell.SafeHaskellMode
+ GHC.Types.SafeHaskell: instance GHC.Internal.Classes.Eq GHC.Types.SafeHaskell.SafeHaskellMode
+ GHC.Types.SaneDouble: instance GHC.Internal.Classes.Eq GHC.Types.SaneDouble.SaneDouble
+ GHC.Types.SaneDouble: instance GHC.Internal.Classes.Ord GHC.Types.SaneDouble.SaneDouble
+ GHC.Types.SourceFile: instance Control.DeepSeq.NFData GHC.Types.SourceFile.HsBootOrSig
+ GHC.Types.SourceFile: instance Control.DeepSeq.NFData GHC.Types.SourceFile.HscSource
+ GHC.Types.SourceFile: instance GHC.Internal.Classes.Eq GHC.Types.SourceFile.HsBootOrSig
+ GHC.Types.SourceFile: instance GHC.Internal.Classes.Eq GHC.Types.SourceFile.HscSource
+ GHC.Types.SourceFile: instance GHC.Internal.Classes.Ord GHC.Types.SourceFile.HsBootOrSig
+ GHC.Types.SourceFile: instance GHC.Internal.Classes.Ord GHC.Types.SourceFile.HscSource
+ GHC.Types.SourceText: instance GHC.Internal.Classes.Eq GHC.Types.SourceText.FractionalExponentBase
+ GHC.Types.SourceText: instance GHC.Internal.Classes.Eq GHC.Types.SourceText.FractionalLit
+ GHC.Types.SourceText: instance GHC.Internal.Classes.Eq GHC.Types.SourceText.IntegralLit
+ GHC.Types.SourceText: instance GHC.Internal.Classes.Eq GHC.Types.SourceText.SourceText
+ GHC.Types.SourceText: instance GHC.Internal.Classes.Eq GHC.Types.SourceText.StringLiteral
+ GHC.Types.SourceText: instance GHC.Internal.Classes.Ord GHC.Types.SourceText.FractionalExponentBase
+ GHC.Types.SourceText: instance GHC.Internal.Classes.Ord GHC.Types.SourceText.FractionalLit
+ GHC.Types.SourceText: instance GHC.Internal.Classes.Ord GHC.Types.SourceText.IntegralLit
+ GHC.Types.SrcLoc: instance (GHC.Internal.Classes.Eq l, GHC.Internal.Classes.Eq e) => GHC.Internal.Classes.Eq (GHC.Types.SrcLoc.GenLocated l e)
+ GHC.Types.SrcLoc: instance (GHC.Internal.Classes.Ord l, GHC.Internal.Classes.Ord e) => GHC.Internal.Classes.Ord (GHC.Types.SrcLoc.GenLocated l e)
+ GHC.Types.SrcLoc: instance Control.DeepSeq.NFData GHC.Types.SrcLoc.BufPos
+ GHC.Types.SrcLoc: instance Control.DeepSeq.NFData GHC.Types.SrcLoc.BufSpan
+ GHC.Types.SrcLoc: instance Control.DeepSeq.NFData GHC.Types.SrcLoc.RealSrcSpan
+ GHC.Types.SrcLoc: instance Control.DeepSeq.NFData GHC.Types.SrcLoc.UnhelpfulSpanReason
+ GHC.Types.SrcLoc: instance GHC.Internal.Classes.Eq GHC.Types.SrcLoc.BufPos
+ GHC.Types.SrcLoc: instance GHC.Internal.Classes.Eq GHC.Types.SrcLoc.BufSpan
+ GHC.Types.SrcLoc: instance GHC.Internal.Classes.Eq GHC.Types.SrcLoc.DeltaPos
+ GHC.Types.SrcLoc: instance GHC.Internal.Classes.Eq GHC.Types.SrcLoc.NoComments
+ GHC.Types.SrcLoc: instance GHC.Internal.Classes.Eq GHC.Types.SrcLoc.PsLoc
+ GHC.Types.SrcLoc: instance GHC.Internal.Classes.Eq GHC.Types.SrcLoc.PsSpan
+ GHC.Types.SrcLoc: instance GHC.Internal.Classes.Eq GHC.Types.SrcLoc.RealSrcLoc
+ GHC.Types.SrcLoc: instance GHC.Internal.Classes.Eq GHC.Types.SrcLoc.RealSrcSpan
+ GHC.Types.SrcLoc: instance GHC.Internal.Classes.Eq GHC.Types.SrcLoc.SrcLoc
+ GHC.Types.SrcLoc: instance GHC.Internal.Classes.Eq GHC.Types.SrcLoc.SrcSpan
+ GHC.Types.SrcLoc: instance GHC.Internal.Classes.Eq GHC.Types.SrcLoc.UnhelpfulSpanReason
+ GHC.Types.SrcLoc: instance GHC.Internal.Classes.Eq a => GHC.Internal.Classes.Eq (GHC.Types.SrcLoc.EpaLocation' a)
+ GHC.Types.SrcLoc: instance GHC.Internal.Classes.Ord GHC.Types.SrcLoc.BufPos
+ GHC.Types.SrcLoc: instance GHC.Internal.Classes.Ord GHC.Types.SrcLoc.BufSpan
+ GHC.Types.SrcLoc: instance GHC.Internal.Classes.Ord GHC.Types.SrcLoc.DeltaPos
+ GHC.Types.SrcLoc: instance GHC.Internal.Classes.Ord GHC.Types.SrcLoc.NoComments
+ GHC.Types.SrcLoc: instance GHC.Internal.Classes.Ord GHC.Types.SrcLoc.PsLoc
+ GHC.Types.SrcLoc: instance GHC.Internal.Classes.Ord GHC.Types.SrcLoc.PsSpan
+ GHC.Types.SrcLoc: instance GHC.Internal.Classes.Ord GHC.Types.SrcLoc.RealSrcLoc
+ GHC.Types.SrcLoc: instance GHC.Internal.Classes.Ord GHC.Types.SrcLoc.RealSrcSpan
+ GHC.Types.Target: instance GHC.Internal.Classes.Eq GHC.Types.Target.TargetId
+ GHC.Types.ThLevelIndex: ThLevelIndex :: Int -> ThLevelIndex
+ GHC.Types.ThLevelIndex: decThLevelIndex :: ThLevelIndex -> ThLevelIndex
+ GHC.Types.ThLevelIndex: incThLevelIndex :: ThLevelIndex -> ThLevelIndex
+ GHC.Types.ThLevelIndex: instance GHC.Internal.Classes.Eq GHC.Types.ThLevelIndex.ThLevelIndex
+ GHC.Types.ThLevelIndex: instance GHC.Internal.Classes.Ord GHC.Types.ThLevelIndex.ThLevelIndex
+ GHC.Types.ThLevelIndex: instance GHC.Internal.Data.Data.Data GHC.Types.ThLevelIndex.ThLevelIndex
+ GHC.Types.ThLevelIndex: instance GHC.Utils.Outputable.Outputable GHC.Types.ThLevelIndex.ThLevelIndex
+ GHC.Types.ThLevelIndex: newtype ThLevelIndex
+ GHC.Types.ThLevelIndex: quoteLevelIndex :: ThLevelIndex
+ GHC.Types.ThLevelIndex: spliceLevelIndex :: ThLevelIndex
+ GHC.Types.ThLevelIndex: thLevelIndexFromImportLevel :: ImportLevel -> ThLevelIndex
+ GHC.Types.ThLevelIndex: topLevelIndex :: ThLevelIndex
+ GHC.Types.Tickish: BreakpointId :: Module -> BreakTickIndex -> BreakpointId
+ GHC.Types.Tickish: [bi_tick_index] :: BreakpointId -> BreakTickIndex
+ GHC.Types.Tickish: [bi_tick_mod] :: BreakpointId -> Module
+ GHC.Types.Tickish: data BreakpointId
+ GHC.Types.Tickish: instance Control.DeepSeq.NFData GHC.Types.Tickish.BreakpointId
+ GHC.Types.Tickish: instance GHC.Internal.Classes.Eq (GHC.Types.Tickish.GenTickish 'GHC.Types.Tickish.TickishPassCmm)
+ GHC.Types.Tickish: instance GHC.Internal.Classes.Eq (GHC.Types.Tickish.GenTickish 'GHC.Types.Tickish.TickishPassCore)
+ GHC.Types.Tickish: instance GHC.Internal.Classes.Eq GHC.Types.Tickish.BreakpointId
+ GHC.Types.Tickish: instance GHC.Internal.Classes.Eq GHC.Types.Tickish.TickishPlacement
+ GHC.Types.Tickish: instance GHC.Internal.Classes.Eq GHC.Types.Tickish.TickishScoping
+ GHC.Types.Tickish: instance GHC.Internal.Classes.Ord (GHC.Types.Tickish.GenTickish 'GHC.Types.Tickish.TickishPassCmm)
+ GHC.Types.Tickish: instance GHC.Internal.Classes.Ord (GHC.Types.Tickish.GenTickish 'GHC.Types.Tickish.TickishPassCore)
+ GHC.Types.Tickish: instance GHC.Internal.Classes.Ord GHC.Types.Tickish.BreakpointId
+ GHC.Types.Tickish: instance GHC.Internal.Data.Data.Data GHC.Types.Tickish.BreakpointId
+ GHC.Types.Tickish: instance GHC.Utils.Outputable.Outputable GHC.Types.Tickish.BreakpointId
+ GHC.Types.Tickish: type BreakTickIndex = Int
+ GHC.Types.Unique: instance GHC.Internal.Classes.Eq GHC.Types.Unique.Unique
+ GHC.Types.Unique: instance GHC.Types.Unique.Uniquable GHC.Internal.Types.Int
+ GHC.Types.Unique.DFM: instance GHC.Internal.Classes.Eq val => GHC.Internal.Classes.Eq (GHC.Types.Unique.DFM.TaggedVal val)
+ GHC.Types.Unique.DSet: instance GHC.Internal.Classes.Eq (GHC.Types.Unique.DSet.UniqDSet a)
+ GHC.Types.Unique.FM: instance GHC.Internal.Classes.Eq a => GHC.Internal.Classes.Eq (GHC.Types.Unique.FM.Edit a)
+ GHC.Types.Unique.FM: instance forall k (key :: k) ele. GHC.Internal.Classes.Eq ele => GHC.Internal.Classes.Eq (GHC.Types.Unique.FM.UniqFM key ele)
+ GHC.Types.Unique.Map: instance (GHC.Internal.Classes.Eq k, GHC.Internal.Classes.Eq a) => GHC.Internal.Classes.Eq (GHC.Types.Unique.Map.UniqMap k a)
+ GHC.Types.Unique.Set: instance GHC.Internal.Classes.Eq (GHC.Types.Unique.Set.UniqSet a)
+ GHC.Types.Unique.Set: instance GHC.Internal.Classes.Eq GHC.Types.Unique.Set.UniqueSet
+ GHC.Types.Unique.Set: instance GHC.Internal.Classes.Ord GHC.Types.Unique.Set.UniqueSet
+ GHC.Types.Var: idMult :: HasDebugCallStack => Id -> Mult
+ GHC.Types.Var: instance (Control.DeepSeq.NFData tv, Control.DeepSeq.NFData vis) => Control.DeepSeq.NFData (GHC.Types.Var.VarBndr tv vis)
+ GHC.Types.Var: instance (GHC.Internal.Classes.Eq var, GHC.Internal.Classes.Eq argf) => GHC.Internal.Classes.Eq (GHC.Types.Var.VarBndr var argf)
+ GHC.Types.Var: instance (GHC.Internal.Classes.Ord var, GHC.Internal.Classes.Ord argf) => GHC.Internal.Classes.Ord (GHC.Types.Var.VarBndr var argf)
+ GHC.Types.Var: instance Control.DeepSeq.NFData GHC.Types.Var.FunTyFlag
+ GHC.Types.Var: instance GHC.Internal.Classes.Eq GHC.Types.Var.FunTyFlag
+ GHC.Types.Var: instance GHC.Internal.Classes.Eq GHC.Types.Var.Var
+ GHC.Types.Var: instance GHC.Internal.Classes.Ord GHC.Types.Var.FunTyFlag
+ GHC.Types.Var: instance GHC.Internal.Classes.Ord GHC.Types.Var.Var
+ GHC.Types.Var: isInvisibleAnonPiTyBinder :: PiTyBinder -> Bool
+ GHC.Types.Var: type InTyCoVar = TyCoVar
+ GHC.Types.Var: type OutTyCoVar = TyCoVar
+ GHC.Types.Var.Env: mapMaybeDVarEnv :: (a -> Maybe b) -> DVarEnv a -> DVarEnv b
+ GHC.Unit.Env: [ue_module_graph] :: UnitEnv -> ModuleGraph
+ GHC.Unit.Env: hugAllAnns :: UnitEnv -> IO AnnEnv
+ GHC.Unit.Env: hugAllInstances :: UnitEnv -> IO (InstEnv, [FamInst])
+ GHC.Unit.Env: hugCompleteSigs :: UnitEnv -> IO CompleteMatches
+ GHC.Unit.Env: insertHpt :: HasDebugCallStack => HomeModInfo -> UnitEnv -> IO ()
+ GHC.Unit.Env: renameUnitId :: HasDebugCallStack => UnitId -> UnitId -> UnitEnv -> UnitEnv
+ GHC.Unit.Env: ue_homeUnitState :: HasDebugCallStack => UnitEnv -> UnitState
+ GHC.Unit.Env: ue_unitHomeUnit_maybe :: UnitId -> UnitEnv -> Maybe HomeUnit
+ GHC.Unit.Finder: findImportedModuleWithIsBoot :: HscEnv -> ModuleName -> IsBootInterface -> PkgQual -> IO FindResult
+ GHC.Unit.Home.Graph: HomeUnitEnv :: UnitState -> Maybe [UnitDatabase UnitId] -> DynFlags -> HomePackageTable -> Maybe HomeUnit -> HomeUnitEnv
+ GHC.Unit.Home.Graph: UnitEnvGraph :: Map UnitEnvGraphKey v -> UnitEnvGraph v
+ GHC.Unit.Home.Graph: [homeUnitEnv_dflags] :: HomeUnitEnv -> DynFlags
+ GHC.Unit.Home.Graph: [homeUnitEnv_home_unit] :: HomeUnitEnv -> Maybe HomeUnit
+ GHC.Unit.Home.Graph: [homeUnitEnv_hpt] :: HomeUnitEnv -> HomePackageTable
+ GHC.Unit.Home.Graph: [homeUnitEnv_unit_dbs] :: HomeUnitEnv -> Maybe [UnitDatabase UnitId]
+ GHC.Unit.Home.Graph: [homeUnitEnv_units] :: HomeUnitEnv -> UnitState
+ GHC.Unit.Home.Graph: [unitEnv_graph] :: UnitEnvGraph v -> Map UnitEnvGraphKey v
+ GHC.Unit.Home.Graph: addHomeModInfoToHug :: HomeModInfo -> HomeUnitGraph -> IO ()
+ GHC.Unit.Home.Graph: allAnns :: HomeUnitGraph -> IO AnnEnv
+ GHC.Unit.Home.Graph: allCompleteSigs :: HomeUnitGraph -> IO CompleteMatches
+ GHC.Unit.Home.Graph: allFamInstances :: HomeUnitGraph -> IO (ModuleEnv FamInstEnv)
+ GHC.Unit.Home.Graph: allInstances :: HomeUnitGraph -> IO (InstEnv, [FamInst])
+ GHC.Unit.Home.Graph: allUnits :: HomeUnitGraph -> Set UnitId
+ GHC.Unit.Home.Graph: data HomeUnitEnv
+ GHC.Unit.Home.Graph: hugFromList :: [(UnitId, HomeUnitEnv)] -> HomeUnitGraph
+ GHC.Unit.Home.Graph: hugSCCs :: HomeUnitGraph -> [SCC UnitId]
+ GHC.Unit.Home.Graph: instance GHC.Internal.Base.Functor GHC.Unit.Home.Graph.UnitEnvGraph
+ GHC.Unit.Home.Graph: instance GHC.Internal.Data.Foldable.Foldable GHC.Unit.Home.Graph.UnitEnvGraph
+ GHC.Unit.Home.Graph: instance GHC.Internal.Data.Traversable.Traversable GHC.Unit.Home.Graph.UnitEnvGraph
+ GHC.Unit.Home.Graph: lookupAllHug :: HomeUnitGraph -> ModuleName -> IO [HomeModInfo]
+ GHC.Unit.Home.Graph: lookupHug :: HomeUnitGraph -> UnitId -> ModuleName -> IO (Maybe HomeModInfo)
+ GHC.Unit.Home.Graph: lookupHugByModule :: Module -> HomeUnitGraph -> IO (Maybe HomeModInfo)
+ GHC.Unit.Home.Graph: lookupHugUnit :: Unit -> HomeUnitGraph -> Maybe HomeUnitEnv
+ GHC.Unit.Home.Graph: lookupHugUnitId :: UnitId -> HomeUnitGraph -> Maybe HomeUnitEnv
+ GHC.Unit.Home.Graph: memberHugUnit :: Unit -> HomeUnitGraph -> Bool
+ GHC.Unit.Home.Graph: memberHugUnitId :: UnitId -> HomeUnitGraph -> Bool
+ GHC.Unit.Home.Graph: mkHomeUnitEnv :: UnitState -> Maybe [UnitDatabase UnitId] -> DynFlags -> HomePackageTable -> Maybe HomeUnit -> HomeUnitEnv
+ GHC.Unit.Home.Graph: newtype UnitEnvGraph v
+ GHC.Unit.Home.Graph: pprHomeUnitEnv :: UnitId -> HomeUnitEnv -> IO SDoc
+ GHC.Unit.Home.Graph: pprHomeUnitGraph :: HomeUnitGraph -> IO SDoc
+ GHC.Unit.Home.Graph: renameUnitId :: UnitId -> UnitId -> HomeUnitGraph -> Maybe HomeUnitGraph
+ GHC.Unit.Home.Graph: restrictHug :: [(UnitId, [HomeModInfo])] -> HomeUnitGraph -> IO ()
+ GHC.Unit.Home.Graph: transitiveHomeDeps :: UnitId -> HomeUnitGraph -> Maybe [UnitId]
+ GHC.Unit.Home.Graph: type HomeUnitGraph = UnitEnvGraph HomeUnitEnv
+ GHC.Unit.Home.Graph: unitEnv_adjust :: (v -> v) -> UnitEnvGraphKey -> UnitEnvGraph v -> UnitEnvGraph v
+ GHC.Unit.Home.Graph: unitEnv_assocs :: UnitEnvGraph a -> [(UnitEnvGraphKey, a)]
+ GHC.Unit.Home.Graph: unitEnv_foldWithKey :: (b -> UnitEnvGraphKey -> a -> b) -> b -> UnitEnvGraph a -> b
+ GHC.Unit.Home.Graph: unitEnv_insert :: UnitEnvGraphKey -> v -> UnitEnvGraph v -> UnitEnvGraph v
+ GHC.Unit.Home.Graph: unitEnv_keys :: UnitEnvGraph v -> Set UnitEnvGraphKey
+ GHC.Unit.Home.Graph: unitEnv_lookup :: UnitEnvGraphKey -> UnitEnvGraph v -> v
+ GHC.Unit.Home.Graph: unitEnv_lookup_maybe :: UnitEnvGraphKey -> UnitEnvGraph v -> Maybe v
+ GHC.Unit.Home.Graph: unitEnv_new :: Map UnitEnvGraphKey v -> UnitEnvGraph v
+ GHC.Unit.Home.Graph: unitEnv_singleton :: UnitEnvGraphKey -> v -> UnitEnvGraph v
+ GHC.Unit.Home.Graph: unitEnv_traverseWithKey :: Applicative f => (UnitEnvGraphKey -> a -> f b) -> UnitEnvGraph a -> f (UnitEnvGraph b)
+ GHC.Unit.Home.Graph: updateUnitFlags :: UnitId -> (DynFlags -> DynFlags) -> HomeUnitGraph -> HomeUnitGraph
+ GHC.Unit.Home.PackageTable: HPT :: IORef (DModuleNameEnv HomeModInfo) -> HomePackageTable
+ GHC.Unit.Home.PackageTable: [table] :: HomePackageTable -> IORef (DModuleNameEnv HomeModInfo)
+ GHC.Unit.Home.PackageTable: addHomeModInfoToHpt :: HomeModInfo -> HomePackageTable -> IO ()
+ GHC.Unit.Home.PackageTable: addHomeModInfosToHpt :: HomePackageTable -> [HomeModInfo] -> IO ()
+ GHC.Unit.Home.PackageTable: addListToHpt :: HomePackageTable -> [(ModuleName, HomeModInfo)] -> IO ()
+ GHC.Unit.Home.PackageTable: addToHpt :: HomePackageTable -> ModuleName -> HomeModInfo -> IO ()
+ GHC.Unit.Home.PackageTable: concatHpt :: (HomeModInfo -> [a]) -> HomePackageTable -> IO [a]
+ GHC.Unit.Home.PackageTable: emptyHomePackageTable :: IO HomePackageTable
+ GHC.Unit.Home.PackageTable: hptAllAnnotations :: HomePackageTable -> IO AnnEnv
+ GHC.Unit.Home.PackageTable: hptAllFamInstances :: HomePackageTable -> IO (ModuleEnv FamInstEnv)
+ GHC.Unit.Home.PackageTable: hptAllInstances :: HomePackageTable -> IO (InstEnv, [FamInst])
+ GHC.Unit.Home.PackageTable: hptCollectDependencies :: HomePackageTable -> IO (Set (IfaceImportLevel, UnitId))
+ GHC.Unit.Home.PackageTable: hptCollectModules :: HomePackageTable -> IO [Module]
+ GHC.Unit.Home.PackageTable: hptCollectObjects :: HomePackageTable -> IO [Linkable]
+ GHC.Unit.Home.PackageTable: hptCompleteSigs :: HomePackageTable -> IO CompleteMatches
+ GHC.Unit.Home.PackageTable: hptInternalTableFromRef :: IORef (DModuleNameEnv HomeModInfo) -> IO HomePackageTable
+ GHC.Unit.Home.PackageTable: hptInternalTableRef :: HomePackageTable -> IORef (DModuleNameEnv HomeModInfo)
+ GHC.Unit.Home.PackageTable: lookupHpt :: HomePackageTable -> ModuleName -> IO (Maybe HomeModInfo)
+ GHC.Unit.Home.PackageTable: lookupHptByModule :: HomePackageTable -> Module -> IO (Maybe HomeModInfo)
+ GHC.Unit.Home.PackageTable: newtype HomePackageTable
+ GHC.Unit.Home.PackageTable: pprHPT :: HomePackageTable -> IO SDoc
+ GHC.Unit.Home.PackageTable: restrictHpt :: HomePackageTable -> [HomeModInfo] -> IO ()
+ GHC.Unit.Info: instance GHC.Internal.Classes.Eq GHC.Unit.Info.PackageId
+ GHC.Unit.Info: instance GHC.Internal.Classes.Eq GHC.Unit.Info.PackageName
+ GHC.Unit.Module.Deps: HMIA_Explicit :: DetOrdAvails -> NameSet -> HomeModImportedAvails
+ GHC.Unit.Module.Deps: HMIA_Implicit :: Fingerprint -> HomeModImportedAvails
+ GHC.Unit.Module.Deps: HomeModImport :: Fingerprint -> HomeModImportedAvails -> HomeModImport
+ GHC.Unit.Module.Deps: IfaceImportLevel :: ImportLevel -> IfaceImportLevel
+ GHC.Unit.Module.Deps: [hmia_exportedAvailsHash] :: HomeModImportedAvails -> Fingerprint
+ GHC.Unit.Module.Deps: [hmia_imported_avails] :: HomeModImportedAvails -> DetOrdAvails
+ GHC.Unit.Module.Deps: [hmia_parents_with_implicits] :: HomeModImportedAvails -> NameSet
+ GHC.Unit.Module.Deps: [hmiu_importedAvails] :: HomeModImport -> HomeModImportedAvails
+ GHC.Unit.Module.Deps: [hmiu_orphanLikeHash] :: HomeModImport -> Fingerprint
+ GHC.Unit.Module.Deps: data HomeModImport
+ GHC.Unit.Module.Deps: data HomeModImportedAvails
+ GHC.Unit.Module.Deps: instance Control.DeepSeq.NFData GHC.Unit.Module.Deps.Dependencies
+ GHC.Unit.Module.Deps: instance Control.DeepSeq.NFData GHC.Unit.Module.Deps.HomeModImport
+ GHC.Unit.Module.Deps: instance Control.DeepSeq.NFData GHC.Unit.Module.Deps.HomeModImportedAvails
+ GHC.Unit.Module.Deps: instance Control.DeepSeq.NFData GHC.Unit.Module.Deps.IfaceImportLevel
+ GHC.Unit.Module.Deps: instance Control.DeepSeq.NFData GHC.Unit.Module.Deps.Usage
+ GHC.Unit.Module.Deps: instance GHC.Internal.Classes.Eq GHC.Unit.Module.Deps.Dependencies
+ GHC.Unit.Module.Deps: instance GHC.Internal.Classes.Eq GHC.Unit.Module.Deps.HomeModImport
+ GHC.Unit.Module.Deps: instance GHC.Internal.Classes.Eq GHC.Unit.Module.Deps.HomeModImportedAvails
+ GHC.Unit.Module.Deps: instance GHC.Internal.Classes.Eq GHC.Unit.Module.Deps.IfaceImportLevel
+ GHC.Unit.Module.Deps: instance GHC.Internal.Classes.Eq GHC.Unit.Module.Deps.Usage
+ GHC.Unit.Module.Deps: instance GHC.Internal.Classes.Ord GHC.Unit.Module.Deps.IfaceImportLevel
+ GHC.Unit.Module.Deps: instance GHC.Utils.Binary.Binary GHC.Unit.Module.Deps.HomeModImport
+ GHC.Unit.Module.Deps: instance GHC.Utils.Binary.Binary GHC.Unit.Module.Deps.HomeModImportedAvails
+ GHC.Unit.Module.Deps: instance GHC.Utils.Binary.Binary GHC.Unit.Module.Deps.IfaceImportLevel
+ GHC.Unit.Module.Deps: instance GHC.Utils.Outputable.Outputable GHC.Unit.Module.Deps.HomeModImport
+ GHC.Unit.Module.Deps: instance GHC.Utils.Outputable.Outputable GHC.Unit.Module.Deps.HomeModImportedAvails
+ GHC.Unit.Module.Deps: instance GHC.Utils.Outputable.Outputable GHC.Unit.Module.Deps.IfaceImportLevel
+ GHC.Unit.Module.Deps: newtype IfaceImportLevel
+ GHC.Unit.Module.Deps: pattern Dependencies :: Set (IfaceImportLevel, UnitId, ModuleNameWithIsBoot) -> Set (IfaceImportLevel, UnitId) -> Set UnitId -> [ModuleName] -> Set UnitId -> Set (UnitId, ModuleNameWithIsBoot) -> [Module] -> [Module] -> Dependencies
+ GHC.Unit.Module.Deps: tcImportLevel :: IfaceImportLevel -> ImportLevel
+ GHC.Unit.Module.Env: instance GHC.Internal.Classes.Eq GHC.Unit.Module.Env.NDModule
+ GHC.Unit.Module.Env: instance GHC.Internal.Classes.Ord GHC.Unit.Module.Env.NDModule
+ GHC.Unit.Module.Graph: DependencyNotInGraph :: NodeKey -> [NodeKey] -> ModuleGraphInvariantError
+ GHC.Unit.Module.Graph: DuplicateModuleNodeKey :: NodeKey -> ModuleGraphInvariantError
+ GHC.Unit.Module.Graph: FixedNodeDependsOnCompileNode :: ModNodeKeyWithUid -> [NodeKey] -> ModuleGraphInvariantError
+ GHC.Unit.Module.Graph: ModuleGraph :: [ModuleGraphNode] -> (ReachabilityIndex SummaryNode, NodeKey -> Maybe SummaryNode) -> (ReachabilityIndex SummaryNode, NodeKey -> Maybe SummaryNode) -> (ReachabilityIndex ZeroSummaryNode, ZeroScopeKey -> Maybe ZeroSummaryNode) -> Bool -> ModuleGraph
+ GHC.Unit.Module.Graph: ModuleNodeCompile :: ModSummary -> ModuleNodeInfo
+ GHC.Unit.Module.Graph: ModuleNodeEdge :: ImportLevel -> NodeKey -> ModuleNodeEdge
+ GHC.Unit.Module.Graph: ModuleNodeFixed :: ModNodeKeyWithUid -> ModLocation -> ModuleNodeInfo
+ GHC.Unit.Module.Graph: ModuleScope :: ModNodeKeyWithUid -> ImportLevel -> ZeroScopeKey
+ GHC.Unit.Module.Graph: NodeKey_ExternalUnit :: UnitId -> NodeKey
+ GHC.Unit.Module.Graph: NormalLevel :: ImportLevel
+ GHC.Unit.Module.Graph: QuoteLevel :: ImportLevel
+ GHC.Unit.Module.Graph: SpliceLevel :: ImportLevel
+ GHC.Unit.Module.Graph: UnitNode :: [UnitId] -> UnitId -> ModuleGraphNode
+ GHC.Unit.Module.Graph: UnitScope :: UnitId -> ZeroScopeKey
+ GHC.Unit.Module.Graph: [edgeLevel] :: ModuleNodeEdge -> ImportLevel
+ GHC.Unit.Module.Graph: [edgeTargetKey] :: ModuleNodeEdge -> NodeKey
+ GHC.Unit.Module.Graph: [mg_graph] :: ModuleGraph -> (ReachabilityIndex SummaryNode, NodeKey -> Maybe SummaryNode)
+ GHC.Unit.Module.Graph: [mg_has_holes] :: ModuleGraph -> Bool
+ GHC.Unit.Module.Graph: [mg_loop_graph] :: ModuleGraph -> (ReachabilityIndex SummaryNode, NodeKey -> Maybe SummaryNode)
+ GHC.Unit.Module.Graph: [mg_mss] :: ModuleGraph -> [ModuleGraphNode]
+ GHC.Unit.Module.Graph: [mg_zero_graph] :: ModuleGraph -> (ReachabilityIndex ZeroSummaryNode, ZeroScopeKey -> Maybe ZeroSummaryNode)
+ GHC.Unit.Module.Graph: checkModuleGraph :: ModuleGraph -> [ModuleGraphInvariantError]
+ GHC.Unit.Module.Graph: data ImportLevel
+ GHC.Unit.Module.Graph: data ModuleGraphInvariantError
+ GHC.Unit.Module.Graph: data ModuleNodeEdge
+ GHC.Unit.Module.Graph: data ModuleNodeInfo
+ GHC.Unit.Module.Graph: data ZeroScopeKey
+ GHC.Unit.Module.Graph: installedModuleToMnk :: InstalledModule -> ModNodeKeyWithUid
+ GHC.Unit.Module.Graph: instance GHC.Internal.Classes.Eq GHC.Unit.Module.Graph.ModuleGraphInvariantError
+ GHC.Unit.Module.Graph: instance GHC.Internal.Classes.Eq GHC.Unit.Module.Graph.ModuleGraphNode
+ GHC.Unit.Module.Graph: instance GHC.Internal.Classes.Eq GHC.Unit.Module.Graph.NodeKey
+ GHC.Unit.Module.Graph: instance GHC.Internal.Classes.Eq GHC.Unit.Module.Graph.ZeroScopeKey
+ GHC.Unit.Module.Graph: instance GHC.Internal.Classes.Ord GHC.Unit.Module.Graph.ModuleGraphInvariantError
+ GHC.Unit.Module.Graph: instance GHC.Internal.Classes.Ord GHC.Unit.Module.Graph.ModuleGraphNode
+ GHC.Unit.Module.Graph: instance GHC.Internal.Classes.Ord GHC.Unit.Module.Graph.NodeKey
+ GHC.Unit.Module.Graph: instance GHC.Internal.Classes.Ord GHC.Unit.Module.Graph.ZeroScopeKey
+ GHC.Unit.Module.Graph: instance GHC.Utils.Outputable.Outputable GHC.Unit.Module.Graph.ModuleGraphInvariantError
+ GHC.Unit.Module.Graph: instance GHC.Utils.Outputable.Outputable GHC.Unit.Module.Graph.ModuleNodeEdge
+ GHC.Unit.Module.Graph: instance GHC.Utils.Outputable.Outputable GHC.Unit.Module.Graph.ModuleNodeType
+ GHC.Unit.Module.Graph: instance GHC.Utils.Outputable.Outputable GHC.Unit.Module.Graph.ZeroScopeKey
+ GHC.Unit.Module.Graph: isBootModuleNodeInfo :: ModuleNodeInfo -> IsBootInterface
+ GHC.Unit.Module.Graph: isEmptyMG :: ModuleGraph -> Bool
+ GHC.Unit.Module.Graph: lengthMG :: ModuleGraph -> Int
+ GHC.Unit.Module.Graph: mgHasHoles :: ModuleGraph -> Bool
+ GHC.Unit.Module.Graph: mgLookupModuleName :: ModuleGraph -> ModuleNameWithIsBoot -> [ModuleNodeInfo]
+ GHC.Unit.Module.Graph: mgMapM :: (ModuleNodeInfo -> IO ModuleNodeInfo) -> ModuleGraph -> IO ModuleGraph
+ GHC.Unit.Module.Graph: mgMember :: ModuleGraph -> NodeKey -> Bool
+ GHC.Unit.Module.Graph: mgNodeDependencies :: Bool -> ModuleGraphNode -> [NodeKey]
+ GHC.Unit.Module.Graph: mgNodeIsModule :: ModuleGraphNode -> Maybe ModuleNodeInfo
+ GHC.Unit.Module.Graph: mgNodeUnitId :: ModuleGraphNode -> UnitId
+ GHC.Unit.Module.Graph: mgQuery :: ModuleGraph -> NodeKey -> NodeKey -> Bool
+ GHC.Unit.Module.Graph: mgQueryMany :: ModuleGraph -> [NodeKey] -> NodeKey -> Bool
+ GHC.Unit.Module.Graph: mgQueryManyZero :: ModuleGraph -> [ZeroScopeKey] -> ZeroScopeKey -> Bool
+ GHC.Unit.Module.Graph: mgQueryZero :: ModuleGraph -> ZeroScopeKey -> ZeroScopeKey -> Bool
+ GHC.Unit.Module.Graph: mgReachable :: ModuleGraph -> NodeKey -> Maybe [ModuleGraphNode]
+ GHC.Unit.Module.Graph: mgReachableLoop :: ModuleGraph -> [NodeKey] -> [ModuleGraphNode]
+ GHC.Unit.Module.Graph: miKey :: ModIface -> ModNodeKeyWithUid
+ GHC.Unit.Module.Graph: mkModuleEdge :: ImportLevel -> NodeKey -> ModuleNodeEdge
+ GHC.Unit.Module.Graph: mkModuleGraphChecked :: [ModuleGraphNode] -> Either [ModuleGraphInvariantError] ModuleGraph
+ GHC.Unit.Module.Graph: mkNormalEdge :: NodeKey -> ModuleNodeEdge
+ GHC.Unit.Module.Graph: mkStageDeps :: [ModuleGraphNode] -> (ReachabilityIndex StageSummaryNode, (NodeKey, ModuleStage) -> Maybe StageSummaryNode)
+ GHC.Unit.Module.Graph: mnKey :: ModuleNodeInfo -> ModNodeKeyWithUid
+ GHC.Unit.Module.Graph: mnkIsBoot :: ModNodeKeyWithUid -> IsBootInterface
+ GHC.Unit.Module.Graph: mnkToInstalledModule :: ModNodeKeyWithUid -> InstalledModule
+ GHC.Unit.Module.Graph: mnkToModule :: ModNodeKeyWithUid -> Module
+ GHC.Unit.Module.Graph: moduleGraphNodesZero :: [ModuleGraphNode] -> (Graph ZeroSummaryNode, ZeroScopeKey -> Maybe ZeroSummaryNode)
+ GHC.Unit.Module.Graph: moduleNodeInfoHscSource :: ModuleNodeInfo -> Maybe HscSource
+ GHC.Unit.Module.Graph: moduleNodeInfoLocation :: ModuleNodeInfo -> ModLocation
+ GHC.Unit.Module.Graph: moduleNodeInfoMnwib :: ModuleNodeInfo -> ModuleNameWithIsBoot
+ GHC.Unit.Module.Graph: moduleNodeInfoModNodeKeyWithUid :: ModuleNodeInfo -> ModNodeKeyWithUid
+ GHC.Unit.Module.Graph: moduleNodeInfoModule :: ModuleNodeInfo -> Module
+ GHC.Unit.Module.Graph: moduleNodeInfoModuleName :: ModuleNodeInfo -> ModuleName
+ GHC.Unit.Module.Graph: moduleNodeInfoUnitId :: ModuleNodeInfo -> UnitId
+ GHC.Unit.Module.Graph: moduleToMnk :: Module -> IsBootInterface -> ModNodeKeyWithUid
+ GHC.Unit.Module.Graph: stageSummaryNodeKey :: StageSummaryNode -> Int
+ GHC.Unit.Module.Graph: stageSummaryNodeSummary :: StageSummaryNode -> (NodeKey, ModuleStage)
+ GHC.Unit.Module.Graph: summaryNodeKey :: SummaryNode -> Int
+ GHC.Unit.Module.Graph: type StageSummaryNode = Node Int (NodeKey, ModuleStage)
+ GHC.Unit.Module.Imported: [imv_is_level] :: ImportedModsVal -> ImportLevel
+ GHC.Unit.Module.ModIface: IfaceAbiHashes :: Fingerprint -> WhetherHasOrphans -> WhetherHasFamInst -> Fingerprint -> Fingerprint -> Fingerprint -> IfaceAbiHashes
+ GHC.Unit.Module.ModIface: IfaceCache :: (OccName -> Maybe (WarningTxt GhcRn)) -> (Name -> Maybe (WarningTxt GhcRn)) -> (OccName -> Maybe Fixity) -> (OccName -> Maybe (OccName, Fingerprint)) -> IfaceCache
+ GHC.Unit.Module.ModIface: IfaceModInfo :: Module -> Maybe Module -> HscSource -> IfaceModInfo
+ GHC.Unit.Module.ModIface: IfacePublic :: [IfaceExport] -> [(OccName, Fixity)] -> IfaceWarnings -> [IfaceAnnotation] -> [IfaceDeclExts phase] -> [IfaceDefault] -> [IfaceClsInst] -> [IfaceFamInst] -> [IfaceRule] -> IfaceTrustInfo -> Bool -> [IfaceCompleteMatch] -> IfaceCache -> IfaceAbiHashesExts phase -> IfacePublic_ (phase :: ModIfacePhase)
+ GHC.Unit.Module.ModIface: IfaceSelfRecomp :: Fingerprint -> [Usage] -> FingerprintWithValue IfaceDynFlags -> Fingerprint -> Fingerprint -> Fingerprint -> IfaceSelfRecomp
+ GHC.Unit.Module.ModIface: IfaceSimplifiedCore :: [IfaceBindingX IfaceMaybeRhs IfaceTopBndrInfo] -> IfaceForeign -> IfaceSimplifiedCore
+ GHC.Unit.Module.ModIface: [mi_abi_export_avails_hash] :: IfaceAbiHashes -> Fingerprint
+ GHC.Unit.Module.ModIface: [mi_abi_finsts] :: IfaceAbiHashes -> WhetherHasFamInst
+ GHC.Unit.Module.ModIface: [mi_abi_hashes_] :: IfacePublic_ (phase :: ModIfacePhase) -> IfaceAbiHashesExts phase
+ GHC.Unit.Module.ModIface: [mi_abi_mod_hash] :: IfaceAbiHashes -> Fingerprint
+ GHC.Unit.Module.ModIface: [mi_abi_orphan] :: IfaceAbiHashes -> WhetherHasOrphans
+ GHC.Unit.Module.ModIface: [mi_abi_orphan_hash] :: IfaceAbiHashes -> Fingerprint
+ GHC.Unit.Module.ModIface: [mi_abi_orphan_like_hash] :: IfaceAbiHashes -> Fingerprint
+ GHC.Unit.Module.ModIface: [mi_anns_] :: IfacePublic_ (phase :: ModIfacePhase) -> [IfaceAnnotation]
+ GHC.Unit.Module.ModIface: [mi_cache_decl_warn_fn] :: IfaceCache -> OccName -> Maybe (WarningTxt GhcRn)
+ GHC.Unit.Module.ModIface: [mi_cache_export_warn_fn] :: IfaceCache -> Name -> Maybe (WarningTxt GhcRn)
+ GHC.Unit.Module.ModIface: [mi_cache_fix_fn] :: IfaceCache -> OccName -> Maybe Fixity
+ GHC.Unit.Module.ModIface: [mi_cache_hash_fn] :: IfaceCache -> OccName -> Maybe (OccName, Fingerprint)
+ GHC.Unit.Module.ModIface: [mi_caches_] :: IfacePublic_ (phase :: ModIfacePhase) -> IfaceCache
+ GHC.Unit.Module.ModIface: [mi_complete_matches_] :: IfacePublic_ (phase :: ModIfacePhase) -> [IfaceCompleteMatch]
+ GHC.Unit.Module.ModIface: [mi_decls_] :: IfacePublic_ (phase :: ModIfacePhase) -> [IfaceDeclExts phase]
+ GHC.Unit.Module.ModIface: [mi_defaults_] :: IfacePublic_ (phase :: ModIfacePhase) -> [IfaceDefault]
+ GHC.Unit.Module.ModIface: [mi_exports_] :: IfacePublic_ (phase :: ModIfacePhase) -> [IfaceExport]
+ GHC.Unit.Module.ModIface: [mi_fam_insts_] :: IfacePublic_ (phase :: ModIfacePhase) -> [IfaceFamInst]
+ GHC.Unit.Module.ModIface: [mi_fixities_] :: IfacePublic_ (phase :: ModIfacePhase) -> [(OccName, Fixity)]
+ GHC.Unit.Module.ModIface: [mi_insts_] :: IfacePublic_ (phase :: ModIfacePhase) -> [IfaceClsInst]
+ GHC.Unit.Module.ModIface: [mi_mod_info_hsc_src] :: IfaceModInfo -> HscSource
+ GHC.Unit.Module.ModIface: [mi_mod_info_module] :: IfaceModInfo -> Module
+ GHC.Unit.Module.ModIface: [mi_mod_info_sig_of] :: IfaceModInfo -> Maybe Module
+ GHC.Unit.Module.ModIface: [mi_rules_] :: IfacePublic_ (phase :: ModIfacePhase) -> [IfaceRule]
+ GHC.Unit.Module.ModIface: [mi_sc_extra_decls] :: IfaceSimplifiedCore -> [IfaceBindingX IfaceMaybeRhs IfaceTopBndrInfo]
+ GHC.Unit.Module.ModIface: [mi_sc_foreign] :: IfaceSimplifiedCore -> IfaceForeign
+ GHC.Unit.Module.ModIface: [mi_sr_flag_hash] :: IfaceSelfRecomp -> FingerprintWithValue IfaceDynFlags
+ GHC.Unit.Module.ModIface: [mi_sr_hpc_hash] :: IfaceSelfRecomp -> Fingerprint
+ GHC.Unit.Module.ModIface: [mi_sr_opt_hash] :: IfaceSelfRecomp -> Fingerprint
+ GHC.Unit.Module.ModIface: [mi_sr_plugin_hash] :: IfaceSelfRecomp -> Fingerprint
+ GHC.Unit.Module.ModIface: [mi_sr_src_hash] :: IfaceSelfRecomp -> Fingerprint
+ GHC.Unit.Module.ModIface: [mi_sr_usages] :: IfaceSelfRecomp -> [Usage]
+ GHC.Unit.Module.ModIface: [mi_trust_] :: IfacePublic_ (phase :: ModIfacePhase) -> IfaceTrustInfo
+ GHC.Unit.Module.ModIface: [mi_trust_pkg_] :: IfacePublic_ (phase :: ModIfacePhase) -> Bool
+ GHC.Unit.Module.ModIface: [mi_warns_] :: IfacePublic_ (phase :: ModIfacePhase) -> IfaceWarnings
+ GHC.Unit.Module.ModIface: data IfaceAbiHashes
+ GHC.Unit.Module.ModIface: data IfaceCache
+ GHC.Unit.Module.ModIface: data IfaceModInfo
+ GHC.Unit.Module.ModIface: data IfacePublic_ (phase :: ModIfacePhase)
+ GHC.Unit.Module.ModIface: data IfaceSelfRecomp
+ GHC.Unit.Module.ModIface: data IfaceSimplifiedCore
+ GHC.Unit.Module.ModIface: instance (Control.DeepSeq.NFData (GHC.Unit.Module.ModIface.IfaceAbiHashesExts phase), Control.DeepSeq.NFData (GHC.Unit.Module.ModIface.IfaceDeclExts phase)) => Control.DeepSeq.NFData (GHC.Unit.Module.ModIface.IfacePublic_ phase)
+ GHC.Unit.Module.ModIface: instance (Control.DeepSeq.NFData (GHC.Unit.Module.ModIface.IfaceAbiHashesExts phase), Control.DeepSeq.NFData (GHC.Unit.Module.ModIface.IfaceDeclExts phase)) => Control.DeepSeq.NFData (GHC.Unit.Module.ModIface.ModIface_ phase)
+ GHC.Unit.Module.ModIface: instance Control.DeepSeq.NFData GHC.Unit.Module.ModIface.IfaceAbiHashes
+ GHC.Unit.Module.ModIface: instance Control.DeepSeq.NFData GHC.Unit.Module.ModIface.IfaceCache
+ GHC.Unit.Module.ModIface: instance Control.DeepSeq.NFData GHC.Unit.Module.ModIface.IfaceModInfo
+ GHC.Unit.Module.ModIface: instance Control.DeepSeq.NFData GHC.Unit.Module.ModIface.IfaceSimplifiedCore
+ GHC.Unit.Module.ModIface: instance GHC.Utils.Binary.Binary (GHC.Unit.Module.ModIface.IfacePublic_ 'GHC.Unit.Module.ModIface.ModIfaceFinal)
+ GHC.Unit.Module.ModIface: instance GHC.Utils.Binary.Binary GHC.Unit.Module.ModIface.IfaceAbiHashes
+ GHC.Unit.Module.ModIface: instance GHC.Utils.Binary.Binary GHC.Unit.Module.ModIface.IfaceModInfo
+ GHC.Unit.Module.ModIface: instance GHC.Utils.Binary.Binary GHC.Unit.Module.ModIface.IfaceSimplifiedCore
+ GHC.Unit.Module.ModIface: instance GHC.Utils.Binary.Binary GHC.Unit.Module.ModIface.IfaceTopEnv
+ GHC.Unit.Module.ModIface: mi_export_avails_hash :: ModIface -> Fingerprint
+ GHC.Unit.Module.ModIface: mi_finsts :: ModIface -> WhetherHasFamInst
+ GHC.Unit.Module.ModIface: mi_flag_hash :: forall (phase :: ModIfacePhase). ModIface_ phase -> Maybe (FingerprintWithValue IfaceDynFlags)
+ GHC.Unit.Module.ModIface: mi_hpc_hash :: forall (phase :: ModIfacePhase). ModIface_ phase -> Maybe Fingerprint
+ GHC.Unit.Module.ModIface: mi_mod_hash :: ModIface -> Fingerprint
+ GHC.Unit.Module.ModIface: mi_mod_info_semantic_module :: IfaceModInfo -> Module
+ GHC.Unit.Module.ModIface: mi_opt_hash :: forall (phase :: ModIfacePhase). ModIface_ phase -> Maybe Fingerprint
+ GHC.Unit.Module.ModIface: mi_orphan :: ModIface -> WhetherHasOrphans
+ GHC.Unit.Module.ModIface: mi_orphan_hash :: ModIface -> Fingerprint
+ GHC.Unit.Module.ModIface: mi_orphan_like_hash :: ModIface -> Fingerprint
+ GHC.Unit.Module.ModIface: mi_plugin_hash :: forall (phase :: ModIfacePhase). ModIface_ phase -> Maybe Fingerprint
+ GHC.Unit.Module.ModIface: mi_src_hash :: forall (phase :: ModIfacePhase). ModIface_ phase -> Maybe Fingerprint
+ GHC.Unit.Module.ModIface: mi_usages :: forall (phase :: ModIfacePhase). ModIface_ phase -> Maybe [Usage]
+ GHC.Unit.Module.ModIface: set_mi_abi_hashes :: forall (phase :: ModIfacePhase). IfaceAbiHashesExts phase -> ModIface_ phase -> ModIface_ phase
+ GHC.Unit.Module.ModIface: set_mi_caches :: forall (phase :: ModIfacePhase). IfaceCache -> ModIface_ phase -> ModIface_ phase
+ GHC.Unit.Module.ModIface: set_mi_decl_warn_fn :: forall (phase :: ModIfacePhase). (OccName -> Maybe (WarningTxt GhcRn)) -> ModIface_ phase -> ModIface_ phase
+ GHC.Unit.Module.ModIface: set_mi_export_warn_fn :: forall (phase :: ModIfacePhase). (Name -> Maybe (WarningTxt GhcRn)) -> ModIface_ phase -> ModIface_ phase
+ GHC.Unit.Module.ModIface: set_mi_fix_fn :: forall (phase :: ModIfacePhase). (OccName -> Maybe Fixity) -> ModIface_ phase -> ModIface_ phase
+ GHC.Unit.Module.ModIface: set_mi_hash_fn :: forall (phase :: ModIfacePhase). (OccName -> Maybe (OccName, Fingerprint)) -> ModIface_ phase -> ModIface_ phase
+ GHC.Unit.Module.ModIface: set_mi_mod_info :: forall (phase :: ModIfacePhase). IfaceModInfo -> ModIface_ phase -> ModIface_ phase
+ GHC.Unit.Module.ModIface: set_mi_self_recomp :: forall (phase :: ModIfacePhase). Maybe IfaceSelfRecomp -> ModIface_ phase -> ModIface_ phase
+ GHC.Unit.Module.ModIface: set_mi_simplified_core :: forall (phase :: ModIfacePhase). Maybe IfaceSimplifiedCore -> ModIface_ phase -> ModIface_ phase
+ GHC.Unit.Module.ModIface: type IfacePublic = IfacePublic_ 'ModIfaceFinal
+ GHC.Unit.Module.ModIface: type PartialIfacePublic = IfacePublic_ 'ModIfaceCore
+ GHC.Unit.Module.ModIface: withSelfRecomp :: forall (phase :: ModIfacePhase) r. ModIface_ phase -> r -> (IfaceSelfRecomp -> r) -> r
+ GHC.Unit.Module.ModNodeKey: ModNodeKeyWithUid :: ModuleNameWithIsBoot -> UnitId -> ModNodeKeyWithUid
+ GHC.Unit.Module.ModNodeKey: [mnkModuleName] :: ModNodeKeyWithUid -> ModuleNameWithIsBoot
+ GHC.Unit.Module.ModNodeKey: [mnkUnitId] :: ModNodeKeyWithUid -> UnitId
+ GHC.Unit.Module.ModNodeKey: data ModNodeKeyWithUid
+ GHC.Unit.Module.ModNodeKey: installedModuleToMnk :: InstalledModule -> ModNodeKeyWithUid
+ GHC.Unit.Module.ModNodeKey: instance GHC.Internal.Classes.Eq GHC.Unit.Module.ModNodeKey.ModNodeKeyWithUid
+ GHC.Unit.Module.ModNodeKey: instance GHC.Internal.Classes.Ord GHC.Unit.Module.ModNodeKey.ModNodeKeyWithUid
+ GHC.Unit.Module.ModNodeKey: instance GHC.Utils.Outputable.Outputable GHC.Unit.Module.ModNodeKey.ModNodeKeyWithUid
+ GHC.Unit.Module.ModNodeKey: mnkIsBoot :: ModNodeKeyWithUid -> IsBootInterface
+ GHC.Unit.Module.ModNodeKey: mnkToInstalledModule :: ModNodeKeyWithUid -> InstalledModule
+ GHC.Unit.Module.ModNodeKey: mnkToModule :: ModNodeKeyWithUid -> Module
+ GHC.Unit.Module.ModNodeKey: moduleToMnk :: Module -> IsBootInterface -> ModNodeKeyWithUid
+ GHC.Unit.Module.ModSummary: isTemplateHaskellOrQQNonBoot :: ModSummary -> Bool
+ GHC.Unit.Module.Stage: CompileStage :: ModuleStage
+ GHC.Unit.Module.Stage: RunStage :: ModuleStage
+ GHC.Unit.Module.Stage: allStages :: [ModuleStage]
+ GHC.Unit.Module.Stage: data ModuleStage
+ GHC.Unit.Module.Stage: decModuleStage :: ModuleStage -> ModuleStage
+ GHC.Unit.Module.Stage: incModuleStage :: ModuleStage -> ModuleStage
+ GHC.Unit.Module.Stage: instance GHC.Internal.Classes.Eq GHC.Unit.Module.Stage.ModuleStage
+ GHC.Unit.Module.Stage: instance GHC.Internal.Classes.Ord GHC.Unit.Module.Stage.ModuleStage
+ GHC.Unit.Module.Stage: instance GHC.Internal.Enum.Bounded GHC.Unit.Module.Stage.ModuleStage
+ GHC.Unit.Module.Stage: instance GHC.Internal.Enum.Enum GHC.Unit.Module.Stage.ModuleStage
+ GHC.Unit.Module.Stage: instance GHC.Utils.Outputable.Outputable GHC.Unit.Module.Stage.ModuleStage
+ GHC.Unit.Module.Stage: maxStage :: ModuleStage
+ GHC.Unit.Module.Stage: minStage :: ModuleStage
+ GHC.Unit.Module.Stage: nowAndFutureStages :: ModuleStage -> [ModuleStage]
+ GHC.Unit.Module.Stage: onlyFutureStages :: ModuleStage -> [ModuleStage]
+ GHC.Unit.Module.Stage: zeroStage :: ModuleStage
+ GHC.Unit.Module.Status: instance GHC.Utils.Outputable.Outputable GHC.Unit.Module.Status.HscRecompStatus
+ GHC.Unit.Module.Warnings: instance GHC.Internal.Classes.Eq (Language.Haskell.Syntax.Extension.IdP pass) => GHC.Internal.Classes.Eq (GHC.Unit.Module.Warnings.WarningTxt pass)
+ GHC.Unit.Module.Warnings: instance GHC.Internal.Classes.Eq (Language.Haskell.Syntax.Extension.IdP pass) => GHC.Internal.Classes.Eq (GHC.Unit.Module.Warnings.Warnings pass)
+ GHC.Unit.Module.Warnings: instance GHC.Internal.Classes.Eq GHC.Unit.Module.Warnings.InWarningCategory
+ GHC.Unit.Module.Warnings: instance GHC.Internal.Classes.Eq GHC.Unit.Module.Warnings.WarningCategory
+ GHC.Unit.State: pprRawUnitIds :: SDoc -> SDoc
+ GHC.Unit.Types: instance Control.DeepSeq.NFData GHC.Unit.Types.UnitId
+ GHC.Unit.Types: instance Control.DeepSeq.NFData mod => Control.DeepSeq.NFData (GHC.Unit.Types.GenWithIsBoot mod)
+ GHC.Unit.Types: instance GHC.Internal.Classes.Eq (GHC.Unit.Types.GenInstantiatedUnit unit)
+ GHC.Unit.Types: instance GHC.Internal.Classes.Eq GHC.Unit.Types.UnitId
+ GHC.Unit.Types: instance GHC.Internal.Classes.Eq mod => GHC.Internal.Classes.Eq (GHC.Unit.Types.GenWithIsBoot mod)
+ GHC.Unit.Types: instance GHC.Internal.Classes.Eq unit => GHC.Internal.Classes.Eq (GHC.Unit.Types.Definite unit)
+ GHC.Unit.Types: instance GHC.Internal.Classes.Eq unit => GHC.Internal.Classes.Eq (GHC.Unit.Types.GenModule unit)
+ GHC.Unit.Types: instance GHC.Internal.Classes.Ord (GHC.Unit.Types.GenInstantiatedUnit unit)
+ GHC.Unit.Types: instance GHC.Internal.Classes.Ord GHC.Unit.Types.Unit
+ GHC.Unit.Types: instance GHC.Internal.Classes.Ord GHC.Unit.Types.UnitId
+ GHC.Unit.Types: instance GHC.Internal.Classes.Ord mod => GHC.Internal.Classes.Ord (GHC.Unit.Types.GenWithIsBoot mod)
+ GHC.Unit.Types: instance GHC.Internal.Classes.Ord unit => GHC.Internal.Classes.Ord (GHC.Unit.Types.Definite unit)
+ GHC.Unit.Types: instance GHC.Internal.Classes.Ord unit => GHC.Internal.Classes.Ord (GHC.Unit.Types.GenModule unit)
+ GHC.Unit.Types: instance GHC.Unit.Types.IsUnitId u => GHC.Internal.Classes.Eq (GHC.Unit.Types.GenUnit u)
+ GHC.Unit.Types: interactiveGhciUnit :: Unit
+ GHC.Unit.Types: interactiveGhciUnitId :: UnitId
+ GHC.Unit.Types: interactiveSessionUnit :: Unit
+ GHC.Unit.Types: interactiveSessionUnitId :: UnitId
+ GHC.Utils.Binary: EnumBinary :: a -> EnumBinary a
+ GHC.Utils.Binary: FingerprintWithValue :: Fingerprint -> Maybe a -> FingerprintWithValue a
+ GHC.Utils.Binary: [unEnumBinary] :: EnumBinary a -> a
+ GHC.Utils.Binary: data FingerprintWithValue a
+ GHC.Utils.Binary: instance (GHC.Utils.Binary.Binary a, GHC.Internal.Classes.Ord a) => GHC.Utils.Binary.Binary (Data.Set.Internal.Set a)
+ GHC.Utils.Binary: instance Control.DeepSeq.NFData a => Control.DeepSeq.NFData (GHC.Utils.Binary.FingerprintWithValue a)
+ GHC.Utils.Binary: instance GHC.Internal.Base.Functor GHC.Utils.Binary.FingerprintWithValue
+ GHC.Utils.Binary: instance GHC.Internal.Classes.Eq GHC.Utils.Binary.BindingName
+ GHC.Utils.Binary: instance GHC.Internal.Classes.Eq GHC.Utils.Binary.FullBinData
+ GHC.Utils.Binary: instance GHC.Internal.Classes.Eq a => GHC.Internal.Classes.Eq (GHC.Utils.Binary.FixedLengthEncoding a)
+ GHC.Utils.Binary: instance GHC.Internal.Classes.Ord GHC.Utils.Binary.FullBinData
+ GHC.Utils.Binary: instance GHC.Internal.Classes.Ord a => GHC.Internal.Classes.Ord (GHC.Utils.Binary.FixedLengthEncoding a)
+ GHC.Utils.Binary: instance GHC.Internal.Enum.Enum a => GHC.Utils.Binary.Binary (GHC.Utils.Binary.EnumBinary a)
+ GHC.Utils.Binary: instance GHC.Utils.Binary.Binary Data.ByteString.Short.Internal.ShortByteString
+ GHC.Utils.Binary: instance GHC.Utils.Binary.Binary GHC.Internal.Bignum.Integer.Integer
+ GHC.Utils.Binary: instance GHC.Utils.Binary.Binary GHC.Internal.Types.Bool
+ GHC.Utils.Binary: instance GHC.Utils.Binary.Binary GHC.Internal.Types.Char
+ GHC.Utils.Binary: instance GHC.Utils.Binary.Binary GHC.Internal.Types.Int
+ GHC.Utils.Binary: instance GHC.Utils.Binary.Binary Language.Haskell.Syntax.ImpExp.IsBoot.IsBootInterface
+ GHC.Utils.Binary: instance GHC.Utils.Binary.Binary a => GHC.Utils.Binary.Binary (GHC.Utils.Binary.FingerprintWithValue a)
+ GHC.Utils.Binary: instance forall k (a :: k). GHC.Internal.Classes.Eq (GHC.Utils.Binary.Bin a)
+ GHC.Utils.Binary: instance forall k (a :: k). GHC.Internal.Classes.Eq (GHC.Utils.Binary.RelBin a)
+ GHC.Utils.Binary: instance forall k (a :: k). GHC.Internal.Classes.Eq (GHC.Utils.Binary.RelBinPtr a)
+ GHC.Utils.Binary: instance forall k (a :: k). GHC.Internal.Classes.Ord (GHC.Utils.Binary.Bin a)
+ GHC.Utils.Binary: instance forall k (a :: k). GHC.Internal.Classes.Ord (GHC.Utils.Binary.RelBin a)
+ GHC.Utils.Binary: instance forall k (a :: k). GHC.Internal.Classes.Ord (GHC.Utils.Binary.RelBinPtr a)
+ GHC.Utils.Binary: newtype EnumBinary a
+ GHC.Utils.Binary.Typeable: instance GHC.Utils.Binary.Binary GHC.Internal.Types.KindRep
+ GHC.Utils.Binary.Typeable: instance GHC.Utils.Binary.Binary GHC.Internal.Types.RuntimeRep
+ GHC.Utils.Binary.Typeable: instance GHC.Utils.Binary.Binary GHC.Internal.Types.TyCon
+ GHC.Utils.Binary.Typeable: instance GHC.Utils.Binary.Binary GHC.Internal.Types.TypeLitSort
+ GHC.Utils.Binary.Typeable: instance GHC.Utils.Binary.Binary GHC.Internal.Types.VecCount
+ GHC.Utils.Binary.Typeable: instance GHC.Utils.Binary.Binary GHC.Internal.Types.VecElem
+ GHC.Utils.CliOption: instance GHC.Internal.Classes.Eq GHC.Utils.CliOption.Option
+ GHC.Utils.Error: -- <a>GhcHint</a>.
+ GHC.Utils.Error: instance GHC.Internal.Classes.Eq GHC.Utils.Error.PrintTimings
+ GHC.Utils.Error: type DiagnosticHint a = GhcHint;
+ GHC.Utils.Exception: displayExceptionWithInfo :: SomeException -> String
+ GHC.Utils.Json: instance GHC.Utils.Json.ToJson GHC.Internal.Types.Int
+ GHC.Utils.Logger: defaultLogActionWithHandles :: Handle -> Handle -> LogAction
+ GHC.Utils.Logger: instance GHC.Internal.Classes.Eq GHC.Utils.Logger.DumpFormat
+ GHC.Utils.Misc: all2Prefix :: (a -> b -> Bool) -> [a] -> [b] -> Bool
+ GHC.Utils.Misc: all3Prefix :: (a -> b -> c -> Bool) -> [a] -> [b] -> [c] -> Bool
+ GHC.Utils.Misc: foldl1WithDefault' :: Foldable f => a -> (a -> a -> a) -> f a -> a
+ GHC.Utils.Misc: foldr1WithDefault :: Foldable f => a -> (a -> a -> a) -> f a -> a
+ GHC.Utils.Monad: infixl 4 <$>
+ GHC.Utils.Outputable: instance GHC.Internal.Classes.Eq GHC.Utils.Outputable.BindingSite
+ GHC.Utils.Outputable: instance GHC.Internal.Classes.Eq GHC.Utils.Outputable.JoinPointHood
+ GHC.Utils.Outputable: instance GHC.Utils.Outputable.Outputable GHC.Internal.Bignum.Integer.Integer
+ GHC.Utils.Outputable: instance GHC.Utils.Outputable.Outputable GHC.Internal.Types.Bool
+ GHC.Utils.Outputable: instance GHC.Utils.Outputable.Outputable GHC.Internal.Types.Double
+ GHC.Utils.Outputable: instance GHC.Utils.Outputable.Outputable GHC.Internal.Types.Float
+ GHC.Utils.Outputable: instance GHC.Utils.Outputable.Outputable GHC.Internal.Types.Int
+ GHC.Utils.Outputable: instance GHC.Utils.Outputable.Outputable GHC.Internal.Types.Ordering
+ GHC.Utils.Outputable: instance GHC.Utils.Outputable.Outputable GHC.Internal.Types.Word
+ GHC.Utils.Outputable: pluralSet :: Set a -> SDoc
+ GHC.Utils.Outputable: pprUnquotedSet :: Outputable a => Set a -> SDoc
+ Language.Haskell.Syntax.Basic: instance Control.DeepSeq.NFData Language.Haskell.Syntax.Basic.Fixity
+ Language.Haskell.Syntax.Basic: instance Control.DeepSeq.NFData Language.Haskell.Syntax.Basic.FixityDirection
+ Language.Haskell.Syntax.Basic: instance GHC.Internal.Classes.Eq Language.Haskell.Syntax.Basic.Boxity
+ Language.Haskell.Syntax.Basic: instance GHC.Internal.Classes.Eq Language.Haskell.Syntax.Basic.FieldLabelString
+ Language.Haskell.Syntax.Basic: instance GHC.Internal.Classes.Eq Language.Haskell.Syntax.Basic.Fixity
+ Language.Haskell.Syntax.Basic: instance GHC.Internal.Classes.Eq Language.Haskell.Syntax.Basic.FixityDirection
+ Language.Haskell.Syntax.Basic: instance GHC.Internal.Classes.Eq Language.Haskell.Syntax.Basic.LexicalFixity
+ Language.Haskell.Syntax.Basic: instance GHC.Internal.Classes.Eq Language.Haskell.Syntax.Basic.Role
+ Language.Haskell.Syntax.Basic: instance GHC.Internal.Classes.Eq Language.Haskell.Syntax.Basic.SrcStrictness
+ Language.Haskell.Syntax.Basic: instance GHC.Internal.Classes.Eq Language.Haskell.Syntax.Basic.SrcUnpackedness
+ Language.Haskell.Syntax.Basic: instance GHC.Internal.Classes.Ord Language.Haskell.Syntax.Basic.Role
+ Language.Haskell.Syntax.Binds: RuleBndr :: XCRuleBndr pass -> LIdP pass -> RuleBndr pass
+ Language.Haskell.Syntax.Binds: RuleBndrSig :: XRuleBndrSig pass -> LIdP pass -> HsPatSigType pass -> RuleBndr pass
+ Language.Haskell.Syntax.Binds: RuleBndrs :: XCRuleBndrs pass -> Maybe [LHsTyVarBndr () (NoGhcTc pass)] -> [LRuleBndr (NoGhcTc pass)] -> RuleBndrs pass
+ Language.Haskell.Syntax.Binds: SpecSigE :: XSpecSigE pass -> RuleBndrs pass -> LHsExpr pass -> InlinePragma -> Sig pass
+ Language.Haskell.Syntax.Binds: XRuleBndr :: XXRuleBndr pass -> RuleBndr pass
+ Language.Haskell.Syntax.Binds: XRuleBndrs :: XXRuleBndrs pass -> RuleBndrs pass
+ Language.Haskell.Syntax.Binds: [rb_ext] :: RuleBndrs pass -> XCRuleBndrs pass
+ Language.Haskell.Syntax.Binds: [rb_tmvs] :: RuleBndrs pass -> [LRuleBndr (NoGhcTc pass)]
+ Language.Haskell.Syntax.Binds: [rb_tyvs] :: RuleBndrs pass -> Maybe [LHsTyVarBndr () (NoGhcTc pass)]
+ Language.Haskell.Syntax.Binds: collectRuleBndrSigTys :: [RuleBndr pass] -> [HsPatSigType pass]
+ Language.Haskell.Syntax.Binds: data RuleBndr pass
+ Language.Haskell.Syntax.Binds: data RuleBndrs pass
+ Language.Haskell.Syntax.Binds: type LRuleBndr pass = XRec pass RuleBndr pass
+ Language.Haskell.Syntax.BooleanFormula: And :: [LBooleanFormula p] -> BooleanFormula p
+ Language.Haskell.Syntax.BooleanFormula: Or :: [LBooleanFormula p] -> BooleanFormula p
+ Language.Haskell.Syntax.BooleanFormula: Parens :: LBooleanFormula p -> BooleanFormula p
+ Language.Haskell.Syntax.BooleanFormula: Var :: LIdP p -> BooleanFormula p
+ Language.Haskell.Syntax.BooleanFormula: data BooleanFormula p
+ Language.Haskell.Syntax.BooleanFormula: instance (GHC.Internal.Classes.Eq (Language.Haskell.Syntax.Extension.LIdP p), GHC.Internal.Classes.Eq (Language.Haskell.Syntax.BooleanFormula.LBooleanFormula p)) => GHC.Internal.Classes.Eq (Language.Haskell.Syntax.BooleanFormula.BooleanFormula p)
+ Language.Haskell.Syntax.BooleanFormula: mkAnd :: (UnXRec p, Eq (LIdP p), Eq (LBooleanFormula p)) => [LBooleanFormula p] -> BooleanFormula p
+ Language.Haskell.Syntax.BooleanFormula: mkBool :: Bool -> BooleanFormula p
+ Language.Haskell.Syntax.BooleanFormula: mkFalse :: BooleanFormula p
+ Language.Haskell.Syntax.BooleanFormula: mkOr :: (UnXRec p, Eq (LIdP p), Eq (LBooleanFormula p)) => [LBooleanFormula p] -> BooleanFormula p
+ Language.Haskell.Syntax.BooleanFormula: mkTrue :: BooleanFormula p
+ Language.Haskell.Syntax.BooleanFormula: mkVar :: LIdP p -> BooleanFormula p
+ Language.Haskell.Syntax.BooleanFormula: type LBooleanFormula p = XRec p BooleanFormula p
+ Language.Haskell.Syntax.Decls: [con_inner_bndrs] :: ConDecl pass -> [HsForAllTelescope pass]
+ Language.Haskell.Syntax.Decls: [con_outer_bndrs] :: ConDecl pass -> XRec pass (HsOuterSigTyVarBndrs pass)
+ Language.Haskell.Syntax.Decls: [rd_bndrs] :: RuleDecl pass -> RuleBndrs pass
+ Language.Haskell.Syntax.Decls: instance GHC.Internal.Classes.Eq Language.Haskell.Syntax.Decls.SpliceDecoration
+ Language.Haskell.Syntax.Decls: instance GHC.Internal.Classes.Eq a => GHC.Internal.Classes.Eq (Language.Haskell.Syntax.Decls.DataDefnCons a)
+ Language.Haskell.Syntax.Expr: HsHole :: XHole p -> HsExpr p
+ Language.Haskell.Syntax.Expr: HsTypedSpliceExpr :: XTypedSpliceExpr id -> LHsExpr id -> HsTypedSplice id
+ Language.Haskell.Syntax.Expr: XTypedSplice :: XXTypedSplice id -> HsTypedSplice id
+ Language.Haskell.Syntax.Expr: data HsTypedSplice id
+ Language.Haskell.Syntax.Expr: instance GHC.Internal.Classes.Eq Language.Haskell.Syntax.Expr.HsDoFlavour
+ Language.Haskell.Syntax.Expr: instance GHC.Internal.Classes.Eq Language.Haskell.Syntax.Expr.HsLamVariant
+ Language.Haskell.Syntax.Extension: instance GHC.Internal.Classes.Eq Language.Haskell.Syntax.Extension.DataConCantHappen
+ Language.Haskell.Syntax.Extension: instance GHC.Internal.Classes.Eq Language.Haskell.Syntax.Extension.NoExtField
+ Language.Haskell.Syntax.Extension: instance GHC.Internal.Classes.Ord Language.Haskell.Syntax.Extension.DataConCantHappen
+ Language.Haskell.Syntax.Extension: instance GHC.Internal.Classes.Ord Language.Haskell.Syntax.Extension.NoExtField
+ Language.Haskell.Syntax.Extension: type LIdOccP p = XRec p IdOccP p
+ Language.Haskell.Syntax.ImpExp: IEData :: XIEData p -> LIdP p -> IEWrappedName p
+ Language.Haskell.Syntax.ImpExp: ImportDeclQuote :: ImportDeclLevel
+ Language.Haskell.Syntax.ImpExp: ImportDeclSplice :: ImportDeclLevel
+ Language.Haskell.Syntax.ImpExp: LevelStylePost :: ImportDeclLevel -> ImportDeclLevelStyle
+ Language.Haskell.Syntax.ImpExp: LevelStylePre :: ImportDeclLevel -> ImportDeclLevelStyle
+ Language.Haskell.Syntax.ImpExp: NotLevelled :: ImportDeclLevelStyle
+ Language.Haskell.Syntax.ImpExp: [ideclLevelSpec] :: ImportDecl pass -> ImportDeclLevelStyle
+ Language.Haskell.Syntax.ImpExp: data ImportDeclLevel
+ Language.Haskell.Syntax.ImpExp: data ImportDeclLevelStyle
+ Language.Haskell.Syntax.ImpExp: instance GHC.Internal.Classes.Eq Language.Haskell.Syntax.ImpExp.IEWildcard
+ Language.Haskell.Syntax.ImpExp: instance GHC.Internal.Classes.Eq Language.Haskell.Syntax.ImpExp.ImportDeclLevel
+ Language.Haskell.Syntax.ImpExp: instance GHC.Internal.Classes.Eq Language.Haskell.Syntax.ImpExp.ImportDeclLevelStyle
+ Language.Haskell.Syntax.ImpExp: instance GHC.Internal.Classes.Eq Language.Haskell.Syntax.ImpExp.ImportDeclQualifiedStyle
+ Language.Haskell.Syntax.ImpExp: instance GHC.Internal.Classes.Eq Language.Haskell.Syntax.ImpExp.ImportListInterpretation
+ Language.Haskell.Syntax.ImpExp: instance GHC.Internal.Data.Data.Data Language.Haskell.Syntax.ImpExp.ImportDeclLevel
+ Language.Haskell.Syntax.ImpExp: instance GHC.Internal.Data.Data.Data Language.Haskell.Syntax.ImpExp.ImportDeclLevelStyle
+ Language.Haskell.Syntax.ImpExp.IsBoot: IsBoot :: IsBootInterface
+ Language.Haskell.Syntax.ImpExp.IsBoot: NotBoot :: IsBootInterface
+ Language.Haskell.Syntax.ImpExp.IsBoot: data IsBootInterface
+ Language.Haskell.Syntax.ImpExp.IsBoot: instance Control.DeepSeq.NFData Language.Haskell.Syntax.ImpExp.IsBoot.IsBootInterface
+ Language.Haskell.Syntax.ImpExp.IsBoot: instance GHC.Internal.Classes.Eq Language.Haskell.Syntax.ImpExp.IsBoot.IsBootInterface
+ Language.Haskell.Syntax.ImpExp.IsBoot: instance GHC.Internal.Classes.Ord Language.Haskell.Syntax.ImpExp.IsBoot.IsBootInterface
+ Language.Haskell.Syntax.ImpExp.IsBoot: instance GHC.Internal.Data.Data.Data Language.Haskell.Syntax.ImpExp.IsBoot.IsBootInterface
+ Language.Haskell.Syntax.ImpExp.IsBoot: instance GHC.Internal.Show.Show Language.Haskell.Syntax.ImpExp.IsBoot.IsBootInterface
+ Language.Haskell.Syntax.Lit: instance GHC.Internal.Classes.Eq (Language.Haskell.Syntax.Extension.XXLit x) => GHC.Internal.Classes.Eq (Language.Haskell.Syntax.Lit.HsLit x)
+ Language.Haskell.Syntax.Lit: instance GHC.Internal.Classes.Eq Language.Haskell.Syntax.Lit.OverLitVal
+ Language.Haskell.Syntax.Lit: instance GHC.Internal.Classes.Ord Language.Haskell.Syntax.Lit.OverLitVal
+ Language.Haskell.Syntax.Module.Name: instance GHC.Internal.Classes.Eq Language.Haskell.Syntax.Module.Name.ModuleName
+ Language.Haskell.Syntax.Module.Name: instance GHC.Internal.Classes.Ord Language.Haskell.Syntax.Module.Name.ModuleName
+ Language.Haskell.Syntax.Module.Name: instance GHC.Internal.Data.Data.Data Language.Haskell.Syntax.Module.Name.ModuleName
+ Language.Haskell.Syntax.Pat: dropHsConPatTyArgs :: UnXRec p => [LPat p] -> [LPat p]
+ Language.Haskell.Syntax.Pat: instance GHC.Internal.Classes.Eq Language.Haskell.Syntax.Pat.RecFieldsDotDot
+ Language.Haskell.Syntax.Pat: instance GHC.Internal.Classes.Ord Language.Haskell.Syntax.Pat.RecFieldsDotDot
+ Language.Haskell.Syntax.Pat: isInvisArgLPat :: UnXRec p => LPat p -> Bool
+ Language.Haskell.Syntax.Pat: isVisArgLPat :: UnXRec p => LPat p -> Bool
+ Language.Haskell.Syntax.Pat: takeHsConPatTyArgs :: UnXRec p => [LPat p] -> [HsTyPat (NoGhcTc p)]
+ Language.Haskell.Syntax.Specificity: instance GHC.Internal.Classes.Eq Language.Haskell.Syntax.Specificity.ForAllTyFlag
+ Language.Haskell.Syntax.Specificity: instance GHC.Internal.Classes.Eq Language.Haskell.Syntax.Specificity.Specificity
+ Language.Haskell.Syntax.Specificity: instance GHC.Internal.Classes.Ord Language.Haskell.Syntax.Specificity.ForAllTyFlag
+ Language.Haskell.Syntax.Specificity: instance GHC.Internal.Classes.Ord Language.Haskell.Syntax.Specificity.Specificity
+ Language.Haskell.Syntax.Type: CDF :: XConDeclField pass -> SrcUnpackedness -> SrcStrictness -> HsMultAnn pass -> LHsType pass -> Maybe (LHsDoc pass) -> HsConDeclField pass
+ Language.Haskell.Syntax.Type: HsConDeclRecField :: XConDeclRecField pass -> [LFieldOcc pass] -> HsConDeclField pass -> HsConDeclRecField pass
+ Language.Haskell.Syntax.Type: HsLinearAnn :: XLinearAnn mult pass -> HsMultAnnOf mult pass
+ Language.Haskell.Syntax.Type: HsUnannotated :: XUnannotated mult pass -> HsMultAnnOf mult pass
+ Language.Haskell.Syntax.Type: XConDeclRecField :: XXConDeclRecField pass -> HsConDeclRecField pass
+ Language.Haskell.Syntax.Type: XMultAnnOf :: XXMultAnnOf mult pass -> HsMultAnnOf mult pass
+ Language.Haskell.Syntax.Type: [cdf_bang] :: HsConDeclField pass -> SrcStrictness
+ Language.Haskell.Syntax.Type: [cdf_doc] :: HsConDeclField pass -> Maybe (LHsDoc pass)
+ Language.Haskell.Syntax.Type: [cdf_ext] :: HsConDeclField pass -> XConDeclField pass
+ Language.Haskell.Syntax.Type: [cdf_multiplicity] :: HsConDeclField pass -> HsMultAnn pass
+ Language.Haskell.Syntax.Type: [cdf_type] :: HsConDeclField pass -> LHsType pass
+ Language.Haskell.Syntax.Type: [cdf_unpack] :: HsConDeclField pass -> SrcUnpackedness
+ Language.Haskell.Syntax.Type: [cdrf_ext] :: HsConDeclRecField pass -> XConDeclRecField pass
+ Language.Haskell.Syntax.Type: [cdrf_names] :: HsConDeclRecField pass -> [LFieldOcc pass]
+ Language.Haskell.Syntax.Type: [cdrf_spec] :: HsConDeclRecField pass -> HsConDeclField pass
+ Language.Haskell.Syntax.Type: data HsConDeclField pass
+ Language.Haskell.Syntax.Type: data HsConDeclRecField pass
+ Language.Haskell.Syntax.Type: data HsMultAnnOf mult pass
+ Language.Haskell.Syntax.Type: instance (GHC.Internal.Classes.Eq (Language.Haskell.Syntax.Extension.LIdP pass), GHC.Internal.Classes.Eq (Language.Haskell.Syntax.Extension.XCFieldOcc pass), GHC.Internal.Classes.Eq (Language.Haskell.Syntax.Extension.XXFieldOcc pass)) => GHC.Internal.Classes.Eq (Language.Haskell.Syntax.Type.FieldOcc pass)
+ Language.Haskell.Syntax.Type: instance (GHC.Internal.Data.Data.Data rec, GHC.Internal.Data.Data.Data arg) => GHC.Internal.Data.Data.Data (Language.Haskell.Syntax.Type.HsConDetails arg rec)
+ Language.Haskell.Syntax.Type: instance Control.DeepSeq.NFData Language.Haskell.Syntax.Type.PromotionFlag
+ Language.Haskell.Syntax.Type: instance GHC.Internal.Classes.Eq Language.Haskell.Syntax.Type.HsIPName
+ Language.Haskell.Syntax.Type: instance GHC.Internal.Classes.Eq Language.Haskell.Syntax.Type.PromotionFlag
+ Language.Haskell.Syntax.Type: instance GHC.Internal.Classes.Ord Language.Haskell.Syntax.Type.PromotionFlag
+ Language.Haskell.Syntax.Type: type HsMultAnn pass = HsMultAnnOf LHsType NoGhcTc pass pass
+ Language.Haskell.Syntax.Type: type LHsConDeclRecField pass = XRec pass HsConDeclRecField pass
- GHC: BreakpointId :: !Module -> !Int -> BreakpointId
+ GHC: BreakpointId :: Module -> BreakTickIndex -> BreakpointId
- GHC: CoreModule :: !Module -> !TypeEnv -> CoreProgram -> SafeHaskellMode -> CoreModule
+ GHC: CoreModule :: Module -> TypeEnv -> CoreProgram -> SafeHaskellMode -> CoreModule
- GHC: DynFlags :: GhcMode -> GhcLink -> !Backend -> {-# UNPACK #-} !GhcNameVersion -> {-# UNPACK #-} !FileSettings -> Platform -> {-# UNPACK #-} !ToolSettings -> {-# UNPACK #-} !PlatformMisc -> [(String, String)] -> TempDir -> Int -> Int -> Int -> Int -> Int -> Maybe String -> [Int] -> Maybe ParMakeCount -> Bool -> Maybe Int -> Maybe Int -> Maybe Int -> Maybe Int -> Maybe Int -> Int -> Int -> Int -> !Int -> Int -> Maybe Int -> Maybe Int -> Int -> Maybe Word -> Maybe Int -> Maybe Int -> Maybe Int -> Maybe Int -> Bool -> Maybe Int -> Int -> [FilePath] -> ModuleName -> Maybe String -> IntWithInf -> IntWithInf -> Int -> Int -> Int -> UnitId -> Maybe UnitId -> [(ModuleName, Module)] -> Maybe FilePath -> Maybe String -> Set ModuleName -> [ReexportedModule] -> Ways -> Maybe (String, Int) -> Maybe String -> Maybe String -> Maybe String -> Maybe String -> Maybe String -> Maybe String -> String -> String -> String -> String -> String -> String -> Maybe String -> Maybe String -> Maybe String -> Maybe String -> DynLibLoader -> !Bool -> FilePath -> Maybe FilePath -> [Option] -> IncludeSpecs -> [String] -> [String] -> [String] -> Maybe String -> RtsOptsEnabled -> Bool -> String -> [ModuleName] -> [(ModuleName, String)] -> [String] -> [ExternalPluginSpec] -> FilePath -> Bool -> Bool -> [ModuleName] -> [String] -> [PackageDBFlag] -> [IgnorePackageFlag] -> [PackageFlag] -> [PackageFlag] -> [TrustFlag] -> Maybe FilePath -> EnumSet DumpFlag -> EnumSet GeneralFlag -> EnumSet WarningFlag -> EnumSet WarningFlag -> WarningCategorySet -> WarningCategorySet -> Maybe Language -> SafeHaskellMode -> Bool -> Bool -> SrcSpan -> SrcSpan -> SrcSpan -> SrcSpan -> SrcSpan -> SrcSpan -> SrcSpan -> SrcSpan -> SrcSpan -> [OnOff Extension] -> EnumSet Extension -> !UnfoldingOpts -> Int -> Int -> Int -> FlushOut -> Maybe FilePath -> Maybe String -> [String] -> Int -> Int -> Bool -> OverridingBool -> Bool -> OverridingBool -> Bool -> Scheme -> ProfAuto -> [CallerCcFilter] -> Maybe String -> Maybe SseVersion -> Maybe BmiVersion -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Int -> Int -> Int -> Bool -> Maybe Int -> Word64 -> Int -> Weights -> DynFlags
+ GHC: DynFlags :: GhcMode -> GhcLink -> Backend -> GhcNameVersion -> FileSettings -> UnitSettings -> Platform -> ToolSettings -> PlatformMisc -> [(String, String)] -> TempDir -> Int -> Int -> Int -> Int -> Int -> Maybe String -> [Int] -> Maybe ParMakeCount -> Bool -> Maybe Int -> Maybe Int -> Maybe Int -> Maybe Int -> Maybe Int -> Int -> Int -> Int -> Int -> Int -> Maybe Int -> Maybe Int -> Int -> Maybe Word -> Maybe Int -> Maybe Int -> Maybe Int -> Maybe Int -> Bool -> Maybe Int -> Int -> [FilePath] -> ModuleName -> Maybe String -> IntWithInf -> IntWithInf -> Int -> Int -> Int -> UnitId -> Maybe UnitId -> [(ModuleName, Module)] -> Maybe FilePath -> Maybe String -> Set ModuleName -> [ReexportedModule] -> Ways -> Maybe (String, Int) -> Maybe String -> Maybe String -> Maybe String -> Maybe String -> Maybe String -> Maybe String -> String -> String -> String -> String -> String -> String -> Maybe String -> Maybe String -> Maybe String -> Maybe String -> DynLibLoader -> Bool -> FilePath -> Maybe FilePath -> [Option] -> IncludeSpecs -> [String] -> [String] -> [String] -> Maybe String -> RtsOptsEnabled -> Bool -> String -> [ModuleName] -> [(ModuleName, String)] -> [String] -> [ExternalPluginSpec] -> FilePath -> Bool -> Bool -> [ModuleName] -> [String] -> [PackageDBFlag] -> [IgnorePackageFlag] -> [PackageFlag] -> [PackageFlag] -> [TrustFlag] -> Maybe FilePath -> EnumSet DumpFlag -> EnumSet GeneralFlag -> EnumSet WarningFlag -> EnumSet WarningFlag -> WarningCategorySet -> WarningCategorySet -> Maybe Language -> SafeHaskellMode -> Bool -> Bool -> SrcSpan -> SrcSpan -> SrcSpan -> SrcSpan -> SrcSpan -> SrcSpan -> SrcSpan -> SrcSpan -> SrcSpan -> [OnOff Extension] -> EnumSet Extension -> UnfoldingOpts -> Int -> Int -> Int -> String -> Int -> Maybe String -> Maybe String -> Maybe String -> FlushOut -> Maybe FilePath -> Maybe String -> [String] -> Int -> Int -> Bool -> OverridingBool -> Bool -> OverridingBool -> Bool -> Scheme -> ProfAuto -> [CallerCcFilter] -> Maybe String -> Maybe SseVersion -> Maybe BmiVersion -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Int -> Int -> Int -> Bool -> Maybe Int -> Word64 -> Int -> Weights -> DynFlags
- GHC: IIModule :: ModuleName -> InteractiveImport
+ GHC: IIModule :: Module -> InteractiveImport
- GHC: InternalBreakpointId :: !Module -> !Int -> !Module -> !Int -> InternalBreakpointId
+ GHC: InternalBreakpointId :: Module -> BreakInfoIndex -> InternalBreakpointId
- GHC: LoadUpTo :: HomeUnitModule -> LoadHowMuch
+ GHC: LoadUpTo :: [HomeUnitModule] -> LoadHowMuch
- GHC: ModBreaks :: ForeignRef BreakArray -> !Array BreakIndex SrcSpan -> !Array BreakIndex [OccName] -> !Array BreakIndex [String] -> !Array BreakIndex (RemotePtr CostCentre) -> IntMap CgBreakInfo -> RemotePtr ModuleName -> ModBreaks
+ GHC: ModBreaks :: Array BreakTickIndex SrcSpan -> Array BreakTickIndex [OccName] -> Array BreakTickIndex [String] -> Array BreakTickIndex (String, String) -> Module -> ModBreaks
- GHC: ModSummary :: Module -> HscSource -> ModLocation -> Fingerprint -> Maybe UTCTime -> !Maybe UTCTime -> Maybe UTCTime -> Maybe UTCTime -> [(PkgQual, Located ModuleName)] -> [(PkgQual, Located ModuleName)] -> !Bool -> Maybe HsParsedModule -> FilePath -> DynFlags -> Maybe StringBuffer -> ModSummary
+ GHC: ModSummary :: Module -> HscSource -> ModLocation -> Fingerprint -> Maybe UTCTime -> Maybe UTCTime -> Maybe UTCTime -> Maybe UTCTime -> [Located ModuleName] -> [(ImportLevel, PkgQual, Located ModuleName)] -> Maybe HsParsedModule -> FilePath -> DynFlags -> Maybe StringBuffer -> ModSummary
- GHC: OtherPkg :: !UnitId -> PkgQual
+ GHC: OtherPkg :: UnitId -> PkgQual
- GHC: RealSrcLoc :: !RealSrcLoc -> !Maybe BufPos -> SrcLoc
+ GHC: RealSrcLoc :: RealSrcLoc -> Maybe BufPos -> SrcLoc
- GHC: RealSrcSpan :: !RealSrcSpan -> !Maybe BufSpan -> SrcSpan
+ GHC: RealSrcSpan :: RealSrcSpan -> Maybe BufSpan -> SrcSpan
- GHC: Target :: !TargetId -> !Bool -> !UnitId -> !Maybe (InputFileBuffer, UTCTime) -> Target
+ GHC: Target :: TargetId -> Bool -> UnitId -> Maybe (InputFileBuffer, UTCTime) -> Target
- GHC: TargetFile :: !FilePath -> !Maybe Phase -> TargetId
+ GHC: TargetFile :: FilePath -> Maybe Phase -> TargetId
- GHC: TargetModule :: !ModuleName -> TargetId
+ GHC: TargetModule :: ModuleName -> TargetId
- GHC: ThisPkg :: !UnitId -> PkgQual
+ GHC: ThisPkg :: UnitId -> PkgQual
- GHC: UnhelpfulLoc :: !FastString -> SrcLoc
+ GHC: UnhelpfulLoc :: FastString -> SrcLoc
- GHC: UnhelpfulSpan :: !UnhelpfulSpanReason -> SrcSpan
+ GHC: UnhelpfulSpan :: UnhelpfulSpanReason -> SrcSpan
- GHC: [backend] :: DynFlags -> !Backend
+ GHC: [backend] :: DynFlags -> Backend
- GHC: [bi_tick_index] :: BreakpointId -> !Int
+ GHC: [bi_tick_index] :: BreakpointId -> BreakTickIndex
- GHC: [bi_tick_mod] :: BreakpointId -> !Module
+ GHC: [bi_tick_mod] :: BreakpointId -> Module
- GHC: [cm_module] :: CoreModule -> !Module
+ GHC: [cm_module] :: CoreModule -> Module
- GHC: [cm_types] :: CoreModule -> !TypeEnv
+ GHC: [cm_types] :: CoreModule -> TypeEnv
- GHC: [dmdUnboxWidth] :: DynFlags -> !Int
+ GHC: [dmdUnboxWidth] :: DynFlags -> Int
- GHC: [dynamicNow] :: DynFlags -> !Bool
+ GHC: [dynamicNow] :: DynFlags -> Bool
- GHC: [fileSettings] :: DynFlags -> {-# UNPACK #-} !FileSettings
+ GHC: [fileSettings] :: DynFlags -> FileSettings
- GHC: [ghcNameVersion] :: DynFlags -> {-# UNPACK #-} !GhcNameVersion
+ GHC: [ghcNameVersion] :: DynFlags -> GhcNameVersion
- GHC: [ibi_info_index] :: InternalBreakpointId -> !Int
+ GHC: [ibi_info_index] :: InternalBreakpointId -> BreakInfoIndex
- GHC: [ibi_info_mod] :: InternalBreakpointId -> !Module
+ GHC: [ibi_info_mod] :: InternalBreakpointId -> Module
- GHC: [modBreaks_ccs] :: ModBreaks -> !Array BreakIndex (RemotePtr CostCentre)
+ GHC: [modBreaks_ccs] :: ModBreaks -> Array BreakTickIndex (String, String)
- GHC: [modBreaks_decls] :: ModBreaks -> !Array BreakIndex [String]
+ GHC: [modBreaks_decls] :: ModBreaks -> Array BreakTickIndex [String]
- GHC: [modBreaks_locs] :: ModBreaks -> !Array BreakIndex SrcSpan
+ GHC: [modBreaks_locs] :: ModBreaks -> Array BreakTickIndex SrcSpan
- GHC: [modBreaks_module] :: ModBreaks -> RemotePtr ModuleName
+ GHC: [modBreaks_module] :: ModBreaks -> Module
- GHC: [modBreaks_vars] :: ModBreaks -> !Array BreakIndex [OccName]
+ GHC: [modBreaks_vars] :: ModBreaks -> Array BreakTickIndex [OccName]
- GHC: [ms_dyn_obj_date] :: ModSummary -> !Maybe UTCTime
+ GHC: [ms_dyn_obj_date] :: ModSummary -> Maybe UTCTime
- GHC: [ms_srcimps] :: ModSummary -> [(PkgQual, Located ModuleName)]
+ GHC: [ms_srcimps] :: ModSummary -> [Located ModuleName]
- GHC: [ms_textual_imps] :: ModSummary -> [(PkgQual, Located ModuleName)]
+ GHC: [ms_textual_imps] :: ModSummary -> [(ImportLevel, PkgQual, Located ModuleName)]
- GHC: [platformMisc] :: DynFlags -> {-# UNPACK #-} !PlatformMisc
+ GHC: [platformMisc] :: DynFlags -> PlatformMisc
- GHC: [targetAllowObjCode] :: Target -> !Bool
+ GHC: [targetAllowObjCode] :: Target -> Bool
- GHC: [targetContents] :: Target -> !Maybe (InputFileBuffer, UTCTime)
+ GHC: [targetContents] :: Target -> Maybe (InputFileBuffer, UTCTime)
- GHC: [targetId] :: Target -> !TargetId
+ GHC: [targetId] :: Target -> TargetId
- GHC: [targetUnitId] :: Target -> !UnitId
+ GHC: [targetUnitId] :: Target -> UnitId
- GHC: [toolSettings] :: DynFlags -> {-# UNPACK #-} !ToolSettings
+ GHC: [toolSettings] :: DynFlags -> ToolSettings
- GHC: [unfoldingOpts] :: DynFlags -> !UnfoldingOpts
+ GHC: [unfoldingOpts] :: DynFlags -> UnfoldingOpts
- GHC: back :: GhcMonad m => Int -> m ([Name], Int, SrcSpan, String)
+ GHC: back :: GhcMonad m => Int -> m ([Name], Int, SrcSpan)
- GHC: depanalE :: GhcMonad m => [ModuleName] -> Bool -> m (DriverMessages, ModuleGraph)
+ GHC: depanalE :: GhcMonad m => (GhcMessage -> AnyGhcDiagnostic) -> Maybe Messager -> [ModuleName] -> Bool -> m (DriverMessages, ModuleGraph)
- GHC: forward :: GhcMonad m => Int -> m ([Name], Int, SrcSpan, String)
+ GHC: forward :: GhcMonad m => Int -> m ([Name], Int, SrcSpan)
- GHC: getHistoryModule :: History -> Module
+ GHC: getHistoryModule :: HomeUnitGraph -> History -> IO Module
- GHC: getModSummary :: GhcMonad m => ModuleName -> m ModSummary
+ GHC: getModSummary :: GhcMonad m => Module -> m ModSummary
- GHC: mgLookupModule :: ModuleGraph -> Module -> Maybe ModSummary
+ GHC: mgLookupModule :: ModuleGraph -> Module -> Maybe ModuleNodeInfo
- GHC: modInfoModBreaks :: ModuleInfo -> ModBreaks
+ GHC: modInfoModBreaks :: ModuleInfo -> Maybe InternalModBreaks
- GHC: moduleIsBootOrNotObjectLinkable :: GhcMonad m => ModSummary -> m Bool
+ GHC: moduleIsBootOrNotObjectLinkable :: GhcMonad m => Module -> m Bool
- GHC: pattern ModIface :: Module -> Maybe Module -> HscSource -> Dependencies -> [Usage] -> [IfaceExport] -> Bool -> [(OccName, Fixity)] -> IfaceWarnings -> [IfaceAnnotation] -> [IfaceDeclExts phase] -> Maybe [IfaceBindingX IfaceMaybeRhs IfaceTopBndrInfo] -> IfaceForeign -> [IfaceDefault] -> Maybe IfaceTopEnv -> [IfaceClsInst] -> [IfaceFamInst] -> [IfaceRule] -> AnyHpcUsage -> IfaceTrustInfo -> Bool -> [IfaceCompleteMatch] -> Maybe Docs -> IfaceBackendExts phase -> ExtensibleFields -> Fingerprint -> IfaceBinHandle phase -> ModIface_ phase
+ GHC: pattern ModIface :: IfaceModInfo -> Module -> Maybe Module -> HscSource -> Fingerprint -> Dependencies -> IfacePublic_ phase -> [IfaceExport] -> [(OccName, Fixity)] -> IfaceWarnings -> [IfaceAnnotation] -> [IfaceDeclExts phase] -> Maybe IfaceSimplifiedCore -> [IfaceDefault] -> IfaceTopEnv -> [IfaceClsInst] -> [IfaceFamInst] -> [IfaceRule] -> IfaceTrustInfo -> Bool -> [IfaceCompleteMatch] -> Maybe Docs -> IfaceAbiHashesExts phase -> ExtensibleFields -> IfaceBinHandle phase -> Maybe IfaceSelfRecomp -> (OccName -> Maybe Fixity) -> (OccName -> Maybe (OccName, Fingerprint)) -> (OccName -> Maybe (WarningTxt GhcRn)) -> (Name -> Maybe (WarningTxt GhcRn)) -> ModIface_ phase
- GHC: resumeExec :: GhcMonad m => (SrcSpan -> Bool) -> SingleStep -> Maybe Int -> m ExecResult
+ GHC: resumeExec :: GhcMonad m => SingleStep -> Maybe Int -> m ExecResult
- GHC: setupBreakpoint :: GhcMonad m => HscEnv -> BreakpointId -> Int -> m ()
+ GHC: setupBreakpoint :: GhcMonad m => Interp -> InternalBreakpointId -> Int -> m ()
- GHC: showModule :: GhcMonad m => ModSummary -> m String
+ GHC: showModule :: GhcMonad m => ModuleNodeInfo -> m String
- GHC: topSortModuleGraph :: Bool -> ModuleGraph -> Maybe HomeUnitModule -> [SCC ModuleGraphNode]
+ GHC: topSortModuleGraph :: Bool -> ModuleGraph -> Maybe [HomeUnitModule] -> [SCC ModuleGraphNode]
- GHC.Builtin.Types: isBuiltInOcc_maybe :: OccName -> Maybe Name
+ GHC.Builtin.Types: isBuiltInOcc_maybe :: Bool -> OccName -> Maybe Name
- GHC.ByteCode.Asm: assembleBCOs :: Interp -> Profile -> FlatBag (ProtoBCO Name) -> [TyCon] -> AddrEnv -> Maybe ModBreaks -> [SptEntry] -> IO CompiledByteCode
+ GHC.ByteCode.Asm: assembleBCOs :: Profile -> FlatBag (ProtoBCO Name) -> [TyCon] -> [(Name, ByteString)] -> Maybe InternalModBreaks -> [SptEntry] -> IO CompiledByteCode
- GHC.ByteCode.InfoTable: mkITbls :: Interp -> Profile -> [TyCon] -> IO ItblEnv
+ GHC.ByteCode.InfoTable: mkITbls :: Profile -> [TyCon] -> [(Name, ConInfoTable)]
- GHC.ByteCode.Instr: ALLOC_AP :: !HalfWord -> BCInstr
+ GHC.ByteCode.Instr: ALLOC_AP :: HalfWord -> BCInstr
- GHC.ByteCode.Instr: ALLOC_AP_NOUPD :: !HalfWord -> BCInstr
+ GHC.ByteCode.Instr: ALLOC_AP_NOUPD :: HalfWord -> BCInstr
- GHC.ByteCode.Instr: ALLOC_PAP :: !HalfWord -> !HalfWord -> BCInstr
+ GHC.ByteCode.Instr: ALLOC_PAP :: HalfWord -> HalfWord -> BCInstr
- GHC.ByteCode.Instr: BCO_NAME :: !ByteString -> BCInstr
+ GHC.ByteCode.Instr: BCO_NAME :: ByteString -> BCInstr
- GHC.ByteCode.Instr: BRK_FUN :: ForeignRef BreakArray -> RemotePtr ModuleName -> !Word16 -> RemotePtr ModuleName -> !Word16 -> RemotePtr CostCentre -> BCInstr
+ GHC.ByteCode.Instr: BRK_FUN :: InternalBreakpointId -> BCInstr
- GHC.ByteCode.Instr: CCALL :: !WordOff -> RemotePtr C_ffi_cif -> !Word16 -> BCInstr
+ GHC.ByteCode.Instr: CCALL :: WordOff -> FFIInfo -> Word16 -> BCInstr
- GHC.ByteCode.Instr: MKAP :: !WordOff -> !HalfWord -> BCInstr
+ GHC.ByteCode.Instr: MKAP :: WordOff -> HalfWord -> BCInstr
- GHC.ByteCode.Instr: MKPAP :: !WordOff -> !HalfWord -> BCInstr
+ GHC.ByteCode.Instr: MKPAP :: WordOff -> HalfWord -> BCInstr
- GHC.ByteCode.Instr: OP_ADD :: !Width -> BCInstr
+ GHC.ByteCode.Instr: OP_ADD :: Width -> BCInstr
- GHC.ByteCode.Instr: OP_AND :: !Width -> BCInstr
+ GHC.ByteCode.Instr: OP_AND :: Width -> BCInstr
- GHC.ByteCode.Instr: OP_ASR :: !Width -> BCInstr
+ GHC.ByteCode.Instr: OP_ASR :: Width -> BCInstr
- GHC.ByteCode.Instr: OP_EQ :: !Width -> BCInstr
+ GHC.ByteCode.Instr: OP_EQ :: Width -> BCInstr
- GHC.ByteCode.Instr: OP_INDEX_ADDR :: !Width -> BCInstr
+ GHC.ByteCode.Instr: OP_INDEX_ADDR :: Width -> BCInstr
- GHC.ByteCode.Instr: OP_LSR :: !Width -> BCInstr
+ GHC.ByteCode.Instr: OP_LSR :: Width -> BCInstr
- GHC.ByteCode.Instr: OP_MUL :: !Width -> BCInstr
+ GHC.ByteCode.Instr: OP_MUL :: Width -> BCInstr
- GHC.ByteCode.Instr: OP_NEG :: !Width -> BCInstr
+ GHC.ByteCode.Instr: OP_NEG :: Width -> BCInstr
- GHC.ByteCode.Instr: OP_NEQ :: !Width -> BCInstr
+ GHC.ByteCode.Instr: OP_NEQ :: Width -> BCInstr
- GHC.ByteCode.Instr: OP_NOT :: !Width -> BCInstr
+ GHC.ByteCode.Instr: OP_NOT :: Width -> BCInstr
- GHC.ByteCode.Instr: OP_OR :: !Width -> BCInstr
+ GHC.ByteCode.Instr: OP_OR :: Width -> BCInstr
- GHC.ByteCode.Instr: OP_SHL :: !Width -> BCInstr
+ GHC.ByteCode.Instr: OP_SHL :: Width -> BCInstr
- GHC.ByteCode.Instr: OP_SUB :: !Width -> BCInstr
+ GHC.ByteCode.Instr: OP_SUB :: Width -> BCInstr
- GHC.ByteCode.Instr: OP_S_GE :: !Width -> BCInstr
+ GHC.ByteCode.Instr: OP_S_GE :: Width -> BCInstr
- GHC.ByteCode.Instr: OP_S_GT :: !Width -> BCInstr
+ GHC.ByteCode.Instr: OP_S_GT :: Width -> BCInstr
- GHC.ByteCode.Instr: OP_S_LE :: !Width -> BCInstr
+ GHC.ByteCode.Instr: OP_S_LE :: Width -> BCInstr
- GHC.ByteCode.Instr: OP_S_LT :: !Width -> BCInstr
+ GHC.ByteCode.Instr: OP_S_LT :: Width -> BCInstr
- GHC.ByteCode.Instr: OP_U_GE :: !Width -> BCInstr
+ GHC.ByteCode.Instr: OP_U_GE :: Width -> BCInstr
- GHC.ByteCode.Instr: OP_U_GT :: !Width -> BCInstr
+ GHC.ByteCode.Instr: OP_U_GT :: Width -> BCInstr
- GHC.ByteCode.Instr: OP_U_LE :: !Width -> BCInstr
+ GHC.ByteCode.Instr: OP_U_LE :: Width -> BCInstr
- GHC.ByteCode.Instr: OP_U_LT :: !Width -> BCInstr
+ GHC.ByteCode.Instr: OP_U_LT :: Width -> BCInstr
- GHC.ByteCode.Instr: OP_XOR :: !Width -> BCInstr
+ GHC.ByteCode.Instr: OP_XOR :: Width -> BCInstr
- GHC.ByteCode.Instr: PACK :: DataCon -> !WordOff -> BCInstr
+ GHC.ByteCode.Instr: PACK :: DataCon -> WordOff -> BCInstr
- GHC.ByteCode.Instr: PUSH16 :: !ByteOff -> BCInstr
+ GHC.ByteCode.Instr: PUSH16 :: ByteOff -> BCInstr
- GHC.ByteCode.Instr: PUSH16_W :: !ByteOff -> BCInstr
+ GHC.ByteCode.Instr: PUSH16_W :: ByteOff -> BCInstr
- GHC.ByteCode.Instr: PUSH32 :: !ByteOff -> BCInstr
+ GHC.ByteCode.Instr: PUSH32 :: ByteOff -> BCInstr
- GHC.ByteCode.Instr: PUSH32_W :: !ByteOff -> BCInstr
+ GHC.ByteCode.Instr: PUSH32_W :: ByteOff -> BCInstr
- GHC.ByteCode.Instr: PUSH8 :: !ByteOff -> BCInstr
+ GHC.ByteCode.Instr: PUSH8 :: ByteOff -> BCInstr
- GHC.ByteCode.Instr: PUSH8_W :: !ByteOff -> BCInstr
+ GHC.ByteCode.Instr: PUSH8_W :: ByteOff -> BCInstr
- GHC.ByteCode.Instr: PUSH_ALTS_TUPLE :: ProtoBCO Name -> !NativeCallInfo -> ProtoBCO Name -> BCInstr
+ GHC.ByteCode.Instr: PUSH_ALTS_TUPLE :: ProtoBCO Name -> NativeCallInfo -> ProtoBCO Name -> BCInstr
- GHC.ByteCode.Instr: PUSH_L :: !WordOff -> BCInstr
+ GHC.ByteCode.Instr: PUSH_L :: WordOff -> BCInstr
- GHC.ByteCode.Instr: PUSH_LL :: !WordOff -> !WordOff -> BCInstr
+ GHC.ByteCode.Instr: PUSH_LL :: WordOff -> WordOff -> BCInstr
- GHC.ByteCode.Instr: PUSH_LLL :: !WordOff -> !WordOff -> !WordOff -> BCInstr
+ GHC.ByteCode.Instr: PUSH_LLL :: WordOff -> WordOff -> WordOff -> BCInstr
- GHC.ByteCode.Instr: PUSH_UBX :: Literal -> !WordOff -> BCInstr
+ GHC.ByteCode.Instr: PUSH_UBX :: Literal -> WordOff -> BCInstr
- GHC.ByteCode.Instr: ProtoBCO :: a -> [BCInstr] -> [StgWord] -> Word -> Int -> Either [CgStgAlt] CgStgRhs -> [FFIInfo] -> ProtoBCO a
+ GHC.ByteCode.Instr: ProtoBCO :: a -> [BCInstr] -> [StgWord] -> Word -> Int -> Either [CgStgAlt] CgStgRhs -> ProtoBCO a
- GHC.ByteCode.Instr: SLIDE :: !WordOff -> !WordOff -> BCInstr
+ GHC.ByteCode.Instr: SLIDE :: WordOff -> WordOff -> BCInstr
- GHC.ByteCode.Instr: STKCHECK :: !Word -> BCInstr
+ GHC.ByteCode.Instr: STKCHECK :: Word -> BCInstr
- GHC.ByteCode.Instr: SWIZZLE :: !WordOff -> !Int -> BCInstr
+ GHC.ByteCode.Instr: SWIZZLE :: WordOff -> Int -> BCInstr
- GHC.ByteCode.Instr: TESTEQ_D :: !Double -> LocalLabel -> BCInstr
+ GHC.ByteCode.Instr: TESTEQ_D :: Double -> LocalLabel -> BCInstr
- GHC.ByteCode.Instr: TESTEQ_F :: !Float -> LocalLabel -> BCInstr
+ GHC.ByteCode.Instr: TESTEQ_F :: Float -> LocalLabel -> BCInstr
- GHC.ByteCode.Instr: TESTEQ_I :: !Int -> LocalLabel -> BCInstr
+ GHC.ByteCode.Instr: TESTEQ_I :: Int -> LocalLabel -> BCInstr
- GHC.ByteCode.Instr: TESTEQ_I16 :: !Int16 -> LocalLabel -> BCInstr
+ GHC.ByteCode.Instr: TESTEQ_I16 :: Int16 -> LocalLabel -> BCInstr
- GHC.ByteCode.Instr: TESTEQ_I32 :: !Int32 -> LocalLabel -> BCInstr
+ GHC.ByteCode.Instr: TESTEQ_I32 :: Int32 -> LocalLabel -> BCInstr
- GHC.ByteCode.Instr: TESTEQ_I64 :: !Int64 -> LocalLabel -> BCInstr
+ GHC.ByteCode.Instr: TESTEQ_I64 :: Int64 -> LocalLabel -> BCInstr
- GHC.ByteCode.Instr: TESTEQ_I8 :: !Int16 -> LocalLabel -> BCInstr
+ GHC.ByteCode.Instr: TESTEQ_I8 :: Int16 -> LocalLabel -> BCInstr
- GHC.ByteCode.Instr: TESTEQ_P :: !Word16 -> LocalLabel -> BCInstr
+ GHC.ByteCode.Instr: TESTEQ_P :: Word16 -> LocalLabel -> BCInstr
- GHC.ByteCode.Instr: TESTEQ_W :: !Word -> LocalLabel -> BCInstr
+ GHC.ByteCode.Instr: TESTEQ_W :: Word -> LocalLabel -> BCInstr
- GHC.ByteCode.Instr: TESTEQ_W16 :: !Word16 -> LocalLabel -> BCInstr
+ GHC.ByteCode.Instr: TESTEQ_W16 :: Word16 -> LocalLabel -> BCInstr
- GHC.ByteCode.Instr: TESTEQ_W32 :: !Word32 -> LocalLabel -> BCInstr
+ GHC.ByteCode.Instr: TESTEQ_W32 :: Word32 -> LocalLabel -> BCInstr
- GHC.ByteCode.Instr: TESTEQ_W64 :: !Word64 -> LocalLabel -> BCInstr
+ GHC.ByteCode.Instr: TESTEQ_W64 :: Word64 -> LocalLabel -> BCInstr
- GHC.ByteCode.Instr: TESTEQ_W8 :: !Word8 -> LocalLabel -> BCInstr
+ GHC.ByteCode.Instr: TESTEQ_W8 :: Word8 -> LocalLabel -> BCInstr
- GHC.ByteCode.Instr: TESTLT_D :: !Double -> LocalLabel -> BCInstr
+ GHC.ByteCode.Instr: TESTLT_D :: Double -> LocalLabel -> BCInstr
- GHC.ByteCode.Instr: TESTLT_F :: !Float -> LocalLabel -> BCInstr
+ GHC.ByteCode.Instr: TESTLT_F :: Float -> LocalLabel -> BCInstr
- GHC.ByteCode.Instr: TESTLT_I :: !Int -> LocalLabel -> BCInstr
+ GHC.ByteCode.Instr: TESTLT_I :: Int -> LocalLabel -> BCInstr
- GHC.ByteCode.Instr: TESTLT_I16 :: !Int16 -> LocalLabel -> BCInstr
+ GHC.ByteCode.Instr: TESTLT_I16 :: Int16 -> LocalLabel -> BCInstr
- GHC.ByteCode.Instr: TESTLT_I32 :: !Int32 -> LocalLabel -> BCInstr
+ GHC.ByteCode.Instr: TESTLT_I32 :: Int32 -> LocalLabel -> BCInstr
- GHC.ByteCode.Instr: TESTLT_I64 :: !Int64 -> LocalLabel -> BCInstr
+ GHC.ByteCode.Instr: TESTLT_I64 :: Int64 -> LocalLabel -> BCInstr
- GHC.ByteCode.Instr: TESTLT_I8 :: !Int8 -> LocalLabel -> BCInstr
+ GHC.ByteCode.Instr: TESTLT_I8 :: Int8 -> LocalLabel -> BCInstr
- GHC.ByteCode.Instr: TESTLT_P :: !Word16 -> LocalLabel -> BCInstr
+ GHC.ByteCode.Instr: TESTLT_P :: Word16 -> LocalLabel -> BCInstr
- GHC.ByteCode.Instr: TESTLT_W :: !Word -> LocalLabel -> BCInstr
+ GHC.ByteCode.Instr: TESTLT_W :: Word -> LocalLabel -> BCInstr
- GHC.ByteCode.Instr: TESTLT_W16 :: !Word16 -> LocalLabel -> BCInstr
+ GHC.ByteCode.Instr: TESTLT_W16 :: Word16 -> LocalLabel -> BCInstr
- GHC.ByteCode.Instr: TESTLT_W32 :: !Word32 -> LocalLabel -> BCInstr
+ GHC.ByteCode.Instr: TESTLT_W32 :: Word32 -> LocalLabel -> BCInstr
- GHC.ByteCode.Instr: TESTLT_W64 :: !Word64 -> LocalLabel -> BCInstr
+ GHC.ByteCode.Instr: TESTLT_W64 :: Word64 -> LocalLabel -> BCInstr
- GHC.ByteCode.Instr: TESTLT_W8 :: !Word8 -> LocalLabel -> BCInstr
+ GHC.ByteCode.Instr: TESTLT_W8 :: Word8 -> LocalLabel -> BCInstr
- GHC.ByteCode.Instr: UNPACK :: !WordOff -> BCInstr
+ GHC.ByteCode.Instr: UNPACK :: WordOff -> BCInstr
- GHC.ByteCode.Linker: linkBCO :: Interp -> PkgsLoaded -> LinkerEnv -> NameEnv Int -> UnlinkedBCO -> IO ResolvedBCO
+ GHC.ByteCode.Linker: linkBCO :: Interp -> PkgsLoaded -> LinkerEnv -> LinkedBreaks -> NameEnv Int -> UnlinkedBCO -> IO ResolvedBCO
- GHC.ByteCode.Linker: linkFail :: String -> String -> IO a
+ GHC.ByteCode.Linker: linkFail :: String -> SDoc -> IO a
- GHC.ByteCode.Types: BCOByteArray :: !ByteArray# -> BCOByteArray a
+ GHC.ByteCode.Types: BCOByteArray :: ByteArray# -> BCOByteArray a
- GHC.ByteCode.Types: BCONPtrAddr :: !Name -> BCONPtr
+ GHC.ByteCode.Types: BCONPtrAddr :: Name -> BCONPtr
- GHC.ByteCode.Types: BCONPtrItbl :: !Name -> BCONPtr
+ GHC.ByteCode.Types: BCONPtrItbl :: Name -> BCONPtr
- GHC.ByteCode.Types: BCONPtrLbl :: !FastString -> BCONPtr
+ GHC.ByteCode.Types: BCONPtrLbl :: FastString -> BCONPtr
- GHC.ByteCode.Types: BCONPtrStr :: !ByteString -> BCONPtr
+ GHC.ByteCode.Types: BCONPtrStr :: ByteString -> BCONPtr
- GHC.ByteCode.Types: BCONPtrWord :: {-# UNPACK #-} !Word -> BCONPtr
+ GHC.ByteCode.Types: BCONPtrWord :: Word -> BCONPtr
- GHC.ByteCode.Types: BCOPtrBCO :: !UnlinkedBCO -> BCOPtr
+ GHC.ByteCode.Types: BCOPtrBCO :: UnlinkedBCO -> BCOPtr
- GHC.ByteCode.Types: BCOPtrBreakArray :: ForeignRef BreakArray -> BCOPtr
+ GHC.ByteCode.Types: BCOPtrBreakArray :: Module -> BCOPtr
- GHC.ByteCode.Types: BCOPtrName :: !Name -> BCOPtr
+ GHC.ByteCode.Types: BCOPtrName :: Name -> BCOPtr
- GHC.ByteCode.Types: BCOPtrPrimOp :: !PrimOp -> BCOPtr
+ GHC.ByteCode.Types: BCOPtrPrimOp :: PrimOp -> BCOPtr
- GHC.ByteCode.Types: CgBreakInfo :: ![IfaceTvBndr] -> ![Maybe (IfaceIdBndr, Word)] -> !IfaceType -> CgBreakInfo
+ GHC.ByteCode.Types: CgBreakInfo :: [IfaceTvBndr] -> [Maybe (IfaceIdBndr, Word)] -> IfaceType -> Either InternalBreakLoc BreakpointId -> CgBreakInfo
- GHC.ByteCode.Types: CompiledByteCode :: FlatBag UnlinkedBCO -> ItblEnv -> [FFIInfo] -> AddrEnv -> Maybe ModBreaks -> ![SptEntry] -> CompiledByteCode
+ GHC.ByteCode.Types: CompiledByteCode :: FlatBag UnlinkedBCO -> [(Name, ConInfoTable)] -> [(Name, ByteString)] -> Maybe InternalModBreaks -> [SptEntry] -> CompiledByteCode
- GHC.ByteCode.Types: FFIInfo :: RemotePtr C_ffi_cif -> FFIInfo
+ GHC.ByteCode.Types: FFIInfo :: [FFIType] -> FFIType -> FFIInfo
- GHC.ByteCode.Types: ModBreaks :: ForeignRef BreakArray -> !Array BreakIndex SrcSpan -> !Array BreakIndex [OccName] -> !Array BreakIndex [String] -> !Array BreakIndex (RemotePtr CostCentre) -> IntMap CgBreakInfo -> RemotePtr ModuleName -> ModBreaks
+ GHC.ByteCode.Types: ModBreaks :: Array BreakTickIndex SrcSpan -> Array BreakTickIndex [OccName] -> Array BreakTickIndex [String] -> Array BreakTickIndex (String, String) -> Module -> ModBreaks
- GHC.ByteCode.Types: NativeCallInfo :: !NativeCallType -> !WordOff -> !GlobalRegSet -> !WordOff -> NativeCallInfo
+ GHC.ByteCode.Types: NativeCallInfo :: NativeCallType -> WordOff -> GlobalRegSet -> WordOff -> NativeCallInfo
- GHC.ByteCode.Types: UnlinkedBCO :: !Name -> {-# UNPACK #-} !Int -> !BCOByteArray Word16 -> !BCOByteArray Word -> !FlatBag BCONPtr -> !FlatBag BCOPtr -> UnlinkedBCO
+ GHC.ByteCode.Types: UnlinkedBCO :: Name -> Int -> BCOByteArray Word16 -> BCOByteArray Word -> FlatBag BCONPtr -> FlatBag BCOPtr -> UnlinkedBCO
- GHC.ByteCode.Types: [bc_breaks] :: CompiledByteCode -> Maybe ModBreaks
+ GHC.ByteCode.Types: [bc_breaks] :: CompiledByteCode -> Maybe InternalModBreaks
- GHC.ByteCode.Types: [bc_itbls] :: CompiledByteCode -> ItblEnv
+ GHC.ByteCode.Types: [bc_itbls] :: CompiledByteCode -> [(Name, ConInfoTable)]
- GHC.ByteCode.Types: [bc_spt_entries] :: CompiledByteCode -> ![SptEntry]
+ GHC.ByteCode.Types: [bc_spt_entries] :: CompiledByteCode -> [SptEntry]
- GHC.ByteCode.Types: [bc_strs] :: CompiledByteCode -> AddrEnv
+ GHC.ByteCode.Types: [bc_strs] :: CompiledByteCode -> [(Name, ByteString)]
- GHC.ByteCode.Types: [cgb_resty] :: CgBreakInfo -> !IfaceType
+ GHC.ByteCode.Types: [cgb_resty] :: CgBreakInfo -> IfaceType
- GHC.ByteCode.Types: [cgb_tyvars] :: CgBreakInfo -> ![IfaceTvBndr]
+ GHC.ByteCode.Types: [cgb_tyvars] :: CgBreakInfo -> [IfaceTvBndr]
- GHC.ByteCode.Types: [cgb_vars] :: CgBreakInfo -> ![Maybe (IfaceIdBndr, Word)]
+ GHC.ByteCode.Types: [cgb_vars] :: CgBreakInfo -> [Maybe (IfaceIdBndr, Word)]
- GHC.ByteCode.Types: [getBCOByteArray] :: BCOByteArray a -> !ByteArray#
+ GHC.ByteCode.Types: [getBCOByteArray] :: BCOByteArray a -> ByteArray#
- GHC.ByteCode.Types: [modBreaks_ccs] :: ModBreaks -> !Array BreakIndex (RemotePtr CostCentre)
+ GHC.ByteCode.Types: [modBreaks_ccs] :: ModBreaks -> Array BreakTickIndex (String, String)
- GHC.ByteCode.Types: [modBreaks_decls] :: ModBreaks -> !Array BreakIndex [String]
+ GHC.ByteCode.Types: [modBreaks_decls] :: ModBreaks -> Array BreakTickIndex [String]
- GHC.ByteCode.Types: [modBreaks_locs] :: ModBreaks -> !Array BreakIndex SrcSpan
+ GHC.ByteCode.Types: [modBreaks_locs] :: ModBreaks -> Array BreakTickIndex SrcSpan
- GHC.ByteCode.Types: [modBreaks_module] :: ModBreaks -> RemotePtr ModuleName
+ GHC.ByteCode.Types: [modBreaks_module] :: ModBreaks -> Module
- GHC.ByteCode.Types: [modBreaks_vars] :: ModBreaks -> !Array BreakIndex [OccName]
+ GHC.ByteCode.Types: [modBreaks_vars] :: ModBreaks -> Array BreakTickIndex [OccName]
- GHC.ByteCode.Types: [nativeCallRegs] :: NativeCallInfo -> !GlobalRegSet
+ GHC.ByteCode.Types: [nativeCallRegs] :: NativeCallInfo -> GlobalRegSet
- GHC.ByteCode.Types: [nativeCallSize] :: NativeCallInfo -> !WordOff
+ GHC.ByteCode.Types: [nativeCallSize] :: NativeCallInfo -> WordOff
- GHC.ByteCode.Types: [nativeCallStackSpillSize] :: NativeCallInfo -> !WordOff
+ GHC.ByteCode.Types: [nativeCallStackSpillSize] :: NativeCallInfo -> WordOff
- GHC.ByteCode.Types: [nativeCallType] :: NativeCallInfo -> !NativeCallType
+ GHC.ByteCode.Types: [nativeCallType] :: NativeCallInfo -> NativeCallType
- GHC.ByteCode.Types: [unlinkedBCOArity] :: UnlinkedBCO -> {-# UNPACK #-} !Int
+ GHC.ByteCode.Types: [unlinkedBCOArity] :: UnlinkedBCO -> Int
- GHC.ByteCode.Types: [unlinkedBCOBitmap] :: UnlinkedBCO -> !BCOByteArray Word
+ GHC.ByteCode.Types: [unlinkedBCOBitmap] :: UnlinkedBCO -> BCOByteArray Word
- GHC.ByteCode.Types: [unlinkedBCOInstrs] :: UnlinkedBCO -> !BCOByteArray Word16
+ GHC.ByteCode.Types: [unlinkedBCOInstrs] :: UnlinkedBCO -> BCOByteArray Word16
- GHC.ByteCode.Types: [unlinkedBCOLits] :: UnlinkedBCO -> !FlatBag BCONPtr
+ GHC.ByteCode.Types: [unlinkedBCOLits] :: UnlinkedBCO -> FlatBag BCONPtr
- GHC.ByteCode.Types: [unlinkedBCOName] :: UnlinkedBCO -> !Name
+ GHC.ByteCode.Types: [unlinkedBCOName] :: UnlinkedBCO -> Name
- GHC.ByteCode.Types: [unlinkedBCOPtrs] :: UnlinkedBCO -> !FlatBag BCOPtr
+ GHC.ByteCode.Types: [unlinkedBCOPtrs] :: UnlinkedBCO -> FlatBag BCOPtr
- GHC.Cmm: sectionProtection :: SectionType -> SectionProtection
+ GHC.Cmm: sectionProtection :: Section -> SectionProtection
- GHC.Cmm.CLabel: InfoProvEnt :: !CLabel -> !Int -> !String -> !Module -> !Maybe (RealSrcSpan, LexicalFastString) -> InfoProvEnt
+ GHC.Cmm.CLabel: InfoProvEnt :: CLabel -> Int -> String -> Module -> Maybe (RealSrcSpan, LexicalFastString) -> InfoProvEnt
- GHC.Cmm.CLabel: [infoProvEntClosureType] :: InfoProvEnt -> !Int
+ GHC.Cmm.CLabel: [infoProvEntClosureType] :: InfoProvEnt -> Int
- GHC.Cmm.CLabel: [infoProvModule] :: InfoProvEnt -> !Module
+ GHC.Cmm.CLabel: [infoProvModule] :: InfoProvEnt -> Module
- GHC.Cmm.CLabel: [infoTableProv] :: InfoProvEnt -> !Maybe (RealSrcSpan, LexicalFastString)
+ GHC.Cmm.CLabel: [infoTableProv] :: InfoProvEnt -> Maybe (RealSrcSpan, LexicalFastString)
- GHC.Cmm.CLabel: [infoTablePtr] :: InfoProvEnt -> !CLabel
+ GHC.Cmm.CLabel: [infoTablePtr] :: InfoProvEnt -> CLabel
- GHC.Cmm.CLabel: [infoTableType] :: InfoProvEnt -> !String
+ GHC.Cmm.CLabel: [infoTableType] :: InfoProvEnt -> String
- GHC.Cmm.Config: CmmConfig :: !Profile -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> CmmConfig
+ GHC.Cmm.Config: CmmConfig :: Profile -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> CmmConfig
- GHC.Cmm.Config: [cmmDoCmmSwitchPlans] :: CmmConfig -> !Bool
+ GHC.Cmm.Config: [cmmDoCmmSwitchPlans] :: CmmConfig -> Bool
- GHC.Cmm.Config: [cmmDoLinting] :: CmmConfig -> !Bool
+ GHC.Cmm.Config: [cmmDoLinting] :: CmmConfig -> Bool
- GHC.Cmm.Config: [cmmExternalDynamicRefs] :: CmmConfig -> !Bool
+ GHC.Cmm.Config: [cmmExternalDynamicRefs] :: CmmConfig -> Bool
- GHC.Cmm.Config: [cmmGenStackUnwindInstr] :: CmmConfig -> !Bool
+ GHC.Cmm.Config: [cmmGenStackUnwindInstr] :: CmmConfig -> Bool
- GHC.Cmm.Config: [cmmOptControlFlow] :: CmmConfig -> !Bool
+ GHC.Cmm.Config: [cmmOptControlFlow] :: CmmConfig -> Bool
- GHC.Cmm.Config: [cmmOptElimCommonBlks] :: CmmConfig -> !Bool
+ GHC.Cmm.Config: [cmmOptElimCommonBlks] :: CmmConfig -> Bool
- GHC.Cmm.Config: [cmmOptSink] :: CmmConfig -> !Bool
+ GHC.Cmm.Config: [cmmOptSink] :: CmmConfig -> Bool
- GHC.Cmm.Config: [cmmOptThreadSanitizer] :: CmmConfig -> !Bool
+ GHC.Cmm.Config: [cmmOptThreadSanitizer] :: CmmConfig -> Bool
- GHC.Cmm.Config: [cmmProfile] :: CmmConfig -> !Profile
+ GHC.Cmm.Config: [cmmProfile] :: CmmConfig -> Profile
- GHC.Cmm.Config: [cmmSplitProcPoints] :: CmmConfig -> !Bool
+ GHC.Cmm.Config: [cmmSplitProcPoints] :: CmmConfig -> Bool
- GHC.Cmm.Dataflow: Changed :: !a -> JoinedFact a
+ GHC.Cmm.Dataflow: Changed :: a -> JoinedFact a
- GHC.Cmm.Dataflow: NotChanged :: !a -> JoinedFact a
+ GHC.Cmm.Dataflow: NotChanged :: a -> JoinedFact a
- GHC.Cmm.DebugBlock: DebugBlock :: !Label -> !Label -> !CLabel -> !Bool -> !Maybe DebugBlock -> ![CmmTickish] -> !Maybe CmmTickish -> !Maybe Int -> [UnwindPoint] -> ![DebugBlock] -> DebugBlock
+ GHC.Cmm.DebugBlock: DebugBlock :: Label -> Label -> CLabel -> Bool -> Maybe DebugBlock -> [CmmTickish] -> Maybe CmmTickish -> Maybe Int -> [UnwindPoint] -> [DebugBlock] -> DebugBlock
- GHC.Cmm.DebugBlock: UnwindPoint :: !CLabel -> !UnwindTable -> UnwindPoint
+ GHC.Cmm.DebugBlock: UnwindPoint :: CLabel -> UnwindTable -> UnwindPoint
- GHC.Cmm.DebugBlock: UwConst :: !Int -> UnwindExpr
+ GHC.Cmm.DebugBlock: UwConst :: Int -> UnwindExpr
- GHC.Cmm.DebugBlock: UwReg :: !GlobalRegUse -> !Int -> UnwindExpr
+ GHC.Cmm.DebugBlock: UwReg :: GlobalRegUse -> Int -> UnwindExpr
- GHC.Cmm.DebugBlock: [dblBlocks] :: DebugBlock -> ![DebugBlock]
+ GHC.Cmm.DebugBlock: [dblBlocks] :: DebugBlock -> [DebugBlock]
- GHC.Cmm.DebugBlock: [dblCLabel] :: DebugBlock -> !CLabel
+ GHC.Cmm.DebugBlock: [dblCLabel] :: DebugBlock -> CLabel
- GHC.Cmm.DebugBlock: [dblHasInfoTbl] :: DebugBlock -> !Bool
+ GHC.Cmm.DebugBlock: [dblHasInfoTbl] :: DebugBlock -> Bool
- GHC.Cmm.DebugBlock: [dblLabel] :: DebugBlock -> !Label
+ GHC.Cmm.DebugBlock: [dblLabel] :: DebugBlock -> Label
- GHC.Cmm.DebugBlock: [dblParent] :: DebugBlock -> !Maybe DebugBlock
+ GHC.Cmm.DebugBlock: [dblParent] :: DebugBlock -> Maybe DebugBlock
- GHC.Cmm.DebugBlock: [dblPosition] :: DebugBlock -> !Maybe Int
+ GHC.Cmm.DebugBlock: [dblPosition] :: DebugBlock -> Maybe Int
- GHC.Cmm.DebugBlock: [dblProcedure] :: DebugBlock -> !Label
+ GHC.Cmm.DebugBlock: [dblProcedure] :: DebugBlock -> Label
- GHC.Cmm.DebugBlock: [dblSourceTick] :: DebugBlock -> !Maybe CmmTickish
+ GHC.Cmm.DebugBlock: [dblSourceTick] :: DebugBlock -> Maybe CmmTickish
- GHC.Cmm.DebugBlock: [dblTicks] :: DebugBlock -> ![CmmTickish]
+ GHC.Cmm.DebugBlock: [dblTicks] :: DebugBlock -> [CmmTickish]
- GHC.Cmm.DebugBlock: cmmDebugGen :: ModLocation -> RawCmmGroup -> [DebugBlock]
+ GHC.Cmm.DebugBlock: cmmDebugGen :: ModLocation -> [RawCmmDecl] -> [DebugBlock]
- GHC.Cmm.Expr: CmmBlock :: {-# UNPACK #-} !BlockId -> CmmLit
+ GHC.Cmm.Expr: CmmBlock :: BlockId -> CmmLit
- GHC.Cmm.Expr: CmmFloat :: Rational -> !Width -> CmmLit
+ GHC.Cmm.Expr: CmmFloat :: Rational -> Width -> CmmLit
- GHC.Cmm.Expr: CmmInt :: !Integer -> !Width -> CmmLit
+ GHC.Cmm.Expr: CmmInt :: Integer -> Width -> CmmLit
- GHC.Cmm.Expr: CmmLabelDiffOff :: CLabel -> CLabel -> !Int -> !Width -> CmmLit
+ GHC.Cmm.Expr: CmmLabelDiffOff :: CLabel -> CLabel -> Int -> Width -> CmmLit
- GHC.Cmm.Expr: CmmLabelOff :: CLabel -> !Int -> CmmLit
+ GHC.Cmm.Expr: CmmLabelOff :: CLabel -> Int -> CmmLit
- GHC.Cmm.Expr: CmmLit :: !CmmLit -> CmmExpr
+ GHC.Cmm.Expr: CmmLit :: CmmLit -> CmmExpr
- GHC.Cmm.Expr: CmmLoad :: !CmmExpr -> !CmmType -> !AlignmentSpec -> CmmExpr
+ GHC.Cmm.Expr: CmmLoad :: CmmExpr -> CmmType -> AlignmentSpec -> CmmExpr
- GHC.Cmm.Expr: CmmLocal :: {-# UNPACK #-} !LocalReg -> CmmReg
+ GHC.Cmm.Expr: CmmLocal :: LocalReg -> CmmReg
- GHC.Cmm.Expr: CmmReg :: !CmmReg -> CmmExpr
+ GHC.Cmm.Expr: CmmReg :: CmmReg -> CmmExpr
- GHC.Cmm.Expr: CmmRegOff :: !CmmReg -> !Int -> CmmExpr
+ GHC.Cmm.Expr: CmmRegOff :: CmmReg -> Int -> CmmExpr
- GHC.Cmm.Expr: CmmStackSlot :: Area -> {-# UNPACK #-} !Int -> CmmExpr
+ GHC.Cmm.Expr: CmmStackSlot :: Area -> Int -> CmmExpr
- GHC.Cmm.Expr: DoubleReg :: {-# UNPACK #-} !Int -> GlobalReg
+ GHC.Cmm.Expr: DoubleReg :: Int -> GlobalReg
- GHC.Cmm.Expr: FloatReg :: {-# UNPACK #-} !Int -> GlobalReg
+ GHC.Cmm.Expr: FloatReg :: Int -> GlobalReg
- GHC.Cmm.Expr: GlobalRegUse :: !GlobalReg -> !CmmType -> GlobalRegUse
+ GHC.Cmm.Expr: GlobalRegUse :: GlobalReg -> CmmType -> GlobalRegUse
- GHC.Cmm.Expr: LocalReg :: {-# UNPACK #-} !Unique -> !CmmType -> LocalReg
+ GHC.Cmm.Expr: LocalReg :: Unique -> CmmType -> LocalReg
- GHC.Cmm.Expr: LongReg :: {-# UNPACK #-} !Int -> GlobalReg
+ GHC.Cmm.Expr: LongReg :: Int -> GlobalReg
- GHC.Cmm.Expr: VanillaReg :: {-# UNPACK #-} !Int -> GlobalReg
+ GHC.Cmm.Expr: VanillaReg :: Int -> GlobalReg
- GHC.Cmm.Expr: XmmReg :: {-# UNPACK #-} !Int -> GlobalReg
+ GHC.Cmm.Expr: XmmReg :: Int -> GlobalReg
- GHC.Cmm.Expr: YmmReg :: {-# UNPACK #-} !Int -> GlobalReg
+ GHC.Cmm.Expr: YmmReg :: Int -> GlobalReg
- GHC.Cmm.Expr: Young :: {-# UNPACK #-} !BlockId -> Area
+ GHC.Cmm.Expr: Young :: BlockId -> Area
- GHC.Cmm.Expr: ZmmReg :: {-# UNPACK #-} !Int -> GlobalReg
+ GHC.Cmm.Expr: ZmmReg :: Int -> GlobalReg
- GHC.Cmm.Expr: [globalRegUse_reg] :: GlobalRegUse -> !GlobalReg
+ GHC.Cmm.Expr: [globalRegUse_reg] :: GlobalRegUse -> GlobalReg
- GHC.Cmm.Expr: [globalRegUse_type] :: GlobalRegUse -> !CmmType
+ GHC.Cmm.Expr: [globalRegUse_type] :: GlobalRegUse -> CmmType
- GHC.Cmm.MachOp: MO_VS_Quot :: Length -> Width -> MachOp
+ GHC.Cmm.MachOp: MO_VS_Quot :: Length -> Width -> CallishMachOp
- GHC.Cmm.MachOp: MO_VS_Rem :: Length -> Width -> MachOp
+ GHC.Cmm.MachOp: MO_VS_Rem :: Length -> Width -> CallishMachOp
- GHC.Cmm.MachOp: MO_VU_Quot :: Length -> Width -> MachOp
+ GHC.Cmm.MachOp: MO_VU_Quot :: Length -> Width -> CallishMachOp
- GHC.Cmm.MachOp: MO_VU_Rem :: Length -> Width -> MachOp
+ GHC.Cmm.MachOp: MO_VU_Rem :: Length -> Width -> CallishMachOp
- GHC.Cmm.Node: SubScope :: !Unique -> CmmTickScope -> CmmTickScope
+ GHC.Cmm.Node: SubScope :: Unique -> CmmTickScope -> CmmTickScope
- GHC.Cmm.Node: [CmmAssign] :: !CmmReg -> !CmmExpr -> CmmNode 'Open 'Open
+ GHC.Cmm.Node: [CmmAssign] :: CmmReg -> CmmExpr -> CmmNode 'Open 'Open
- GHC.Cmm.Node: [CmmBranch] :: {-# UNPACK #-} !Label -> CmmNode 'Open 'Closed
+ GHC.Cmm.Node: [CmmBranch] :: Label -> CmmNode 'Open 'Closed
- GHC.Cmm.Node: [CmmCondBranch] :: CmmExpr -> {-# UNPACK #-} !Label -> {-# UNPACK #-} !Label -> Maybe Bool -> CmmNode 'Open 'Closed
+ GHC.Cmm.Node: [CmmCondBranch] :: CmmExpr -> Label -> Label -> Maybe Bool -> CmmNode 'Open 'Closed
- GHC.Cmm.Node: [CmmEntry] :: {-# UNPACK #-} !Label -> CmmTickScope -> CmmNode 'Closed 'Open
+ GHC.Cmm.Node: [CmmEntry] :: Label -> CmmTickScope -> CmmNode 'Closed 'Open
- GHC.Cmm.Node: [CmmForeignCall] :: ForeignTarget -> [CmmFormal] -> [CmmActual] -> {-# UNPACK #-} !Label -> ByteOff -> ByteOff -> Bool -> CmmNode 'Open 'Closed
+ GHC.Cmm.Node: [CmmForeignCall] :: ForeignTarget -> [CmmFormal] -> [CmmActual] -> Label -> ByteOff -> ByteOff -> Bool -> CmmNode 'Open 'Closed
- GHC.Cmm.Node: [CmmStore] :: !CmmExpr -> !CmmExpr -> !AlignmentSpec -> CmmNode 'Open 'Open
+ GHC.Cmm.Node: [CmmStore] :: CmmExpr -> CmmExpr -> AlignmentSpec -> CmmNode 'Open 'Open
- GHC.Cmm.Node: [CmmTick] :: !CmmTickish -> CmmNode 'Open 'Open
+ GHC.Cmm.Node: [CmmTick] :: CmmTickish -> CmmNode 'Open 'Open
- GHC.Cmm.Parser: CmmParserConfig :: !ParserOpts -> !PDConfig -> !StgToCmmConfig -> CmmParserConfig
+ GHC.Cmm.Parser: CmmParserConfig :: ParserOpts -> PDConfig -> StgToCmmConfig -> CmmParserConfig
- GHC.Cmm.Parser: [cmmpPDConfig] :: CmmParserConfig -> !PDConfig
+ GHC.Cmm.Parser: [cmmpPDConfig] :: CmmParserConfig -> PDConfig
- GHC.Cmm.Parser: [cmmpParserOpts] :: CmmParserConfig -> !ParserOpts
+ GHC.Cmm.Parser: [cmmpParserOpts] :: CmmParserConfig -> ParserOpts
- GHC.Cmm.Parser: [cmmpStgToCmmConfig] :: CmmParserConfig -> !StgToCmmConfig
+ GHC.Cmm.Parser: [cmmpStgToCmmConfig] :: CmmParserConfig -> StgToCmmConfig
- GHC.Cmm.Parser.Config: CmmParserConfig :: !ParserOpts -> !PDConfig -> !StgToCmmConfig -> CmmParserConfig
+ GHC.Cmm.Parser.Config: CmmParserConfig :: ParserOpts -> PDConfig -> StgToCmmConfig -> CmmParserConfig
- GHC.Cmm.Parser.Config: PDConfig :: !Profile -> !Bool -> PDConfig
+ GHC.Cmm.Parser.Config: PDConfig :: Profile -> Bool -> PDConfig
- GHC.Cmm.Parser.Config: [cmmpPDConfig] :: CmmParserConfig -> !PDConfig
+ GHC.Cmm.Parser.Config: [cmmpPDConfig] :: CmmParserConfig -> PDConfig
- GHC.Cmm.Parser.Config: [cmmpParserOpts] :: CmmParserConfig -> !ParserOpts
+ GHC.Cmm.Parser.Config: [cmmpParserOpts] :: CmmParserConfig -> ParserOpts
- GHC.Cmm.Parser.Config: [cmmpStgToCmmConfig] :: CmmParserConfig -> !StgToCmmConfig
+ GHC.Cmm.Parser.Config: [cmmpStgToCmmConfig] :: CmmParserConfig -> StgToCmmConfig
- GHC.Cmm.Parser.Config: [pdProfile] :: PDConfig -> !Profile
+ GHC.Cmm.Parser.Config: [pdProfile] :: PDConfig -> Profile
- GHC.Cmm.Parser.Config: [pdSanitizeAlignment] :: PDConfig -> !Bool
+ GHC.Cmm.Parser.Config: [pdSanitizeAlignment] :: PDConfig -> Bool
- GHC.Cmm.Parser.Monad: PDConfig :: !Profile -> !Bool -> PDConfig
+ GHC.Cmm.Parser.Monad: PDConfig :: Profile -> Bool -> PDConfig
- GHC.Cmm.Parser.Monad: [pdProfile] :: PDConfig -> !Profile
+ GHC.Cmm.Parser.Monad: [pdProfile] :: PDConfig -> Profile
- GHC.Cmm.Parser.Monad: [pdSanitizeAlignment] :: PDConfig -> !Bool
+ GHC.Cmm.Parser.Monad: [pdSanitizeAlignment] :: PDConfig -> Bool
- GHC.Cmm.Reg: CmmLocal :: {-# UNPACK #-} !LocalReg -> CmmReg
+ GHC.Cmm.Reg: CmmLocal :: LocalReg -> CmmReg
- GHC.Cmm.Reg: DoubleReg :: {-# UNPACK #-} !Int -> GlobalReg
+ GHC.Cmm.Reg: DoubleReg :: Int -> GlobalReg
- GHC.Cmm.Reg: FloatReg :: {-# UNPACK #-} !Int -> GlobalReg
+ GHC.Cmm.Reg: FloatReg :: Int -> GlobalReg
- GHC.Cmm.Reg: GlobalRegUse :: !GlobalReg -> !CmmType -> GlobalRegUse
+ GHC.Cmm.Reg: GlobalRegUse :: GlobalReg -> CmmType -> GlobalRegUse
- GHC.Cmm.Reg: LocalReg :: {-# UNPACK #-} !Unique -> !CmmType -> LocalReg
+ GHC.Cmm.Reg: LocalReg :: Unique -> CmmType -> LocalReg
- GHC.Cmm.Reg: LongReg :: {-# UNPACK #-} !Int -> GlobalReg
+ GHC.Cmm.Reg: LongReg :: Int -> GlobalReg
- GHC.Cmm.Reg: VanillaReg :: {-# UNPACK #-} !Int -> GlobalReg
+ GHC.Cmm.Reg: VanillaReg :: Int -> GlobalReg
- GHC.Cmm.Reg: XmmReg :: {-# UNPACK #-} !Int -> GlobalReg
+ GHC.Cmm.Reg: XmmReg :: Int -> GlobalReg
- GHC.Cmm.Reg: YmmReg :: {-# UNPACK #-} !Int -> GlobalReg
+ GHC.Cmm.Reg: YmmReg :: Int -> GlobalReg
- GHC.Cmm.Reg: ZmmReg :: {-# UNPACK #-} !Int -> GlobalReg
+ GHC.Cmm.Reg: ZmmReg :: Int -> GlobalReg
- GHC.Cmm.Reg: [globalRegUse_reg] :: GlobalRegUse -> !GlobalReg
+ GHC.Cmm.Reg: [globalRegUse_reg] :: GlobalRegUse -> GlobalReg
- GHC.Cmm.Reg: [globalRegUse_type] :: GlobalRegUse -> !CmmType
+ GHC.Cmm.Reg: [globalRegUse_type] :: GlobalRegUse -> CmmType
- GHC.CmmToAsm: NcgImpl :: !NCGConfig -> (RawCmmDecl -> NatM [NatCmmDecl statics instr]) -> (instr -> Maybe (NatCmmDecl statics instr)) -> (jumpDest -> Maybe BlockId) -> (instr -> Maybe jumpDest) -> ((BlockId -> Maybe jumpDest) -> statics -> statics) -> ((BlockId -> Maybe jumpDest) -> instr -> instr) -> (NatCmmDecl statics instr -> SDoc) -> (NatCmmDecl statics instr -> HDoc) -> Int -> [RealReg] -> (Int -> NatCmmDecl statics instr -> UniqDSM (NatCmmDecl statics instr, [(BlockId, BlockId)])) -> (Platform -> LabelMap RawCmmStatics -> [NatBasicBlock instr] -> UniqDSM [NatBasicBlock instr]) -> ([instr] -> [UnwindPoint]) -> (Maybe CFG -> LabelMap RawCmmStatics -> [NatBasicBlock instr] -> [NatBasicBlock instr]) -> NcgImpl statics instr jumpDest
+ GHC.CmmToAsm: NcgImpl :: NCGConfig -> (RawCmmDecl -> NatM [NatCmmDecl statics instr]) -> (instr -> Maybe (NatCmmDecl statics instr)) -> (jumpDest -> Maybe BlockId) -> (instr -> Maybe jumpDest) -> ((BlockId -> Maybe jumpDest) -> statics -> statics) -> ((BlockId -> Maybe jumpDest) -> instr -> instr) -> (NatCmmDecl statics instr -> SDoc) -> (NatCmmDecl statics instr -> HDoc) -> Int -> [RealReg] -> (Int -> NatCmmDecl statics instr -> UniqDSM (NatCmmDecl statics instr, [(BlockId, BlockId)])) -> (Platform -> LabelMap RawCmmStatics -> [NatBasicBlock instr] -> UniqDSM [NatBasicBlock instr]) -> ([instr] -> [UnwindPoint]) -> (Maybe CFG -> LabelMap RawCmmStatics -> [NatBasicBlock instr] -> [NatBasicBlock instr]) -> NcgImpl statics instr jumpDest
- GHC.CmmToAsm: [ncgConfig] :: NcgImpl statics instr jumpDest -> !NCGConfig
+ GHC.CmmToAsm: [ncgConfig] :: NcgImpl statics instr jumpDest -> NCGConfig
- GHC.CmmToAsm.CFG: CfgEdge :: !BlockId -> !BlockId -> !EdgeInfo -> CfgEdge
+ GHC.CmmToAsm.CFG: CfgEdge :: BlockId -> BlockId -> EdgeInfo -> CfgEdge
- GHC.CmmToAsm.CFG: EdgeInfo :: !TransitionSource -> !EdgeWeight -> EdgeInfo
+ GHC.CmmToAsm.CFG: EdgeInfo :: TransitionSource -> EdgeWeight -> EdgeInfo
- GHC.CmmToAsm.CFG: [edgeFrom] :: CfgEdge -> !BlockId
+ GHC.CmmToAsm.CFG: [edgeFrom] :: CfgEdge -> BlockId
- GHC.CmmToAsm.CFG: [edgeInfo] :: CfgEdge -> !EdgeInfo
+ GHC.CmmToAsm.CFG: [edgeInfo] :: CfgEdge -> EdgeInfo
- GHC.CmmToAsm.CFG: [edgeTo] :: CfgEdge -> !BlockId
+ GHC.CmmToAsm.CFG: [edgeTo] :: CfgEdge -> BlockId
- GHC.CmmToAsm.CFG: [edgeWeight] :: EdgeInfo -> !EdgeWeight
+ GHC.CmmToAsm.CFG: [edgeWeight] :: EdgeInfo -> EdgeWeight
- GHC.CmmToAsm.CFG: [transitionSource] :: EdgeInfo -> !TransitionSource
+ GHC.CmmToAsm.CFG: [transitionSource] :: EdgeInfo -> TransitionSource
- GHC.CmmToAsm.CFG: getCfgProc :: Platform -> Weights -> RawCmmDecl -> CFG
+ GHC.CmmToAsm.CFG: getCfgProc :: Platform -> Weights -> GenCmmDecl d h CmmGraph -> CFG
- GHC.CmmToAsm.Config: NCGConfig :: !Platform -> !SDocContext -> !Module -> !Maybe Int -> !Bool -> !Bool -> !Word -> !Word -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> Maybe SseVersion -> !Bool -> !Bool -> !Bool -> Maybe BmiVersion -> !Bool -> !Bool -> !Bool -> !Weights -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> NCGConfig
+ GHC.CmmToAsm.Config: NCGConfig :: Platform -> SDocContext -> Module -> Maybe Int -> Bool -> Bool -> Word -> Word -> Bool -> Bool -> Bool -> Bool -> Bool -> Maybe SseVersion -> Bool -> Bool -> Bool -> Maybe BmiVersion -> Bool -> Bool -> Bool -> Weights -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> NCGConfig
- GHC.CmmToAsm.Config: [ncgAsmContext] :: NCGConfig -> !SDocContext
+ GHC.CmmToAsm.Config: [ncgAsmContext] :: NCGConfig -> SDocContext
- GHC.CmmToAsm.Config: [ncgAsmLinting] :: NCGConfig -> !Bool
+ GHC.CmmToAsm.Config: [ncgAsmLinting] :: NCGConfig -> Bool
- GHC.CmmToAsm.Config: [ncgAvx2Enabled] :: NCGConfig -> !Bool
+ GHC.CmmToAsm.Config: [ncgAvx2Enabled] :: NCGConfig -> Bool
- GHC.CmmToAsm.Config: [ncgAvx512fEnabled] :: NCGConfig -> !Bool
+ GHC.CmmToAsm.Config: [ncgAvx512fEnabled] :: NCGConfig -> Bool
- GHC.CmmToAsm.Config: [ncgAvxEnabled] :: NCGConfig -> !Bool
+ GHC.CmmToAsm.Config: [ncgAvxEnabled] :: NCGConfig -> Bool
- GHC.CmmToAsm.Config: [ncgCfgBlockLayout] :: NCGConfig -> !Bool
+ GHC.CmmToAsm.Config: [ncgCfgBlockLayout] :: NCGConfig -> Bool
- GHC.CmmToAsm.Config: [ncgCfgWeightlessLayout] :: NCGConfig -> !Bool
+ GHC.CmmToAsm.Config: [ncgCfgWeightlessLayout] :: NCGConfig -> Bool
- GHC.CmmToAsm.Config: [ncgCfgWeights] :: NCGConfig -> !Weights
+ GHC.CmmToAsm.Config: [ncgCfgWeights] :: NCGConfig -> Weights
- GHC.CmmToAsm.Config: [ncgCmmStaticPred] :: NCGConfig -> !Bool
+ GHC.CmmToAsm.Config: [ncgCmmStaticPred] :: NCGConfig -> Bool
- GHC.CmmToAsm.Config: [ncgComputeUnwinding] :: NCGConfig -> !Bool
+ GHC.CmmToAsm.Config: [ncgComputeUnwinding] :: NCGConfig -> Bool
- GHC.CmmToAsm.Config: [ncgDoConstantFolding] :: NCGConfig -> !Bool
+ GHC.CmmToAsm.Config: [ncgDoConstantFolding] :: NCGConfig -> Bool
- GHC.CmmToAsm.Config: [ncgDumpAsmConflicts] :: NCGConfig -> !Bool
+ GHC.CmmToAsm.Config: [ncgDumpAsmConflicts] :: NCGConfig -> Bool
- GHC.CmmToAsm.Config: [ncgDumpAsmStats] :: NCGConfig -> !Bool
+ GHC.CmmToAsm.Config: [ncgDumpAsmStats] :: NCGConfig -> Bool
- GHC.CmmToAsm.Config: [ncgDumpRegAllocStages] :: NCGConfig -> !Bool
+ GHC.CmmToAsm.Config: [ncgDumpRegAllocStages] :: NCGConfig -> Bool
- GHC.CmmToAsm.Config: [ncgDwarfEnabled] :: NCGConfig -> !Bool
+ GHC.CmmToAsm.Config: [ncgDwarfEnabled] :: NCGConfig -> Bool
- GHC.CmmToAsm.Config: [ncgDwarfSourceNotes] :: NCGConfig -> !Bool
+ GHC.CmmToAsm.Config: [ncgDwarfSourceNotes] :: NCGConfig -> Bool
- GHC.CmmToAsm.Config: [ncgDwarfStripBlockInfo] :: NCGConfig -> !Bool
+ GHC.CmmToAsm.Config: [ncgDwarfStripBlockInfo] :: NCGConfig -> Bool
- GHC.CmmToAsm.Config: [ncgDwarfUnwindings] :: NCGConfig -> !Bool
+ GHC.CmmToAsm.Config: [ncgDwarfUnwindings] :: NCGConfig -> Bool
- GHC.CmmToAsm.Config: [ncgEnableDeadCodeElimination] :: NCGConfig -> !Bool
+ GHC.CmmToAsm.Config: [ncgEnableDeadCodeElimination] :: NCGConfig -> Bool
- GHC.CmmToAsm.Config: [ncgEnableInterModuleFarJumps] :: NCGConfig -> !Bool
+ GHC.CmmToAsm.Config: [ncgEnableInterModuleFarJumps] :: NCGConfig -> Bool
- GHC.CmmToAsm.Config: [ncgEnableShortcutting] :: NCGConfig -> !Bool
+ GHC.CmmToAsm.Config: [ncgEnableShortcutting] :: NCGConfig -> Bool
- GHC.CmmToAsm.Config: [ncgExposeInternalSymbols] :: NCGConfig -> !Bool
+ GHC.CmmToAsm.Config: [ncgExposeInternalSymbols] :: NCGConfig -> Bool
- GHC.CmmToAsm.Config: [ncgExternalDynamicRefs] :: NCGConfig -> !Bool
+ GHC.CmmToAsm.Config: [ncgExternalDynamicRefs] :: NCGConfig -> Bool
- GHC.CmmToAsm.Config: [ncgInlineThresholdMemcpy] :: NCGConfig -> !Word
+ GHC.CmmToAsm.Config: [ncgInlineThresholdMemcpy] :: NCGConfig -> Word
- GHC.CmmToAsm.Config: [ncgInlineThresholdMemset] :: NCGConfig -> !Word
+ GHC.CmmToAsm.Config: [ncgInlineThresholdMemset] :: NCGConfig -> Word
- GHC.CmmToAsm.Config: [ncgPIC] :: NCGConfig -> !Bool
+ GHC.CmmToAsm.Config: [ncgPIC] :: NCGConfig -> Bool
- GHC.CmmToAsm.Config: [ncgPlatform] :: NCGConfig -> !Platform
+ GHC.CmmToAsm.Config: [ncgPlatform] :: NCGConfig -> Platform
- GHC.CmmToAsm.Config: [ncgProcAlignment] :: NCGConfig -> !Maybe Int
+ GHC.CmmToAsm.Config: [ncgProcAlignment] :: NCGConfig -> Maybe Int
- GHC.CmmToAsm.Config: [ncgRegsGraph] :: NCGConfig -> !Bool
+ GHC.CmmToAsm.Config: [ncgRegsGraph] :: NCGConfig -> Bool
- GHC.CmmToAsm.Config: [ncgRegsIterative] :: NCGConfig -> !Bool
+ GHC.CmmToAsm.Config: [ncgRegsIterative] :: NCGConfig -> Bool
- GHC.CmmToAsm.Config: [ncgSplitSections] :: NCGConfig -> !Bool
+ GHC.CmmToAsm.Config: [ncgSplitSections] :: NCGConfig -> Bool
- GHC.CmmToAsm.Config: [ncgThisModule] :: NCGConfig -> !Module
+ GHC.CmmToAsm.Config: [ncgThisModule] :: NCGConfig -> Module
- GHC.CmmToAsm.Format: RegWithFormat :: {-# UNPACK #-} !Reg -> !Format -> RegWithFormat
+ GHC.CmmToAsm.Format: RegWithFormat :: Reg -> Format -> RegWithFormat
- GHC.CmmToAsm.Format: VecFormat :: !Length -> !ScalarFormat -> Format
+ GHC.CmmToAsm.Format: VecFormat :: Length -> ScalarFormat -> Format
- GHC.CmmToAsm.Format: VirtualRegWithFormat :: {-# UNPACK #-} !VirtualReg -> !Format -> VirtualRegWithFormat
+ GHC.CmmToAsm.Format: VirtualRegWithFormat :: VirtualReg -> Format -> VirtualRegWithFormat
- GHC.CmmToAsm.Format: [regWithFormat_format] :: RegWithFormat -> !Format
+ GHC.CmmToAsm.Format: [regWithFormat_format] :: RegWithFormat -> Format
- GHC.CmmToAsm.Format: [regWithFormat_reg] :: RegWithFormat -> {-# UNPACK #-} !Reg
+ GHC.CmmToAsm.Format: [regWithFormat_reg] :: RegWithFormat -> Reg
- GHC.CmmToAsm.Format: [virtualRegWithFormat_format] :: VirtualRegWithFormat -> !Format
+ GHC.CmmToAsm.Format: [virtualRegWithFormat_format] :: VirtualRegWithFormat -> Format
- GHC.CmmToAsm.Format: [virtualRegWithFormat_reg] :: VirtualRegWithFormat -> {-# UNPACK #-} !VirtualReg
+ GHC.CmmToAsm.Format: [virtualRegWithFormat_reg] :: VirtualRegWithFormat -> VirtualReg
- GHC.CmmToAsm.Monad: NcgImpl :: !NCGConfig -> (RawCmmDecl -> NatM [NatCmmDecl statics instr]) -> (instr -> Maybe (NatCmmDecl statics instr)) -> (jumpDest -> Maybe BlockId) -> (instr -> Maybe jumpDest) -> ((BlockId -> Maybe jumpDest) -> statics -> statics) -> ((BlockId -> Maybe jumpDest) -> instr -> instr) -> (NatCmmDecl statics instr -> SDoc) -> (NatCmmDecl statics instr -> HDoc) -> Int -> [RealReg] -> (Int -> NatCmmDecl statics instr -> UniqDSM (NatCmmDecl statics instr, [(BlockId, BlockId)])) -> (Platform -> LabelMap RawCmmStatics -> [NatBasicBlock instr] -> UniqDSM [NatBasicBlock instr]) -> ([instr] -> [UnwindPoint]) -> (Maybe CFG -> LabelMap RawCmmStatics -> [NatBasicBlock instr] -> [NatBasicBlock instr]) -> NcgImpl statics instr jumpDest
+ GHC.CmmToAsm.Monad: NcgImpl :: NCGConfig -> (RawCmmDecl -> NatM [NatCmmDecl statics instr]) -> (instr -> Maybe (NatCmmDecl statics instr)) -> (jumpDest -> Maybe BlockId) -> (instr -> Maybe jumpDest) -> ((BlockId -> Maybe jumpDest) -> statics -> statics) -> ((BlockId -> Maybe jumpDest) -> instr -> instr) -> (NatCmmDecl statics instr -> SDoc) -> (NatCmmDecl statics instr -> HDoc) -> Int -> [RealReg] -> (Int -> NatCmmDecl statics instr -> UniqDSM (NatCmmDecl statics instr, [(BlockId, BlockId)])) -> (Platform -> LabelMap RawCmmStatics -> [NatBasicBlock instr] -> UniqDSM [NatBasicBlock instr]) -> ([instr] -> [UnwindPoint]) -> (Maybe CFG -> LabelMap RawCmmStatics -> [NatBasicBlock instr] -> [NatBasicBlock instr]) -> NcgImpl statics instr jumpDest
- GHC.CmmToAsm.Monad: Reg64 :: !Reg -> !Reg -> Reg64
+ GHC.CmmToAsm.Monad: Reg64 :: Reg -> Reg -> Reg64
- GHC.CmmToAsm.Monad: RegCode64 :: code -> !Reg -> !Reg -> RegCode64 code
+ GHC.CmmToAsm.Monad: RegCode64 :: code -> Reg -> Reg -> RegCode64 code
- GHC.CmmToAsm.Monad: [ncgConfig] :: NcgImpl statics instr jumpDest -> !NCGConfig
+ GHC.CmmToAsm.Monad: [ncgConfig] :: NcgImpl statics instr jumpDest -> NCGConfig
- GHC.CmmToAsm.Reg.Graph.Stats: RegAllocStatsColored :: [LiveCmmDecl statics instr] -> Graph VirtualReg RegClass RealReg -> Graph VirtualReg RegClass RealReg -> UniqFM VirtualReg VirtualReg -> [LiveCmmDecl statics instr] -> [LiveCmmDecl statics instr] -> [LiveCmmDecl statics instr] -> [NatCmmDecl statics instr] -> (Int, Int, Int) -> !Platform -> RegAllocStats statics instr
+ GHC.CmmToAsm.Reg.Graph.Stats: RegAllocStatsColored :: [LiveCmmDecl statics instr] -> Graph VirtualReg RegClass RealReg -> Graph VirtualReg RegClass RealReg -> UniqFM VirtualReg VirtualReg -> [LiveCmmDecl statics instr] -> [LiveCmmDecl statics instr] -> [LiveCmmDecl statics instr] -> [NatCmmDecl statics instr] -> (Int, Int, Int) -> Platform -> RegAllocStats statics instr
- GHC.CmmToAsm.Reg.Graph.Stats: RegAllocStatsSpill :: [LiveCmmDecl statics instr] -> Graph VirtualReg RegClass RealReg -> UniqFM VirtualReg VirtualReg -> SpillStats -> SpillCostInfo -> [LiveCmmDecl statics instr] -> !Platform -> RegAllocStats statics instr
+ GHC.CmmToAsm.Reg.Graph.Stats: RegAllocStatsSpill :: [LiveCmmDecl statics instr] -> Graph VirtualReg RegClass RealReg -> UniqFM VirtualReg VirtualReg -> SpillStats -> SpillCostInfo -> [LiveCmmDecl statics instr] -> Platform -> RegAllocStats statics instr
- GHC.CmmToAsm.Reg.Graph.Stats: RegAllocStatsStart :: [LiveCmmDecl statics instr] -> Graph VirtualReg RegClass RealReg -> SpillCostInfo -> !Platform -> RegAllocStats statics instr
+ GHC.CmmToAsm.Reg.Graph.Stats: RegAllocStatsStart :: [LiveCmmDecl statics instr] -> Graph VirtualReg RegClass RealReg -> SpillCostInfo -> Platform -> RegAllocStats statics instr
- GHC.CmmToAsm.Reg.Graph.Stats: [raPlatform] :: RegAllocStats statics instr -> !Platform
+ GHC.CmmToAsm.Reg.Graph.Stats: [raPlatform] :: RegAllocStats statics instr -> Platform
- GHC.CmmToAsm.Reg.Linear.AArch64: FreeRegs :: !Word32 -> !Word32 -> FreeRegs
+ GHC.CmmToAsm.Reg.Linear.AArch64: FreeRegs :: Word32 -> Word32 -> FreeRegs
- GHC.CmmToAsm.Reg.Linear.Base: InBoth :: {-# UNPACK #-} !RealReg -> {-# UNPACK #-} !StackSlot -> VLoc
+ GHC.CmmToAsm.Reg.Linear.Base: InBoth :: RealRegUsage -> StackSlot -> Loc
- GHC.CmmToAsm.Reg.Linear.Base: InMem :: {-# UNPACK #-} !StackSlot -> VLoc
+ GHC.CmmToAsm.Reg.Linear.Base: InMem :: StackSlot -> Loc
- GHC.CmmToAsm.Reg.Linear.Base: InReg :: {-# UNPACK #-} !RealReg -> VLoc
+ GHC.CmmToAsm.Reg.Linear.Base: InReg :: RealRegUsage -> Loc
- GHC.CmmToAsm.Reg.Linear.Base: RA_State :: BlockAssignment freeRegs -> !freeRegs -> RegMap Loc -> Int -> StackMap -> DUniqSupply -> [SpillReason] -> !NCGConfig -> [(BlockId, BlockId, BlockId)] -> RA_State freeRegs
+ GHC.CmmToAsm.Reg.Linear.Base: RA_State :: BlockAssignment freeRegs -> freeRegs -> RegMap Loc -> Int -> StackMap -> DUniqSupply -> [SpillReason] -> NCGConfig -> [(BlockId, BlockId, BlockId)] -> RA_State freeRegs
- GHC.CmmToAsm.Reg.Linear.Base: RealRegUsage :: !RealReg -> !Format -> RealRegUsage
+ GHC.CmmToAsm.Reg.Linear.Base: RealRegUsage :: RealReg -> Format -> RealRegUsage
- GHC.CmmToAsm.Reg.Linear.Base: SpillAlloc :: !Unique -> SpillReason
+ GHC.CmmToAsm.Reg.Linear.Base: SpillAlloc :: Unique -> SpillReason
- GHC.CmmToAsm.Reg.Linear.Base: SpillClobber :: !Unique -> SpillReason
+ GHC.CmmToAsm.Reg.Linear.Base: SpillClobber :: Unique -> SpillReason
- GHC.CmmToAsm.Reg.Linear.Base: SpillJoinRM :: !Unique -> SpillReason
+ GHC.CmmToAsm.Reg.Linear.Base: SpillJoinRM :: Unique -> SpillReason
- GHC.CmmToAsm.Reg.Linear.Base: SpillJoinRR :: !Unique -> SpillReason
+ GHC.CmmToAsm.Reg.Linear.Base: SpillJoinRR :: Unique -> SpillReason
- GHC.CmmToAsm.Reg.Linear.Base: SpillLoad :: !Unique -> SpillReason
+ GHC.CmmToAsm.Reg.Linear.Base: SpillLoad :: Unique -> SpillReason
- GHC.CmmToAsm.Reg.Linear.Base: [ra_config] :: RA_State freeRegs -> !NCGConfig
+ GHC.CmmToAsm.Reg.Linear.Base: [ra_config] :: RA_State freeRegs -> NCGConfig
- GHC.CmmToAsm.Reg.Linear.Base: [ra_freeregs] :: RA_State freeRegs -> !freeRegs
+ GHC.CmmToAsm.Reg.Linear.Base: [ra_freeregs] :: RA_State freeRegs -> freeRegs
- GHC.CmmToAsm.Reg.Linear.Base: [realRegFormat] :: RealRegUsage -> !Format
+ GHC.CmmToAsm.Reg.Linear.Base: [realRegFormat] :: RealRegUsage -> Format
- GHC.CmmToAsm.Reg.Linear.Base: [realReg] :: RealRegUsage -> !RealReg
+ GHC.CmmToAsm.Reg.Linear.Base: [realReg] :: RealRegUsage -> RealReg
- GHC.CmmToAsm.Reg.Linear.Base: regsOfLoc :: VLoc -> [RealReg]
+ GHC.CmmToAsm.Reg.Linear.Base: regsOfLoc :: Loc -> [RealRegUsage]
- GHC.CmmToAsm.Reg.Linear.JoinToTargets: joinToTargets :: (FR freeRegs, Instruction instr) => BlockMap Regs -> BlockId -> instr -> RegM freeRegs ([NatBasicBlock instr], instr)
+ GHC.CmmToAsm.Reg.Linear.JoinToTargets: joinToTargets :: (FR freeRegs, Instruction instr) => BlockMap (UniqSet RegWithFormat) -> BlockId -> instr -> RegM freeRegs ([NatBasicBlock instr], instr)
- GHC.CmmToAsm.Reg.Linear.PPC: FreeRegs :: !Word32 -> !Word32 -> FreeRegs
+ GHC.CmmToAsm.Reg.Linear.PPC: FreeRegs :: Word32 -> Word32 -> FreeRegs
- GHC.CmmToAsm.Reg.Linear.RV64: FreeRegs :: !Word32 -> !Word32 -> FreeRegs
+ GHC.CmmToAsm.Reg.Linear.RV64: FreeRegs :: Word32 -> Word32 -> FreeRegs
- GHC.CmmToAsm.Reg.Linear.StackMap: StackMap :: !Int -> UniqFM Unique (StackSlot, Int) -> StackMap
+ GHC.CmmToAsm.Reg.Linear.StackMap: StackMap :: Int -> UniqFM Unique StackSlot -> StackMap
- GHC.CmmToAsm.Reg.Linear.StackMap: [stackMapAssignment] :: StackMap -> UniqFM Unique (StackSlot, Int)
+ GHC.CmmToAsm.Reg.Linear.StackMap: [stackMapAssignment] :: StackMap -> UniqFM Unique StackSlot
- GHC.CmmToAsm.Reg.Linear.StackMap: [stackMapNextFreeSlot] :: StackMap -> !Int
+ GHC.CmmToAsm.Reg.Linear.StackMap: [stackMapNextFreeSlot] :: StackMap -> Int
- GHC.CmmToAsm.Reg.Linear.State: RA_State :: BlockAssignment freeRegs -> !freeRegs -> RegMap Loc -> Int -> StackMap -> DUniqSupply -> [SpillReason] -> !NCGConfig -> [(BlockId, BlockId, BlockId)] -> RA_State freeRegs
+ GHC.CmmToAsm.Reg.Linear.State: RA_State :: BlockAssignment freeRegs -> freeRegs -> RegMap Loc -> Int -> StackMap -> DUniqSupply -> [SpillReason] -> NCGConfig -> [(BlockId, BlockId, BlockId)] -> RA_State freeRegs
- GHC.CmmToAsm.Reg.Linear.State: [ra_config] :: RA_State freeRegs -> !NCGConfig
+ GHC.CmmToAsm.Reg.Linear.State: [ra_config] :: RA_State freeRegs -> NCGConfig
- GHC.CmmToAsm.Reg.Linear.State: [ra_freeregs] :: RA_State freeRegs -> !freeRegs
+ GHC.CmmToAsm.Reg.Linear.State: [ra_freeregs] :: RA_State freeRegs -> freeRegs
- GHC.CmmToAsm.Reg.Liveness: Instr :: !instr -> InstrSR instr
+ GHC.CmmToAsm.Reg.Liveness: Instr :: instr -> InstrSR instr
- GHC.CmmToAsm.Reg.Liveness: LiveInfo :: LabelMap RawCmmStatics -> [BlockId] -> BlockMap Regs -> BlockMap IntSet -> LiveInfo
+ GHC.CmmToAsm.Reg.Liveness: LiveInfo :: LabelMap RawCmmStatics -> [BlockId] -> BlockMap (UniqSet RegWithFormat) -> BlockMap IntSet -> LiveInfo
- GHC.CmmToAsm.Reg.Liveness: Liveness :: Regs -> Regs -> Regs -> Liveness
+ GHC.CmmToAsm.Reg.Liveness: Liveness :: UniqSet RegWithFormat -> UniqSet RegWithFormat -> UniqSet RegWithFormat -> Liveness
- GHC.CmmToAsm.Reg.Liveness: RELOAD :: !Int -> !RegWithFormat -> InstrSR instr
+ GHC.CmmToAsm.Reg.Liveness: RELOAD :: Int -> RegWithFormat -> InstrSR instr
- GHC.CmmToAsm.Reg.Liveness: SPILL :: !RegWithFormat -> !Int -> InstrSR instr
+ GHC.CmmToAsm.Reg.Liveness: SPILL :: RegWithFormat -> Int -> InstrSR instr
- GHC.CmmToAsm.Reg.Liveness: [liveBorn] :: Liveness -> Regs
+ GHC.CmmToAsm.Reg.Liveness: [liveBorn] :: Liveness -> UniqSet RegWithFormat
- GHC.CmmToAsm.Reg.Liveness: [liveDieRead] :: Liveness -> Regs
+ GHC.CmmToAsm.Reg.Liveness: [liveDieRead] :: Liveness -> UniqSet RegWithFormat
- GHC.CmmToAsm.Reg.Liveness: [liveDieWrite] :: Liveness -> Regs
+ GHC.CmmToAsm.Reg.Liveness: [liveDieWrite] :: Liveness -> UniqSet RegWithFormat
- GHC.CmmToAsm.Reg.Liveness: slurpConflicts :: Instruction instr => Platform -> LiveCmmDecl statics instr -> (Bag Regs, Bag (Reg, Reg))
+ GHC.CmmToAsm.Reg.Liveness: slurpConflicts :: Instruction instr => Platform -> LiveCmmDecl statics instr -> (Bag (UniqSet RegWithFormat), Bag (Reg, Reg))
- GHC.CmmToAsm.Wasm.Types: WasmAsmConfig :: Bool -> Bool -> ~SymSet -> ~SymSet -> WasmAsmConfig
+ GHC.CmmToAsm.Wasm.Types: WasmAsmConfig :: Bool -> Bool -> SymSet -> SymSet -> WasmAsmConfig
- GHC.CmmToAsm.Wasm.Types: [mbrelSyms] :: WasmAsmConfig -> ~SymSet
+ GHC.CmmToAsm.Wasm.Types: [mbrelSyms] :: WasmAsmConfig -> SymSet
- GHC.CmmToAsm.Wasm.Types: [tbrelSyms] :: WasmAsmConfig -> ~SymSet
+ GHC.CmmToAsm.Wasm.Types: [tbrelSyms] :: WasmAsmConfig -> SymSet
- GHC.CmmToAsm.X86.Instr: FDIV :: Format -> Operand -> Operand -> Instr
+ GHC.CmmToAsm.X86.Instr: FDIV :: Format -> Operand -> Reg -> Instr
- GHC.CmmToAsm.X86.Instr: MINMAX :: MinOrMax -> MinMaxType -> Format -> Operand -> Operand -> Instr
+ GHC.CmmToAsm.X86.Instr: MINMAX :: MinOrMax -> MinMaxType -> Format -> Operand -> Reg -> Instr
- GHC.CmmToAsm.X86.Instr: PSLLDQ :: Format -> Operand -> Reg -> Instr
+ GHC.CmmToAsm.X86.Instr: PSLLDQ :: Format -> Imm -> Reg -> Instr
- GHC.CmmToAsm.X86.Instr: PSRLDQ :: Format -> Operand -> Reg -> Instr
+ GHC.CmmToAsm.X86.Instr: PSRLDQ :: Format -> Imm -> Reg -> Instr
- GHC.CmmToLlvm.Config: LlvmCgConfig :: !Platform -> !SDocContext -> !Bool -> !Bool -> !Bool -> Maybe BmiVersion -> Maybe LlvmVersion -> !Bool -> !String -> !LlvmConfig -> LlvmCgConfig
+ GHC.CmmToLlvm.Config: LlvmCgConfig :: Platform -> SDocContext -> Bool -> Bool -> Bool -> Maybe BmiVersion -> Maybe LlvmVersion -> Bool -> String -> LlvmConfig -> LlvmCgConfig
- GHC.CmmToLlvm.Config: [llvmCgAvxEnabled] :: LlvmCgConfig -> !Bool
+ GHC.CmmToLlvm.Config: [llvmCgAvxEnabled] :: LlvmCgConfig -> Bool
- GHC.CmmToLlvm.Config: [llvmCgContext] :: LlvmCgConfig -> !SDocContext
+ GHC.CmmToLlvm.Config: [llvmCgContext] :: LlvmCgConfig -> SDocContext
- GHC.CmmToLlvm.Config: [llvmCgDoWarn] :: LlvmCgConfig -> !Bool
+ GHC.CmmToLlvm.Config: [llvmCgDoWarn] :: LlvmCgConfig -> Bool
- GHC.CmmToLlvm.Config: [llvmCgFillUndefWithGarbage] :: LlvmCgConfig -> !Bool
+ GHC.CmmToLlvm.Config: [llvmCgFillUndefWithGarbage] :: LlvmCgConfig -> Bool
- GHC.CmmToLlvm.Config: [llvmCgLlvmConfig] :: LlvmCgConfig -> !LlvmConfig
+ GHC.CmmToLlvm.Config: [llvmCgLlvmConfig] :: LlvmCgConfig -> LlvmConfig
- GHC.CmmToLlvm.Config: [llvmCgLlvmTarget] :: LlvmCgConfig -> !String
+ GHC.CmmToLlvm.Config: [llvmCgLlvmTarget] :: LlvmCgConfig -> String
- GHC.CmmToLlvm.Config: [llvmCgPlatform] :: LlvmCgConfig -> !Platform
+ GHC.CmmToLlvm.Config: [llvmCgPlatform] :: LlvmCgConfig -> Platform
- GHC.CmmToLlvm.Config: [llvmCgSplitSection] :: LlvmCgConfig -> !Bool
+ GHC.CmmToLlvm.Config: [llvmCgSplitSection] :: LlvmCgConfig -> Bool
- GHC.Core: NotOrphan :: !OccName -> IsOrphan
+ GHC.Core: NotOrphan :: OccName -> IsOrphan
- GHC.Core: Rule :: RuleName -> Activation -> !Name -> [Maybe Name] -> [CoreBndr] -> [CoreExpr] -> CoreExpr -> Bool -> !Module -> !IsOrphan -> Bool -> CoreRule
+ GHC.Core: Rule :: RuleName -> Activation -> Name -> [Maybe Name] -> [CoreBndr] -> [CoreExpr] -> CoreExpr -> Bool -> Module -> IsOrphan -> Bool -> CoreRule
- GHC.Core: UnfoldingCache :: !Bool -> !Bool -> !Bool -> !Bool -> UnfoldingCache
+ GHC.Core: UnfoldingCache :: Bool -> Bool -> Bool -> Bool -> UnfoldingCache
- GHC.Core: [ru_origin] :: CoreRule -> !Module
+ GHC.Core: [ru_origin] :: CoreRule -> Module
- GHC.Core: [ru_orphan] :: CoreRule -> !IsOrphan
+ GHC.Core: [ru_orphan] :: CoreRule -> IsOrphan
- GHC.Core: [uf_expandable] :: UnfoldingCache -> !Bool
+ GHC.Core: [uf_expandable] :: UnfoldingCache -> Bool
- GHC.Core: [uf_is_conlike] :: UnfoldingCache -> !Bool
+ GHC.Core: [uf_is_conlike] :: UnfoldingCache -> Bool
- GHC.Core: [uf_is_value] :: UnfoldingCache -> !Bool
+ GHC.Core: [uf_is_value] :: UnfoldingCache -> Bool
- GHC.Core: [uf_is_work_free] :: UnfoldingCache -> !Bool
+ GHC.Core: [uf_is_work_free] :: UnfoldingCache -> Bool
- GHC.Core: ruleArity :: CoreRule -> Int
+ GHC.Core: ruleArity :: CoreRule -> FullArgCount
- GHC.Core.Class: type ClassMinimalDef = BooleanFormula Name
+ GHC.Core.Class: type ClassMinimalDef = BooleanFormula GhcRn
- GHC.Core.Coercion: CoercionHole :: CoVar -> IORef (Maybe Coercion) -> Bool -> CoercionHole
+ GHC.Core.Coercion: CoercionHole :: CoVar -> IORef (Maybe Coercion) -> CoercionHole
- GHC.Core.Coercion: liftCoSubstWithEx :: Role -> [TyVar] -> [Coercion] -> [TyCoVar] -> [Type] -> (Type -> Coercion, [Type])
+ GHC.Core.Coercion: liftCoSubstWithEx :: [TyVar] -> [Coercion] -> [TyCoVar] -> [Type] -> (Type -> CoercionR, [Type])
- GHC.Core.ConLike: conLikeUserTyVarBinders :: ConLike -> [InvisTVBinder]
+ GHC.Core.ConLike: conLikeUserTyVarBinders :: ConLike -> [TyVarBinder]
- GHC.Core.DataCon: DCR :: Id -> DataConBoxer -> [Scaled Type] -> [StrictnessMark] -> [HsImplBang] -> DataConRep
+ GHC.Core.DataCon: DCR :: Id -> DataConBoxer -> [Scaled Type] -> DataConRep
- GHC.Core.DataCon: HsSrcBang :: SourceText -> HsBang -> HsSrcBang
+ GHC.Core.DataCon: HsSrcBang :: SourceText -> SrcUnpackedness -> SrcStrictness -> HsSrcBang
- GHC.Core.DataCon: dataConUserTyVarBinders :: DataCon -> [InvisTVBinder]
+ GHC.Core.DataCon: dataConUserTyVarBinders :: DataCon -> [TyVarBinder]
- GHC.Core.DataCon: mkDataCon :: Name -> Bool -> TyConRepName -> [HsSrcBang] -> [FieldLabel] -> [TyVar] -> [TyCoVar] -> ConcreteTyVars -> [InvisTVBinder] -> [EqSpec] -> KnotTied ThetaType -> [KnotTied (Scaled Type)] -> KnotTied Type -> PromDataConInfo -> KnotTied TyCon -> ConTag -> ThetaType -> Id -> DataConRep -> DataCon
+ GHC.Core.DataCon: mkDataCon :: Name -> Bool -> TyConRepName -> [HsSrcBang] -> [HsImplBang] -> [StrictnessMark] -> [FieldLabel] -> [TyVar] -> [TyCoVar] -> ConcreteTyVars -> [TyVarBinder] -> [EqSpec] -> KnotTied ThetaType -> [KnotTied (Scaled Type)] -> KnotTied Type -> PromDataConInfo -> KnotTied TyCon -> ConTag -> ThetaType -> Id -> DataConRep -> DataCon
- GHC.Core.InstEnv: instanceBindFun :: BindFun
+ GHC.Core.InstEnv: instanceBindFun :: BindTvFun
- GHC.Core.LateCC.Types: LateCCConfig :: !LateCCBindSpec -> !Bool -> !LateCCEnv -> LateCCConfig
+ GHC.Core.LateCC.Types: LateCCConfig :: LateCCBindSpec -> Bool -> LateCCEnv -> LateCCConfig
- GHC.Core.LateCC.Types: LateCCEnv :: !Module -> Maybe FastString -> !Bool -> !Bool -> LateCCEnv
+ GHC.Core.LateCC.Types: LateCCEnv :: Module -> Maybe FastString -> Bool -> Bool -> LateCCEnv
- GHC.Core.LateCC.Types: LateCCState :: !Set CostCentre -> !CostCentreState -> !s -> LateCCState s
+ GHC.Core.LateCC.Types: LateCCState :: Set CostCentre -> CostCentreState -> s -> LateCCState s
- GHC.Core.LateCC.Types: [lateCCConfig_env] :: LateCCConfig -> !LateCCEnv
+ GHC.Core.LateCC.Types: [lateCCConfig_env] :: LateCCConfig -> LateCCEnv
- GHC.Core.LateCC.Types: [lateCCConfig_overloadedCalls] :: LateCCConfig -> !Bool
+ GHC.Core.LateCC.Types: [lateCCConfig_overloadedCalls] :: LateCCConfig -> Bool
- GHC.Core.LateCC.Types: [lateCCConfig_whichBinds] :: LateCCConfig -> !LateCCBindSpec
+ GHC.Core.LateCC.Types: [lateCCConfig_whichBinds] :: LateCCConfig -> LateCCBindSpec
- GHC.Core.LateCC.Types: [lateCCEnv_collectCCs] :: LateCCEnv -> !Bool
+ GHC.Core.LateCC.Types: [lateCCEnv_collectCCs] :: LateCCEnv -> Bool
- GHC.Core.LateCC.Types: [lateCCEnv_countEntries] :: LateCCEnv -> !Bool
+ GHC.Core.LateCC.Types: [lateCCEnv_countEntries] :: LateCCEnv -> Bool
- GHC.Core.LateCC.Types: [lateCCEnv_module] :: LateCCEnv -> !Module
+ GHC.Core.LateCC.Types: [lateCCEnv_module] :: LateCCEnv -> Module
- GHC.Core.LateCC.Types: [lateCCState_ccState] :: LateCCState s -> !CostCentreState
+ GHC.Core.LateCC.Types: [lateCCState_ccState] :: LateCCState s -> CostCentreState
- GHC.Core.LateCC.Types: [lateCCState_ccs] :: LateCCState s -> !Set CostCentre
+ GHC.Core.LateCC.Types: [lateCCState_ccs] :: LateCCState s -> Set CostCentre
- GHC.Core.LateCC.Types: [lateCCState_extra] :: LateCCState s -> !s
+ GHC.Core.LateCC.Types: [lateCCState_extra] :: LateCCState s -> s
- GHC.Core.Lint: EndPassConfig :: !Bool -> !Maybe LintPassResultConfig -> !NamePprCtx -> !Maybe DumpFlag -> !SDoc -> !SDoc -> EndPassConfig
+ GHC.Core.Lint: EndPassConfig :: Bool -> Maybe LintPassResultConfig -> NamePprCtx -> Maybe DumpFlag -> SDoc -> SDoc -> EndPassConfig
- GHC.Core.Lint: LintConfig :: !DiagOpts -> !Platform -> !LintFlags -> ![Var] -> LintConfig
+ GHC.Core.Lint: LintConfig :: DiagOpts -> Platform -> LintFlags -> [Var] -> LintConfig
- GHC.Core.Lint: LintPassResultConfig :: !DiagOpts -> !Platform -> !LintFlags -> !Bool -> !SDoc -> ![Var] -> LintPassResultConfig
+ GHC.Core.Lint: LintPassResultConfig :: DiagOpts -> Platform -> LintFlags -> Bool -> SDoc -> [Var] -> LintPassResultConfig
- GHC.Core.Lint: [ep_dumpCoreSizes] :: EndPassConfig -> !Bool
+ GHC.Core.Lint: [ep_dumpCoreSizes] :: EndPassConfig -> Bool
- GHC.Core.Lint: [ep_dumpFlag] :: EndPassConfig -> !Maybe DumpFlag
+ GHC.Core.Lint: [ep_dumpFlag] :: EndPassConfig -> Maybe DumpFlag
- GHC.Core.Lint: [ep_lintPassResult] :: EndPassConfig -> !Maybe LintPassResultConfig
+ GHC.Core.Lint: [ep_lintPassResult] :: EndPassConfig -> Maybe LintPassResultConfig
- GHC.Core.Lint: [ep_namePprCtx] :: EndPassConfig -> !NamePprCtx
+ GHC.Core.Lint: [ep_namePprCtx] :: EndPassConfig -> NamePprCtx
- GHC.Core.Lint: [ep_passDetails] :: EndPassConfig -> !SDoc
+ GHC.Core.Lint: [ep_passDetails] :: EndPassConfig -> SDoc
- GHC.Core.Lint: [ep_prettyPass] :: EndPassConfig -> !SDoc
+ GHC.Core.Lint: [ep_prettyPass] :: EndPassConfig -> SDoc
- GHC.Core.Lint: [l_diagOpts] :: LintConfig -> !DiagOpts
+ GHC.Core.Lint: [l_diagOpts] :: LintConfig -> DiagOpts
- GHC.Core.Lint: [l_flags] :: LintConfig -> !LintFlags
+ GHC.Core.Lint: [l_flags] :: LintConfig -> LintFlags
- GHC.Core.Lint: [l_platform] :: LintConfig -> !Platform
+ GHC.Core.Lint: [l_platform] :: LintConfig -> Platform
- GHC.Core.Lint: [l_vars] :: LintConfig -> ![Var]
+ GHC.Core.Lint: [l_vars] :: LintConfig -> [Var]
- GHC.Core.Lint: [lpr_diagOpts] :: LintPassResultConfig -> !DiagOpts
+ GHC.Core.Lint: [lpr_diagOpts] :: LintPassResultConfig -> DiagOpts
- GHC.Core.Lint: [lpr_localsInScope] :: LintPassResultConfig -> ![Var]
+ GHC.Core.Lint: [lpr_localsInScope] :: LintPassResultConfig -> [Var]
- GHC.Core.Lint: [lpr_makeLintFlags] :: LintPassResultConfig -> !LintFlags
+ GHC.Core.Lint: [lpr_makeLintFlags] :: LintPassResultConfig -> LintFlags
- GHC.Core.Lint: [lpr_passPpr] :: LintPassResultConfig -> !SDoc
+ GHC.Core.Lint: [lpr_passPpr] :: LintPassResultConfig -> SDoc
- GHC.Core.Lint: [lpr_platform] :: LintPassResultConfig -> !Platform
+ GHC.Core.Lint: [lpr_platform] :: LintPassResultConfig -> Platform
- GHC.Core.Lint: [lpr_showLintWarnings] :: LintPassResultConfig -> !Bool
+ GHC.Core.Lint: [lpr_showLintWarnings] :: LintPassResultConfig -> Bool
- GHC.Core.Make: MkStringIds :: !Id -> !Id -> MkStringIds
+ GHC.Core.Make: MkStringIds :: Id -> Id -> MkStringIds
- GHC.Core.Make: [unpackCStringId] :: MkStringIds -> !Id
+ GHC.Core.Make: [unpackCStringId] :: MkStringIds -> Id
- GHC.Core.Make: [unpackCStringUtf8Id] :: MkStringIds -> !Id
+ GHC.Core.Make: [unpackCStringUtf8Id] :: MkStringIds -> Id
- GHC.Core.Multiplicity: Scaled :: !Mult -> a -> Scaled a
+ GHC.Core.Multiplicity: Scaled :: Mult -> a -> Scaled a
- GHC.Core.Opt.Arity: ArityOpts :: !Bool -> !Bool -> ArityOpts
+ GHC.Core.Opt.Arity: ArityOpts :: Bool -> Bool -> ArityOpts
- GHC.Core.Opt.Arity: [ao_dicts_cheap] :: ArityOpts -> !Bool
+ GHC.Core.Opt.Arity: [ao_dicts_cheap] :: ArityOpts -> Bool
- GHC.Core.Opt.Arity: [ao_ped_bot] :: ArityOpts -> !Bool
+ GHC.Core.Opt.Arity: [ao_ped_bot] :: ArityOpts -> Bool
- GHC.Core.Opt.Arity: pushCoDataCon :: DataCon -> [CoreExpr] -> MCoercion -> Maybe (DataCon, [Type], [CoreExpr])
+ GHC.Core.Opt.Arity: pushCoDataCon :: DataCon -> [CoreExpr] -> MCoercionR -> Maybe (DataCon, [Type], [CoreExpr])
- GHC.Core.Opt.DmdAnal: DmdAnalOpts :: !Bool -> !Bool -> !Int -> !Int -> DmdAnalOpts
+ GHC.Core.Opt.DmdAnal: DmdAnalOpts :: Bool -> Bool -> Int -> Int -> DmdAnalOpts
- GHC.Core.Opt.DmdAnal: [dmd_do_boxity] :: DmdAnalOpts -> !Bool
+ GHC.Core.Opt.DmdAnal: [dmd_do_boxity] :: DmdAnalOpts -> Bool
- GHC.Core.Opt.DmdAnal: [dmd_max_worker_args] :: DmdAnalOpts -> !Int
+ GHC.Core.Opt.DmdAnal: [dmd_max_worker_args] :: DmdAnalOpts -> Int
- GHC.Core.Opt.DmdAnal: [dmd_strict_dicts] :: DmdAnalOpts -> !Bool
+ GHC.Core.Opt.DmdAnal: [dmd_strict_dicts] :: DmdAnalOpts -> Bool
- GHC.Core.Opt.DmdAnal: [dmd_unbox_width] :: DmdAnalOpts -> !Int
+ GHC.Core.Opt.DmdAnal: [dmd_unbox_width] :: DmdAnalOpts -> Int
- GHC.Core.Opt.LiberateCase: LibCaseOpts :: !Maybe Int -> !UnfoldingOpts -> LibCaseOpts
+ GHC.Core.Opt.LiberateCase: LibCaseOpts :: Maybe Int -> UnfoldingOpts -> LibCaseOpts
- GHC.Core.Opt.LiberateCase: [lco_threshold] :: LibCaseOpts -> !Maybe Int
+ GHC.Core.Opt.LiberateCase: [lco_threshold] :: LibCaseOpts -> Maybe Int
- GHC.Core.Opt.LiberateCase: [lco_unfolding_opts] :: LibCaseOpts -> !UnfoldingOpts
+ GHC.Core.Opt.LiberateCase: [lco_unfolding_opts] :: LibCaseOpts -> UnfoldingOpts
- GHC.Core.Opt.Pipeline.Types: CoreDoSimplify :: !SimplifyOpts -> CoreToDo
+ GHC.Core.Opt.Pipeline.Types: CoreDoSimplify :: SimplifyOpts -> CoreToDo
- GHC.Core.Opt.Simplify: SimplifyExprOpts :: ![FamInst] -> !SimplMode -> !TopEnvConfig -> SimplifyExprOpts
+ GHC.Core.Opt.Simplify: SimplifyExprOpts :: [FamInst] -> SimplMode -> TopEnvConfig -> SimplifyExprOpts
- GHC.Core.Opt.Simplify: SimplifyOpts :: !Bool -> !Int -> !SimplMode -> !Maybe LintPassResultConfig -> !RuleBase -> !TopEnvConfig -> SimplifyOpts
+ GHC.Core.Opt.Simplify: SimplifyOpts :: Bool -> Int -> SimplMode -> Maybe LintPassResultConfig -> RuleBase -> TopEnvConfig -> SimplifyOpts
- GHC.Core.Opt.Simplify: [se_fam_inst] :: SimplifyExprOpts -> ![FamInst]
+ GHC.Core.Opt.Simplify: [se_fam_inst] :: SimplifyExprOpts -> [FamInst]
- GHC.Core.Opt.Simplify: [se_mode] :: SimplifyExprOpts -> !SimplMode
+ GHC.Core.Opt.Simplify: [se_mode] :: SimplifyExprOpts -> SimplMode
- GHC.Core.Opt.Simplify: [se_top_env_cfg] :: SimplifyExprOpts -> !TopEnvConfig
+ GHC.Core.Opt.Simplify: [se_top_env_cfg] :: SimplifyExprOpts -> TopEnvConfig
- GHC.Core.Opt.Simplify: [so_dump_core_sizes] :: SimplifyOpts -> !Bool
+ GHC.Core.Opt.Simplify: [so_dump_core_sizes] :: SimplifyOpts -> Bool
- GHC.Core.Opt.Simplify: [so_hpt_rules] :: SimplifyOpts -> !RuleBase
+ GHC.Core.Opt.Simplify: [so_hpt_rules] :: SimplifyOpts -> RuleBase
- GHC.Core.Opt.Simplify: [so_iterations] :: SimplifyOpts -> !Int
+ GHC.Core.Opt.Simplify: [so_iterations] :: SimplifyOpts -> Int
- GHC.Core.Opt.Simplify: [so_mode] :: SimplifyOpts -> !SimplMode
+ GHC.Core.Opt.Simplify: [so_mode] :: SimplifyOpts -> SimplMode
- GHC.Core.Opt.Simplify: [so_pass_result_cfg] :: SimplifyOpts -> !Maybe LintPassResultConfig
+ GHC.Core.Opt.Simplify: [so_pass_result_cfg] :: SimplifyOpts -> Maybe LintPassResultConfig
- GHC.Core.Opt.Simplify: [so_top_env_cfg] :: SimplifyOpts -> !TopEnvConfig
+ GHC.Core.Opt.Simplify: [so_top_env_cfg] :: SimplifyOpts -> TopEnvConfig
- GHC.Core.Opt.Simplify.Env: SimplEnv :: !SimplMode -> !(FamInstEnv, FamInstEnv) -> TvSubstEnv -> CvSubstEnv -> SimplIdSubst -> !UnVarSet -> !InScopeSet -> !Int -> !Int -> SimplEnv
+ GHC.Core.Opt.Simplify.Env: SimplEnv :: SimplMode -> (FamInstEnv, FamInstEnv) -> TvSubstEnv -> CvSubstEnv -> SimplIdSubst -> UnVarSet -> InScopeSet -> Int -> Int -> SimplEnv
- GHC.Core.Opt.Simplify.Env: SimplMode :: !CompilerPhase -> ![String] -> !Bool -> !Bool -> !Bool -> !Bool -> !UnfoldingOpts -> !Bool -> !Bool -> !FloatEnable -> !Bool -> !ArityOpts -> !RuleOpts -> !Bool -> !Bool -> !OptCoercionOpts -> SimplMode
+ GHC.Core.Opt.Simplify.Env: SimplMode :: CompilerPhase -> [String] -> Bool -> Bool -> Bool -> Bool -> UnfoldingOpts -> Bool -> Bool -> FloatEnable -> Bool -> ArityOpts -> RuleOpts -> Bool -> Bool -> OptCoercionOpts -> SimplMode
- GHC.Core.Opt.Simplify.Env: [seCaseDepth] :: SimplEnv -> !Int
+ GHC.Core.Opt.Simplify.Env: [seCaseDepth] :: SimplEnv -> Int
- GHC.Core.Opt.Simplify.Env: [seFamEnvs] :: SimplEnv -> !(FamInstEnv, FamInstEnv)
+ GHC.Core.Opt.Simplify.Env: [seFamEnvs] :: SimplEnv -> (FamInstEnv, FamInstEnv)
- GHC.Core.Opt.Simplify.Env: [seInScope] :: SimplEnv -> !InScopeSet
+ GHC.Core.Opt.Simplify.Env: [seInScope] :: SimplEnv -> InScopeSet
- GHC.Core.Opt.Simplify.Env: [seInlineDepth] :: SimplEnv -> !Int
+ GHC.Core.Opt.Simplify.Env: [seInlineDepth] :: SimplEnv -> Int
- GHC.Core.Opt.Simplify.Env: [seMode] :: SimplEnv -> !SimplMode
+ GHC.Core.Opt.Simplify.Env: [seMode] :: SimplEnv -> SimplMode
- GHC.Core.Opt.Simplify.Env: [seRecIds] :: SimplEnv -> !UnVarSet
+ GHC.Core.Opt.Simplify.Env: [seRecIds] :: SimplEnv -> UnVarSet
- GHC.Core.Opt.Simplify.Env: [sm_arity_opts] :: SimplMode -> !ArityOpts
+ GHC.Core.Opt.Simplify.Env: [sm_arity_opts] :: SimplMode -> ArityOpts
- GHC.Core.Opt.Simplify.Env: [sm_case_case] :: SimplMode -> !Bool
+ GHC.Core.Opt.Simplify.Env: [sm_case_case] :: SimplMode -> Bool
- GHC.Core.Opt.Simplify.Env: [sm_case_folding] :: SimplMode -> !Bool
+ GHC.Core.Opt.Simplify.Env: [sm_case_folding] :: SimplMode -> Bool
- GHC.Core.Opt.Simplify.Env: [sm_case_merge] :: SimplMode -> !Bool
+ GHC.Core.Opt.Simplify.Env: [sm_case_merge] :: SimplMode -> Bool
- GHC.Core.Opt.Simplify.Env: [sm_cast_swizzle] :: SimplMode -> !Bool
+ GHC.Core.Opt.Simplify.Env: [sm_cast_swizzle] :: SimplMode -> Bool
- GHC.Core.Opt.Simplify.Env: [sm_co_opt_opts] :: SimplMode -> !OptCoercionOpts
+ GHC.Core.Opt.Simplify.Env: [sm_co_opt_opts] :: SimplMode -> OptCoercionOpts
- GHC.Core.Opt.Simplify.Env: [sm_do_eta_reduction] :: SimplMode -> !Bool
+ GHC.Core.Opt.Simplify.Env: [sm_do_eta_reduction] :: SimplMode -> Bool
- GHC.Core.Opt.Simplify.Env: [sm_eta_expand] :: SimplMode -> !Bool
+ GHC.Core.Opt.Simplify.Env: [sm_eta_expand] :: SimplMode -> Bool
- GHC.Core.Opt.Simplify.Env: [sm_float_enable] :: SimplMode -> !FloatEnable
+ GHC.Core.Opt.Simplify.Env: [sm_float_enable] :: SimplMode -> FloatEnable
- GHC.Core.Opt.Simplify.Env: [sm_inline] :: SimplMode -> !Bool
+ GHC.Core.Opt.Simplify.Env: [sm_inline] :: SimplMode -> Bool
- GHC.Core.Opt.Simplify.Env: [sm_names] :: SimplMode -> ![String]
+ GHC.Core.Opt.Simplify.Env: [sm_names] :: SimplMode -> [String]
- GHC.Core.Opt.Simplify.Env: [sm_phase] :: SimplMode -> !CompilerPhase
+ GHC.Core.Opt.Simplify.Env: [sm_phase] :: SimplMode -> CompilerPhase
- GHC.Core.Opt.Simplify.Env: [sm_pre_inline] :: SimplMode -> !Bool
+ GHC.Core.Opt.Simplify.Env: [sm_pre_inline] :: SimplMode -> Bool
- GHC.Core.Opt.Simplify.Env: [sm_rule_opts] :: SimplMode -> !RuleOpts
+ GHC.Core.Opt.Simplify.Env: [sm_rule_opts] :: SimplMode -> RuleOpts
- GHC.Core.Opt.Simplify.Env: [sm_rules] :: SimplMode -> !Bool
+ GHC.Core.Opt.Simplify.Env: [sm_rules] :: SimplMode -> Bool
- GHC.Core.Opt.Simplify.Env: [sm_uf_opts] :: SimplMode -> !UnfoldingOpts
+ GHC.Core.Opt.Simplify.Env: [sm_uf_opts] :: SimplMode -> UnfoldingOpts
- GHC.Core.Opt.Simplify.Monad: TopEnvConfig :: !Int -> !Int -> TopEnvConfig
+ GHC.Core.Opt.Simplify.Monad: TopEnvConfig :: Int -> Int -> TopEnvConfig
- GHC.Core.Opt.Simplify.Monad: [te_history_size] :: TopEnvConfig -> !Int
+ GHC.Core.Opt.Simplify.Monad: [te_history_size] :: TopEnvConfig -> Int
- GHC.Core.Opt.Simplify.Monad: [te_tick_factor] :: TopEnvConfig -> !Int
+ GHC.Core.Opt.Simplify.Monad: [te_tick_factor] :: TopEnvConfig -> Int
- GHC.Core.Opt.Simplify.Utils: ArgInfo :: OutId -> [ArgSpec] -> RewriteCall -> Bool -> [Demand] -> [Int] -> ArgInfo
+ GHC.Core.Opt.Simplify.Utils: ArgInfo :: OutId -> [ArgSpec] -> [CoreRule] -> Bool -> [Demand] -> [Int] -> ArgInfo
- GHC.Core.Opt.Simplify.Utils: mkArgInfo :: SimplEnv -> RuleEnv -> Id -> SimplCont -> ArgInfo
+ GHC.Core.Opt.Simplify.Utils: mkArgInfo :: SimplEnv -> Id -> [CoreRule] -> SimplCont -> ArgInfo
- GHC.Core.Opt.WorkWrap: MkWwOpts :: !FamInstEnvs -> !SimpleOpts -> !Bool -> !Module -> !Bool -> WwOpts
+ GHC.Core.Opt.WorkWrap: MkWwOpts :: FamInstEnvs -> SimpleOpts -> Bool -> Module -> Bool -> WwOpts
- GHC.Core.Opt.WorkWrap: [wo_cpr_anal] :: WwOpts -> !Bool
+ GHC.Core.Opt.WorkWrap: [wo_cpr_anal] :: WwOpts -> Bool
- GHC.Core.Opt.WorkWrap: [wo_fam_envs] :: WwOpts -> !FamInstEnvs
+ GHC.Core.Opt.WorkWrap: [wo_fam_envs] :: WwOpts -> FamInstEnvs
- GHC.Core.Opt.WorkWrap: [wo_module] :: WwOpts -> !Module
+ GHC.Core.Opt.WorkWrap: [wo_module] :: WwOpts -> Module
- GHC.Core.Opt.WorkWrap: [wo_simple_opts] :: WwOpts -> !SimpleOpts
+ GHC.Core.Opt.WorkWrap: [wo_simple_opts] :: WwOpts -> SimpleOpts
- GHC.Core.Opt.WorkWrap: [wo_unlift_strict] :: WwOpts -> !Bool
+ GHC.Core.Opt.WorkWrap: [wo_unlift_strict] :: WwOpts -> Bool
- GHC.Core.Opt.WorkWrap.Utils: DataConPatContext :: !DataCon -> ![Type] -> !Coercion -> ![s] -> DataConPatContext s
+ GHC.Core.Opt.WorkWrap.Utils: DataConPatContext :: DataCon -> [Type] -> Coercion -> [s] -> DataConPatContext s
- GHC.Core.Opt.WorkWrap.Utils: DoUnbox :: !unboxing_info -> UnboxingDecision unboxing_info
+ GHC.Core.Opt.WorkWrap.Utils: DoUnbox :: unboxing_info -> UnboxingDecision unboxing_info
- GHC.Core.Opt.WorkWrap.Utils: MkWwOpts :: !FamInstEnvs -> !SimpleOpts -> !Bool -> !Module -> !Bool -> WwOpts
+ GHC.Core.Opt.WorkWrap.Utils: MkWwOpts :: FamInstEnvs -> SimpleOpts -> Bool -> Module -> Bool -> WwOpts
- GHC.Core.Opt.WorkWrap.Utils: [dcpc_args] :: DataConPatContext s -> ![s]
+ GHC.Core.Opt.WorkWrap.Utils: [dcpc_args] :: DataConPatContext s -> [s]
- GHC.Core.Opt.WorkWrap.Utils: [dcpc_co] :: DataConPatContext s -> !Coercion
+ GHC.Core.Opt.WorkWrap.Utils: [dcpc_co] :: DataConPatContext s -> Coercion
- GHC.Core.Opt.WorkWrap.Utils: [dcpc_dc] :: DataConPatContext s -> !DataCon
+ GHC.Core.Opt.WorkWrap.Utils: [dcpc_dc] :: DataConPatContext s -> DataCon
- GHC.Core.Opt.WorkWrap.Utils: [dcpc_tc_args] :: DataConPatContext s -> ![Type]
+ GHC.Core.Opt.WorkWrap.Utils: [dcpc_tc_args] :: DataConPatContext s -> [Type]
- GHC.Core.Opt.WorkWrap.Utils: [wo_cpr_anal] :: WwOpts -> !Bool
+ GHC.Core.Opt.WorkWrap.Utils: [wo_cpr_anal] :: WwOpts -> Bool
- GHC.Core.Opt.WorkWrap.Utils: [wo_fam_envs] :: WwOpts -> !FamInstEnvs
+ GHC.Core.Opt.WorkWrap.Utils: [wo_fam_envs] :: WwOpts -> FamInstEnvs
- GHC.Core.Opt.WorkWrap.Utils: [wo_module] :: WwOpts -> !Module
+ GHC.Core.Opt.WorkWrap.Utils: [wo_module] :: WwOpts -> Module
- GHC.Core.Opt.WorkWrap.Utils: [wo_simple_opts] :: WwOpts -> !SimpleOpts
+ GHC.Core.Opt.WorkWrap.Utils: [wo_simple_opts] :: WwOpts -> SimpleOpts
- GHC.Core.Opt.WorkWrap.Utils: [wo_unlift_strict] :: WwOpts -> !Bool
+ GHC.Core.Opt.WorkWrap.Utils: [wo_unlift_strict] :: WwOpts -> Bool
- GHC.Core.Predicate: classifyPredType :: PredType -> Pred
+ GHC.Core.Predicate: classifyPredType :: HasDebugCallStack => PredType -> Pred
- GHC.Core.Predicate: isPredTy :: HasDebugCallStack => Type -> Bool
+ GHC.Core.Predicate: isPredTy :: Type -> Bool
- GHC.Core.Predicate: typeDeterminesValue :: Type -> Bool
+ GHC.Core.Predicate: typeDeterminesValue :: PredType -> Bool
- GHC.Core.Reduction: ArgsReductions :: {-# UNPACK #-} !Reductions -> !MCoercionN -> ArgsReductions
+ GHC.Core.Reduction: ArgsReductions :: Reductions -> MCoercionN -> ArgsReductions
- GHC.Core.Reduction: Reduction :: Coercion -> !Type -> Reduction
+ GHC.Core.Reduction: Reduction :: Coercion -> Type -> Reduction
- GHC.Core.Reduction: [reductionReducedType] :: Reduction -> !Type
+ GHC.Core.Reduction: [reductionReducedType] :: Reduction -> Type
- GHC.Core.Rules: RuleEnv :: !RuleBase -> !RuleBase -> !RuleBase -> !ModuleSet -> RuleEnv
+ GHC.Core.Rules: RuleEnv :: RuleBase -> RuleBase -> RuleBase -> ModuleSet -> RuleEnv
- GHC.Core.Rules: [re_eps_rules] :: RuleEnv -> !RuleBase
+ GHC.Core.Rules: [re_eps_rules] :: RuleEnv -> RuleBase
- GHC.Core.Rules: [re_home_rules] :: RuleEnv -> !RuleBase
+ GHC.Core.Rules: [re_home_rules] :: RuleEnv -> RuleBase
- GHC.Core.Rules: [re_local_rules] :: RuleEnv -> !RuleBase
+ GHC.Core.Rules: [re_local_rules] :: RuleEnv -> RuleBase
- GHC.Core.Rules: [re_visible_orphs] :: RuleEnv -> !ModuleSet
+ GHC.Core.Rules: [re_visible_orphs] :: RuleEnv -> ModuleSet
- GHC.Core.Rules: lookupRule :: RuleOpts -> InScopeEnv -> (Activation -> Bool) -> Id -> [CoreExpr] -> [CoreRule] -> Maybe (CoreRule, CoreExpr)
+ GHC.Core.Rules: lookupRule :: HasDebugCallStack => RuleOpts -> InScopeEnv -> (Activation -> Bool) -> Id -> [CoreExpr] -> [CoreRule] -> Maybe (CoreRule, CoreExpr)
- GHC.Core.Rules: matchExprs :: InScopeEnv -> [Var] -> [CoreExpr] -> [CoreExpr] -> Maybe (BindWrapper, [CoreExpr])
+ GHC.Core.Rules: matchExprs :: HasDebugCallStack => InScopeEnv -> [Var] -> [CoreExpr] -> [CoreExpr] -> Maybe (BindWrapper, [CoreExpr])
- GHC.Core.Rules.Config: RuleOpts :: !Platform -> !Bool -> !Bool -> !Bool -> RuleOpts
+ GHC.Core.Rules.Config: RuleOpts :: Platform -> Bool -> Bool -> Bool -> RuleOpts
- GHC.Core.Rules.Config: [roBignumRules] :: RuleOpts -> !Bool
+ GHC.Core.Rules.Config: [roBignumRules] :: RuleOpts -> Bool
- GHC.Core.Rules.Config: [roExcessRationalPrecision] :: RuleOpts -> !Bool
+ GHC.Core.Rules.Config: [roExcessRationalPrecision] :: RuleOpts -> Bool
- GHC.Core.Rules.Config: [roNumConstantFolding] :: RuleOpts -> !Bool
+ GHC.Core.Rules.Config: [roNumConstantFolding] :: RuleOpts -> Bool
- GHC.Core.Rules.Config: [roPlatform] :: RuleOpts -> !Platform
+ GHC.Core.Rules.Config: [roPlatform] :: RuleOpts -> Platform
- GHC.Core.SimpleOpt: SimpleOpts :: !UnfoldingOpts -> !OptCoercionOpts -> !Bool -> SimpleOpts
+ GHC.Core.SimpleOpt: SimpleOpts :: UnfoldingOpts -> OptCoercionOpts -> Bool -> Bool -> SimpleOpts
- GHC.Core.SimpleOpt: [so_co_opts] :: SimpleOpts -> !OptCoercionOpts
+ GHC.Core.SimpleOpt: [so_co_opts] :: SimpleOpts -> OptCoercionOpts
- GHC.Core.SimpleOpt: [so_eta_red] :: SimpleOpts -> !Bool
+ GHC.Core.SimpleOpt: [so_eta_red] :: SimpleOpts -> Bool
- GHC.Core.SimpleOpt: [so_uf_opts] :: SimpleOpts -> !UnfoldingOpts
+ GHC.Core.SimpleOpt: [so_uf_opts] :: SimpleOpts -> UnfoldingOpts
- GHC.Core.Stats: CS :: !Int -> !Int -> !Int -> !Int -> !Int -> CoreStats
+ GHC.Core.Stats: CS :: Int -> Int -> Int -> Int -> Int -> CoreStats
- GHC.Core.Stats: [cs_co] :: CoreStats -> !Int
+ GHC.Core.Stats: [cs_co] :: CoreStats -> Int
- GHC.Core.Stats: [cs_jb] :: CoreStats -> !Int
+ GHC.Core.Stats: [cs_jb] :: CoreStats -> Int
- GHC.Core.Stats: [cs_tm] :: CoreStats -> !Int
+ GHC.Core.Stats: [cs_tm] :: CoreStats -> Int
- GHC.Core.Stats: [cs_ty] :: CoreStats -> !Int
+ GHC.Core.Stats: [cs_ty] :: CoreStats -> Int
- GHC.Core.Stats: [cs_vb] :: CoreStats -> !Int
+ GHC.Core.Stats: [cs_vb] :: CoreStats -> Int
- GHC.Core.Subst: cloneBndrs :: MonadUnique m => Subst -> [Var] -> m (Subst, [Var])
+ GHC.Core.Subst: cloneBndrs :: Subst -> UniqSupply -> [Var] -> (Subst, [Var])
- GHC.Core.Subst: cloneRecIdBndrs :: MonadUnique m => Subst -> [Id] -> m (Subst, [Id])
+ GHC.Core.Subst: cloneRecIdBndrs :: Subst -> UniqSupply -> [Id] -> (Subst, [Id])
- GHC.Core.Subst: extendSubst :: Subst -> Var -> CoreArg -> Subst
+ GHC.Core.Subst: extendSubst :: HasDebugCallStack => Subst -> Var -> CoreArg -> Subst
- GHC.Core.TyCo.Rep: CoercionHole :: CoVar -> IORef (Maybe Coercion) -> Bool -> CoercionHole
+ GHC.Core.TyCo.Rep: CoercionHole :: CoVar -> IORef (Maybe Coercion) -> CoercionHole
- GHC.Core.TyCo.Rep: ForAllCo :: TyCoVar -> !ForAllTyFlag -> !ForAllTyFlag -> KindCoercion -> Coercion -> Coercion
+ GHC.Core.TyCo.Rep: ForAllCo :: TyCoVar -> ForAllTyFlag -> ForAllTyFlag -> KindCoercion -> Coercion -> Coercion
- GHC.Core.TyCo.Rep: ForAllTy :: {-# UNPACK #-} !ForAllTyBinder -> Type -> Type
+ GHC.Core.TyCo.Rep: ForAllTy :: ForAllTyBinder -> Type -> Type
- GHC.Core.TyCo.Rep: Invisible :: !Specificity -> ForAllTyFlag
+ GHC.Core.TyCo.Rep: Invisible :: Specificity -> ForAllTyFlag
- GHC.Core.TyCo.Rep: Scaled :: !Mult -> a -> Scaled a
+ GHC.Core.TyCo.Rep: Scaled :: Mult -> a -> Scaled a
- GHC.Core.TyCo.Rep: [fco_visL] :: Coercion -> !ForAllTyFlag
+ GHC.Core.TyCo.Rep: [fco_visL] :: Coercion -> ForAllTyFlag
- GHC.Core.TyCo.Rep: [fco_visR] :: Coercion -> !ForAllTyFlag
+ GHC.Core.TyCo.Rep: [fco_visR] :: Coercion -> ForAllTyFlag
- GHC.Core.TyCo.Subst: substForAllCoBndrUsing :: SwapFlag -> (Coercion -> Coercion) -> Subst -> TyCoVar -> KindCoercion -> (Subst, TyCoVar, KindCoercion)
+ GHC.Core.TyCo.Subst: substForAllCoBndrUsing :: (Coercion -> Coercion) -> Subst -> TyCoVar -> KindCoercion -> (Subst, TyCoVar, KindCoercion)
- GHC.Core.TyCon: BoxedRep :: {-# UNPACK #-} !Maybe Levity -> PrimRep
+ GHC.Core.TyCon: BoxedRep :: Maybe Levity -> PrimRep
- GHC.Core.TyCon: tyConBinderForAllTyFlag :: TyConBinder -> ForAllTyFlag
+ GHC.Core.TyCon: tyConBinderForAllTyFlag :: VarBndr a TyConBndrVis -> ForAllTyFlag
- GHC.Core.Type: Invisible :: !Specificity -> ForAllTyFlag
+ GHC.Core.Type: Invisible :: Specificity -> ForAllTyFlag
- GHC.Core.Unfold: SizeIs :: {-# UNPACK #-} !Int -> !Bag (Id, Int) -> {-# UNPACK #-} !Int -> ExprSize
+ GHC.Core.Unfold: SizeIs :: Int -> Bag (Id, Int) -> Int -> ExprSize
- GHC.Core.Unfold: UnfoldingOpts :: !Int -> !Int -> !Int -> !Int -> !Bool -> !Int -> !Int -> !Maybe String -> UnfoldingOpts
+ GHC.Core.Unfold: UnfoldingOpts :: Int -> Int -> Int -> Int -> Bool -> Int -> Int -> Maybe String -> UnfoldingOpts
- GHC.Core.Unfold: [_es_args] :: ExprSize -> !Bag (Id, Int)
+ GHC.Core.Unfold: [_es_args] :: ExprSize -> Bag (Id, Int)
- GHC.Core.Unfold: [_es_discount] :: ExprSize -> {-# UNPACK #-} !Int
+ GHC.Core.Unfold: [_es_discount] :: ExprSize -> Int
- GHC.Core.Unfold: [_es_size_is] :: ExprSize -> {-# UNPACK #-} !Int
+ GHC.Core.Unfold: [_es_size_is] :: ExprSize -> Int
- GHC.Core.Unfold: [unfoldingCaseScaling] :: UnfoldingOpts -> !Int
+ GHC.Core.Unfold: [unfoldingCaseScaling] :: UnfoldingOpts -> Int
- GHC.Core.Unfold: [unfoldingCaseThreshold] :: UnfoldingOpts -> !Int
+ GHC.Core.Unfold: [unfoldingCaseThreshold] :: UnfoldingOpts -> Int
- GHC.Core.Unfold: [unfoldingCreationThreshold] :: UnfoldingOpts -> !Int
+ GHC.Core.Unfold: [unfoldingCreationThreshold] :: UnfoldingOpts -> Int
- GHC.Core.Unfold: [unfoldingDictDiscount] :: UnfoldingOpts -> !Int
+ GHC.Core.Unfold: [unfoldingDictDiscount] :: UnfoldingOpts -> Int
- GHC.Core.Unfold: [unfoldingFunAppDiscount] :: UnfoldingOpts -> !Int
+ GHC.Core.Unfold: [unfoldingFunAppDiscount] :: UnfoldingOpts -> Int
- GHC.Core.Unfold: [unfoldingReportPrefix] :: UnfoldingOpts -> !Maybe String
+ GHC.Core.Unfold: [unfoldingReportPrefix] :: UnfoldingOpts -> Maybe String
- GHC.Core.Unfold: [unfoldingUseThreshold] :: UnfoldingOpts -> !Int
+ GHC.Core.Unfold: [unfoldingUseThreshold] :: UnfoldingOpts -> Int
- GHC.Core.Unfold: [unfoldingVeryAggressive] :: UnfoldingOpts -> !Bool
+ GHC.Core.Unfold: [unfoldingVeryAggressive] :: UnfoldingOpts -> Bool
- GHC.Core.Unify: tcMatchTy :: Type -> Type -> Maybe Subst
+ GHC.Core.Unify: tcMatchTy :: HasDebugCallStack => Type -> Type -> Maybe Subst
- GHC.Core.Unify: tcMatchTyKi :: Type -> Type -> Maybe Subst
+ GHC.Core.Unify: tcMatchTyKi :: HasDebugCallStack => Type -> Type -> Maybe Subst
- GHC.Core.Unify: tcMatchTyKis :: [Type] -> [Type] -> Maybe Subst
+ GHC.Core.Unify: tcMatchTyKis :: HasDebugCallStack => [Type] -> [Type] -> Maybe Subst
- GHC.Core.Unify: tcMatchTyKisX :: Subst -> [Type] -> [Type] -> Maybe Subst
+ GHC.Core.Unify: tcMatchTyKisX :: HasDebugCallStack => Subst -> [Type] -> [Type] -> Maybe Subst
- GHC.Core.Unify: tcMatchTyX :: Subst -> Type -> Type -> Maybe Subst
+ GHC.Core.Unify: tcMatchTyX :: HasDebugCallStack => Subst -> Type -> Type -> Maybe Subst
- GHC.Core.Unify: tcMatchTyX_BM :: BindFun -> Subst -> Type -> Type -> Maybe Subst
+ GHC.Core.Unify: tcMatchTyX_BM :: HasDebugCallStack => BindTvFun -> Subst -> Type -> Type -> Maybe Subst
- GHC.Core.Unify: tcMatchTys :: [Type] -> [Type] -> Maybe Subst
+ GHC.Core.Unify: tcMatchTys :: HasDebugCallStack => [Type] -> [Type] -> Maybe Subst
- GHC.Core.Unify: tcMatchTysX :: Subst -> [Type] -> [Type] -> Maybe Subst
+ GHC.Core.Unify: tcMatchTysX :: HasDebugCallStack => Subst -> [Type] -> [Type] -> Maybe Subst
- GHC.Core.Unify: tcUnifyTys :: BindFun -> [Type] -> [Type] -> Maybe Subst
+ GHC.Core.Unify: tcUnifyTys :: BindTvFun -> [Type] -> [Type] -> Maybe Subst
- GHC.Core.Unify: tcUnifyTysFG :: BindFun -> [Type] -> [Type] -> UnifyResult
+ GHC.Core.Unify: tcUnifyTysFG :: BindFamFun -> BindTvFun -> [Type] -> [Type] -> UnifyResult
- GHC.Core.UsageEnv: supUEs :: [UsageEnv] -> UsageEnv
+ GHC.Core.UsageEnv: supUEs :: Foldable f => f UsageEnv -> UsageEnv
- GHC.Core.Utils: applyTypeToArgs :: HasDebugCallStack => SDoc -> Type -> [CoreExpr] -> Type
+ GHC.Core.Utils: applyTypeToArgs :: HasDebugCallStack => Type -> [CoreExpr] -> Type
- GHC.Core.Utils: exprIsCheapX :: CheapAppFun -> CoreExpr -> Bool
+ GHC.Core.Utils: exprIsCheapX :: CheapAppFun -> Bool -> CoreExpr -> Bool
- GHC.CoreToStg.Prep: CorePrepConfig :: !Bool -> Platform -> !Maybe ArityOpts -> !Bool -> !Bool -> CorePrepConfig
+ GHC.CoreToStg.Prep: CorePrepConfig :: Bool -> Platform -> Maybe ArityOpts -> Bool -> Bool -> CorePrepConfig
- GHC.CoreToStg.Prep: CorePrepPgmConfig :: !EndPassConfig -> !Bool -> CorePrepPgmConfig
+ GHC.CoreToStg.Prep: CorePrepPgmConfig :: EndPassConfig -> Bool -> CorePrepPgmConfig
- GHC.CoreToStg.Prep: [cpPgm_endPassConfig] :: CorePrepPgmConfig -> !EndPassConfig
+ GHC.CoreToStg.Prep: [cpPgm_endPassConfig] :: CorePrepPgmConfig -> EndPassConfig
- GHC.CoreToStg.Prep: [cpPgm_generateDebugInfo] :: CorePrepPgmConfig -> !Bool
+ GHC.CoreToStg.Prep: [cpPgm_generateDebugInfo] :: CorePrepPgmConfig -> Bool
- GHC.CoreToStg.Prep: [cp_arityOpts] :: CorePrepConfig -> !Maybe ArityOpts
+ GHC.CoreToStg.Prep: [cp_arityOpts] :: CorePrepConfig -> Maybe ArityOpts
- GHC.CoreToStg.Prep: [cp_catchNonexhaustiveCases] :: CorePrepConfig -> !Bool
+ GHC.CoreToStg.Prep: [cp_catchNonexhaustiveCases] :: CorePrepConfig -> Bool
- GHC.CoreToStg.Prep: [cp_specEvalDFun] :: CorePrepConfig -> !Bool
+ GHC.CoreToStg.Prep: [cp_specEvalDFun] :: CorePrepConfig -> Bool
- GHC.CoreToStg.Prep: [cp_specEval] :: CorePrepConfig -> !Bool
+ GHC.CoreToStg.Prep: [cp_specEval] :: CorePrepConfig -> Bool
- GHC.CoreToStg.Prep: corePrepPgm :: Logger -> CorePrepConfig -> CorePrepPgmConfig -> Module -> ModLocation -> CoreProgram -> [TyCon] -> IO CoreProgram
+ GHC.CoreToStg.Prep: corePrepPgm :: Logger -> CorePrepConfig -> CorePrepPgmConfig -> Module -> CoreProgram -> IO CoreProgram
- GHC.Data.BooleanFormula: eval :: (a -> Bool) -> BooleanFormula a -> Bool
+ GHC.Data.BooleanFormula: eval :: forall (p :: Pass). (LIdP (GhcPass p) -> Bool) -> BooleanFormula (GhcPass p) -> Bool
- GHC.Data.BooleanFormula: implies :: Uniquable a => BooleanFormula a -> BooleanFormula a -> Bool
+ GHC.Data.BooleanFormula: implies :: forall (p :: Pass). Uniquable (IdP (GhcPass p)) => BooleanFormula (GhcPass p) -> BooleanFormula (GhcPass p) -> Bool
- GHC.Data.BooleanFormula: impliesAtom :: Eq a => BooleanFormula a -> a -> Bool
+ GHC.Data.BooleanFormula: impliesAtom :: forall (p :: Pass). Eq (IdP (GhcPass p)) => BooleanFormula (GhcPass p) -> LIdP (GhcPass p) -> Bool
- GHC.Data.BooleanFormula: isFalse :: BooleanFormula a -> Bool
+ GHC.Data.BooleanFormula: isFalse :: forall (p :: Pass). BooleanFormula (GhcPass p) -> Bool
- GHC.Data.BooleanFormula: isTrue :: BooleanFormula a -> Bool
+ GHC.Data.BooleanFormula: isTrue :: forall (p :: Pass). BooleanFormula (GhcPass p) -> Bool
- GHC.Data.BooleanFormula: isUnsatisfied :: Eq a => (a -> Bool) -> BooleanFormula a -> Maybe (BooleanFormula a)
+ GHC.Data.BooleanFormula: isUnsatisfied :: forall (p :: Pass). Eq (LIdP (GhcPass p)) => (LIdP (GhcPass p) -> Bool) -> BooleanFormula (GhcPass p) -> Maybe (BooleanFormula (GhcPass p))
- GHC.Data.BooleanFormula: pprBooleanFormula :: (Rational -> a -> SDoc) -> Rational -> BooleanFormula a -> SDoc
+ GHC.Data.BooleanFormula: pprBooleanFormula :: forall (p :: Pass). (Rational -> LIdP (GhcPass p) -> SDoc) -> Rational -> BooleanFormula (GhcPass p) -> SDoc
- GHC.Data.BooleanFormula: pprBooleanFormulaNice :: Outputable a => BooleanFormula a -> SDoc
+ GHC.Data.BooleanFormula: pprBooleanFormulaNice :: forall (p :: Pass). Outputable (LIdP (GhcPass p)) => BooleanFormula (GhcPass p) -> SDoc
- GHC.Data.BooleanFormula: simplify :: Eq a => (a -> Maybe Bool) -> BooleanFormula a -> BooleanFormula a
+ GHC.Data.BooleanFormula: simplify :: forall (p :: Pass). Eq (LIdP (GhcPass p)) => (LIdP (GhcPass p) -> Maybe Bool) -> BooleanFormula (GhcPass p) -> BooleanFormula (GhcPass p)
- GHC.Data.FastString: FastString :: {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !ShortByteString -> FastZString -> FastString
+ GHC.Data.FastString: FastString :: Int -> Int -> ShortByteString -> FastZString -> FastString
- GHC.Data.FastString: PtrString :: !Ptr Word8 -> !Int -> PtrString
+ GHC.Data.FastString: PtrString :: Ptr Word8 -> Int -> PtrString
- GHC.Data.FastString: [fs_sbs] :: FastString -> {-# UNPACK #-} !ShortByteString
+ GHC.Data.FastString: [fs_sbs] :: FastString -> ShortByteString
- GHC.Data.FastString: [n_chars] :: FastString -> {-# UNPACK #-} !Int
+ GHC.Data.FastString: [n_chars] :: FastString -> Int
- GHC.Data.FastString: [uniq] :: FastString -> {-# UNPACK #-} !Int
+ GHC.Data.FastString: [uniq] :: FastString -> Int
- GHC.Data.FlatBag: TupleFlatBag :: !a -> !a -> FlatBag a
+ GHC.Data.FlatBag: TupleFlatBag :: a -> a -> FlatBag a
- GHC.Data.FlatBag: UnitFlatBag :: !a -> FlatBag a
+ GHC.Data.FlatBag: UnitFlatBag :: a -> FlatBag a
- GHC.Data.Graph.Directed: NECyclicSCC :: {-# UNPACK #-} !NonEmpty vertex -> SCC vertex
+ GHC.Data.Graph.Directed: NECyclicSCC :: NonEmpty vertex -> SCC vertex
- GHC.Data.Maybe: expectJust :: HasDebugCallStack => String -> Maybe a -> a
+ GHC.Data.Maybe: expectJust :: HasCallStack => Maybe a -> a
- GHC.Data.Strict: And :: !a -> !b -> Pair a b
+ GHC.Data.Strict: And :: a -> b -> Pair a b
- GHC.Data.Strict: Just :: !a -> Maybe a
+ GHC.Data.Strict: Just :: a -> Maybe a
- GHC.Data.StringBuffer: StringBuffer :: {-# UNPACK #-} !ForeignPtr Word8 -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> StringBuffer
+ GHC.Data.StringBuffer: StringBuffer :: ForeignPtr Word8 -> Int -> Int -> StringBuffer
- GHC.Data.StringBuffer: [buf] :: StringBuffer -> {-# UNPACK #-} !ForeignPtr Word8
+ GHC.Data.StringBuffer: [buf] :: StringBuffer -> ForeignPtr Word8
- GHC.Data.StringBuffer: [cur] :: StringBuffer -> {-# UNPACK #-} !Int
+ GHC.Data.StringBuffer: [cur] :: StringBuffer -> Int
- GHC.Data.StringBuffer: [len] :: StringBuffer -> {-# UNPACK #-} !Int
+ GHC.Data.StringBuffer: [len] :: StringBuffer -> Int
- GHC.Data.UnionFind: Info :: {-# UNPACK #-} !STRef s Int -> {-# UNPACK #-} !STRef s a -> Link s a
+ GHC.Data.UnionFind: Info :: STRef s Int -> STRef s a -> Link s a
- GHC.Data.UnionFind: Link :: {-# UNPACK #-} !Point s a -> Link s a
+ GHC.Data.UnionFind: Link :: Point s a -> Link s a
- GHC.Data.Word64Map.Internal: Bin :: {-# UNPACK #-} !Prefix -> {-# UNPACK #-} !Mask -> !Word64Map a -> !Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Internal: Bin :: Prefix -> Mask -> Word64Map a -> Word64Map a -> Word64Map a
- GHC.Data.Word64Map.Internal: Tip :: {-# UNPACK #-} !Key -> a -> Word64Map a
+ GHC.Data.Word64Map.Internal: Tip :: Key -> a -> Word64Map a
- GHC.Data.Word64Set.Internal: Bin :: {-# UNPACK #-} !Prefix -> {-# UNPACK #-} !Mask -> !Word64Set -> !Word64Set -> Word64Set
+ GHC.Data.Word64Set.Internal: Bin :: Prefix -> Mask -> Word64Set -> Word64Set -> Word64Set
- GHC.Data.Word64Set.Internal: Tip :: {-# UNPACK #-} !Prefix -> {-# UNPACK #-} !BitMap -> Word64Set
+ GHC.Data.Word64Set.Internal: Tip :: Prefix -> BitMap -> Word64Set
- GHC.Driver.Config: initEvalOpts :: DynFlags -> Bool -> EvalOpts
+ GHC.Driver.Config: initEvalOpts :: DynFlags -> EvalStep -> EvalOpts
- GHC.Driver.DynFlags: DynFlags :: GhcMode -> GhcLink -> !Backend -> {-# UNPACK #-} !GhcNameVersion -> {-# UNPACK #-} !FileSettings -> Platform -> {-# UNPACK #-} !ToolSettings -> {-# UNPACK #-} !PlatformMisc -> [(String, String)] -> TempDir -> Int -> Int -> Int -> Int -> Int -> Maybe String -> [Int] -> Maybe ParMakeCount -> Bool -> Maybe Int -> Maybe Int -> Maybe Int -> Maybe Int -> Maybe Int -> Int -> Int -> Int -> !Int -> Int -> Maybe Int -> Maybe Int -> Int -> Maybe Word -> Maybe Int -> Maybe Int -> Maybe Int -> Maybe Int -> Bool -> Maybe Int -> Int -> [FilePath] -> ModuleName -> Maybe String -> IntWithInf -> IntWithInf -> Int -> Int -> Int -> UnitId -> Maybe UnitId -> [(ModuleName, Module)] -> Maybe FilePath -> Maybe String -> Set ModuleName -> [ReexportedModule] -> Ways -> Maybe (String, Int) -> Maybe String -> Maybe String -> Maybe String -> Maybe String -> Maybe String -> Maybe String -> String -> String -> String -> String -> String -> String -> Maybe String -> Maybe String -> Maybe String -> Maybe String -> DynLibLoader -> !Bool -> FilePath -> Maybe FilePath -> [Option] -> IncludeSpecs -> [String] -> [String] -> [String] -> Maybe String -> RtsOptsEnabled -> Bool -> String -> [ModuleName] -> [(ModuleName, String)] -> [String] -> [ExternalPluginSpec] -> FilePath -> Bool -> Bool -> [ModuleName] -> [String] -> [PackageDBFlag] -> [IgnorePackageFlag] -> [PackageFlag] -> [PackageFlag] -> [TrustFlag] -> Maybe FilePath -> EnumSet DumpFlag -> EnumSet GeneralFlag -> EnumSet WarningFlag -> EnumSet WarningFlag -> WarningCategorySet -> WarningCategorySet -> Maybe Language -> SafeHaskellMode -> Bool -> Bool -> SrcSpan -> SrcSpan -> SrcSpan -> SrcSpan -> SrcSpan -> SrcSpan -> SrcSpan -> SrcSpan -> SrcSpan -> [OnOff Extension] -> EnumSet Extension -> !UnfoldingOpts -> Int -> Int -> Int -> FlushOut -> Maybe FilePath -> Maybe String -> [String] -> Int -> Int -> Bool -> OverridingBool -> Bool -> OverridingBool -> Bool -> Scheme -> ProfAuto -> [CallerCcFilter] -> Maybe String -> Maybe SseVersion -> Maybe BmiVersion -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Int -> Int -> Int -> Bool -> Maybe Int -> Word64 -> Int -> Weights -> DynFlags
+ GHC.Driver.DynFlags: DynFlags :: GhcMode -> GhcLink -> Backend -> GhcNameVersion -> FileSettings -> UnitSettings -> Platform -> ToolSettings -> PlatformMisc -> [(String, String)] -> TempDir -> Int -> Int -> Int -> Int -> Int -> Maybe String -> [Int] -> Maybe ParMakeCount -> Bool -> Maybe Int -> Maybe Int -> Maybe Int -> Maybe Int -> Maybe Int -> Int -> Int -> Int -> Int -> Int -> Maybe Int -> Maybe Int -> Int -> Maybe Word -> Maybe Int -> Maybe Int -> Maybe Int -> Maybe Int -> Bool -> Maybe Int -> Int -> [FilePath] -> ModuleName -> Maybe String -> IntWithInf -> IntWithInf -> Int -> Int -> Int -> UnitId -> Maybe UnitId -> [(ModuleName, Module)] -> Maybe FilePath -> Maybe String -> Set ModuleName -> [ReexportedModule] -> Ways -> Maybe (String, Int) -> Maybe String -> Maybe String -> Maybe String -> Maybe String -> Maybe String -> Maybe String -> String -> String -> String -> String -> String -> String -> Maybe String -> Maybe String -> Maybe String -> Maybe String -> DynLibLoader -> Bool -> FilePath -> Maybe FilePath -> [Option] -> IncludeSpecs -> [String] -> [String] -> [String] -> Maybe String -> RtsOptsEnabled -> Bool -> String -> [ModuleName] -> [(ModuleName, String)] -> [String] -> [ExternalPluginSpec] -> FilePath -> Bool -> Bool -> [ModuleName] -> [String] -> [PackageDBFlag] -> [IgnorePackageFlag] -> [PackageFlag] -> [PackageFlag] -> [TrustFlag] -> Maybe FilePath -> EnumSet DumpFlag -> EnumSet GeneralFlag -> EnumSet WarningFlag -> EnumSet WarningFlag -> WarningCategorySet -> WarningCategorySet -> Maybe Language -> SafeHaskellMode -> Bool -> Bool -> SrcSpan -> SrcSpan -> SrcSpan -> SrcSpan -> SrcSpan -> SrcSpan -> SrcSpan -> SrcSpan -> SrcSpan -> [OnOff Extension] -> EnumSet Extension -> UnfoldingOpts -> Int -> Int -> Int -> String -> Int -> Maybe String -> Maybe String -> Maybe String -> FlushOut -> Maybe FilePath -> Maybe String -> [String] -> Int -> Int -> Bool -> OverridingBool -> Bool -> OverridingBool -> Bool -> Scheme -> ProfAuto -> [CallerCcFilter] -> Maybe String -> Maybe SseVersion -> Maybe BmiVersion -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Int -> Int -> Int -> Bool -> Maybe Int -> Word64 -> Int -> Weights -> DynFlags
- GHC.Driver.DynFlags: WarningWithCategory :: !WarningCategory -> DiagnosticReason
+ GHC.Driver.DynFlags: WarningWithCategory :: WarningCategory -> DiagnosticReason
- GHC.Driver.DynFlags: WarningWithFlags :: !NonEmpty WarningFlag -> DiagnosticReason
+ GHC.Driver.DynFlags: WarningWithFlags :: NonEmpty WarningFlag -> DiagnosticReason
- GHC.Driver.DynFlags: [backend] :: DynFlags -> !Backend
+ GHC.Driver.DynFlags: [backend] :: DynFlags -> Backend
- GHC.Driver.DynFlags: [dmdUnboxWidth] :: DynFlags -> !Int
+ GHC.Driver.DynFlags: [dmdUnboxWidth] :: DynFlags -> Int
- GHC.Driver.DynFlags: [dynamicNow] :: DynFlags -> !Bool
+ GHC.Driver.DynFlags: [dynamicNow] :: DynFlags -> Bool
- GHC.Driver.DynFlags: [fileSettings] :: DynFlags -> {-# UNPACK #-} !FileSettings
+ GHC.Driver.DynFlags: [fileSettings] :: DynFlags -> FileSettings
- GHC.Driver.DynFlags: [ghcNameVersion] :: DynFlags -> {-# UNPACK #-} !GhcNameVersion
+ GHC.Driver.DynFlags: [ghcNameVersion] :: DynFlags -> GhcNameVersion
- GHC.Driver.DynFlags: [platformMisc] :: DynFlags -> {-# UNPACK #-} !PlatformMisc
+ GHC.Driver.DynFlags: [platformMisc] :: DynFlags -> PlatformMisc
- GHC.Driver.DynFlags: [toolSettings] :: DynFlags -> {-# UNPACK #-} !ToolSettings
+ GHC.Driver.DynFlags: [toolSettings] :: DynFlags -> ToolSettings
- GHC.Driver.DynFlags: [unfoldingOpts] :: DynFlags -> !UnfoldingOpts
+ GHC.Driver.DynFlags: [unfoldingOpts] :: DynFlags -> UnfoldingOpts
- GHC.Driver.Env: HscEnv :: DynFlags -> [Target] -> ModuleGraph -> InteractiveContext -> {-# UNPACK #-} !NameCache -> {-# UNPACK #-} !FinderCache -> KnotVars (IORef TypeEnv) -> Maybe Interp -> !Plugins -> UnitEnv -> !Logger -> !Hooks -> !TmpFs -> !LlvmConfigCache -> HscEnv
+ GHC.Driver.Env: HscEnv :: DynFlags -> [Target] -> InteractiveContext -> NameCache -> FinderCache -> KnotVars (IORef TypeEnv) -> Maybe Interp -> Plugins -> UnitEnv -> Logger -> Hooks -> TmpFs -> LlvmConfigCache -> HscEnv
- GHC.Driver.Env: [hsc_FC] :: HscEnv -> {-# UNPACK #-} !FinderCache
+ GHC.Driver.Env: [hsc_FC] :: HscEnv -> FinderCache
- GHC.Driver.Env: [hsc_NC] :: HscEnv -> {-# UNPACK #-} !NameCache
+ GHC.Driver.Env: [hsc_NC] :: HscEnv -> NameCache
- GHC.Driver.Env: [hsc_hooks] :: HscEnv -> !Hooks
+ GHC.Driver.Env: [hsc_hooks] :: HscEnv -> Hooks
- GHC.Driver.Env: [hsc_llvm_config] :: HscEnv -> !LlvmConfigCache
+ GHC.Driver.Env: [hsc_llvm_config] :: HscEnv -> LlvmConfigCache
- GHC.Driver.Env: [hsc_logger] :: HscEnv -> !Logger
+ GHC.Driver.Env: [hsc_logger] :: HscEnv -> Logger
- GHC.Driver.Env: [hsc_plugins] :: HscEnv -> !Plugins
+ GHC.Driver.Env: [hsc_plugins] :: HscEnv -> Plugins
- GHC.Driver.Env: [hsc_tmpfs] :: HscEnv -> !TmpFs
+ GHC.Driver.Env: [hsc_tmpfs] :: HscEnv -> TmpFs
- GHC.Driver.Env: lookupIfaceByModule :: HomeUnitGraph -> PackageIfaceTable -> Module -> Maybe ModIface
+ GHC.Driver.Env: lookupIfaceByModule :: HomeUnitGraph -> PackageIfaceTable -> Module -> IO (Maybe ModIface)
- GHC.Driver.Env.Types: HscEnv :: DynFlags -> [Target] -> ModuleGraph -> InteractiveContext -> {-# UNPACK #-} !NameCache -> {-# UNPACK #-} !FinderCache -> KnotVars (IORef TypeEnv) -> Maybe Interp -> !Plugins -> UnitEnv -> !Logger -> !Hooks -> !TmpFs -> !LlvmConfigCache -> HscEnv
+ GHC.Driver.Env.Types: HscEnv :: DynFlags -> [Target] -> InteractiveContext -> NameCache -> FinderCache -> KnotVars (IORef TypeEnv) -> Maybe Interp -> Plugins -> UnitEnv -> Logger -> Hooks -> TmpFs -> LlvmConfigCache -> HscEnv
- GHC.Driver.Env.Types: [hsc_FC] :: HscEnv -> {-# UNPACK #-} !FinderCache
+ GHC.Driver.Env.Types: [hsc_FC] :: HscEnv -> FinderCache
- GHC.Driver.Env.Types: [hsc_NC] :: HscEnv -> {-# UNPACK #-} !NameCache
+ GHC.Driver.Env.Types: [hsc_NC] :: HscEnv -> NameCache
- GHC.Driver.Env.Types: [hsc_hooks] :: HscEnv -> !Hooks
+ GHC.Driver.Env.Types: [hsc_hooks] :: HscEnv -> Hooks
- GHC.Driver.Env.Types: [hsc_llvm_config] :: HscEnv -> !LlvmConfigCache
+ GHC.Driver.Env.Types: [hsc_llvm_config] :: HscEnv -> LlvmConfigCache
- GHC.Driver.Env.Types: [hsc_logger] :: HscEnv -> !Logger
+ GHC.Driver.Env.Types: [hsc_logger] :: HscEnv -> Logger
- GHC.Driver.Env.Types: [hsc_plugins] :: HscEnv -> !Plugins
+ GHC.Driver.Env.Types: [hsc_plugins] :: HscEnv -> Plugins
- GHC.Driver.Env.Types: [hsc_tmpfs] :: HscEnv -> !TmpFs
+ GHC.Driver.Env.Types: [hsc_tmpfs] :: HscEnv -> TmpFs
- GHC.Driver.Errors.Types: PsHeaderMessage :: !PsHeaderMessage -> PsMessage
+ GHC.Driver.Errors.Types: PsHeaderMessage :: PsHeaderMessage -> PsMessage
- GHC.Driver.Errors.Types: [DriverBackpackModuleNotFound] :: !ModuleName -> DriverMessage
+ GHC.Driver.Errors.Types: [DriverBackpackModuleNotFound] :: ModuleName -> DriverMessage
- GHC.Driver.Errors.Types: [DriverCannotImportFromUntrustedPackage] :: !UnitState -> !Module -> DriverMessage
+ GHC.Driver.Errors.Types: [DriverCannotImportFromUntrustedPackage] :: UnitState -> Module -> DriverMessage
- GHC.Driver.Errors.Types: [DriverCannotImportUnsafeModule] :: !Module -> DriverMessage
+ GHC.Driver.Errors.Types: [DriverCannotImportUnsafeModule] :: Module -> DriverMessage
- GHC.Driver.Errors.Types: [DriverCannotLoadInterfaceFile] :: !Module -> DriverMessage
+ GHC.Driver.Errors.Types: [DriverCannotLoadInterfaceFile] :: Module -> DriverMessage
- GHC.Driver.Errors.Types: [DriverDuplicatedModuleDeclaration] :: !Module -> [FilePath] -> DriverMessage
+ GHC.Driver.Errors.Types: [DriverDuplicatedModuleDeclaration] :: Module -> [FilePath] -> DriverMessage
- GHC.Driver.Errors.Types: [DriverFileModuleNameMismatch] :: !ModuleName -> !ModuleName -> DriverMessage
+ GHC.Driver.Errors.Types: [DriverFileModuleNameMismatch] :: ModuleName -> ModuleName -> DriverMessage
- GHC.Driver.Errors.Types: [DriverFileNotFound] :: !FilePath -> DriverMessage
+ GHC.Driver.Errors.Types: [DriverFileNotFound] :: FilePath -> DriverMessage
- GHC.Driver.Errors.Types: [DriverHomePackagesNotClosed] :: ![UnitId] -> DriverMessage
+ GHC.Driver.Errors.Types: [DriverHomePackagesNotClosed] :: [UnitId] -> DriverMessage
- GHC.Driver.Errors.Types: [DriverInferredSafeImport] :: !Module -> DriverMessage
+ GHC.Driver.Errors.Types: [DriverInferredSafeImport] :: Module -> DriverMessage
- GHC.Driver.Errors.Types: [DriverInferredSafeModule] :: !Module -> DriverMessage
+ GHC.Driver.Errors.Types: [DriverInferredSafeModule] :: Module -> DriverMessage
- GHC.Driver.Errors.Types: [DriverInterfaceError] :: !IfaceMessage -> DriverMessage
+ GHC.Driver.Errors.Types: [DriverInterfaceError] :: IfaceMessage -> DriverMessage
- GHC.Driver.Errors.Types: [DriverMarkedTrustworthyButInferredSafe] :: !Module -> DriverMessage
+ GHC.Driver.Errors.Types: [DriverMarkedTrustworthyButInferredSafe] :: Module -> DriverMessage
- GHC.Driver.Errors.Types: [DriverMissingHomeModules] :: UnitId -> [ModuleName] -> !BuildingCabalPackage -> DriverMessage
+ GHC.Driver.Errors.Types: [DriverMissingHomeModules] :: UnitId -> [ModuleName] -> BuildingCabalPackage -> DriverMessage
- GHC.Driver.Errors.Types: [DriverMissingSafeHaskellMode] :: !Module -> DriverMessage
+ GHC.Driver.Errors.Types: [DriverMissingSafeHaskellMode] :: Module -> DriverMessage
- GHC.Driver.Errors.Types: [DriverMixedSafetyImport] :: !ModuleName -> DriverMessage
+ GHC.Driver.Errors.Types: [DriverMixedSafetyImport] :: ModuleName -> DriverMessage
- GHC.Driver.Errors.Types: [DriverModuleNotFound] :: !ModuleName -> DriverMessage
+ GHC.Driver.Errors.Types: [DriverModuleNotFound] :: UnitId -> ModuleName -> DriverMessage
- GHC.Driver.Errors.Types: [DriverPackageNotTrusted] :: !UnitState -> !UnitId -> DriverMessage
+ GHC.Driver.Errors.Types: [DriverPackageNotTrusted] :: UnitState -> UnitId -> DriverMessage
- GHC.Driver.Errors.Types: [DriverPsHeaderMessage] :: !PsMessage -> DriverMessage
+ GHC.Driver.Errors.Types: [DriverPsHeaderMessage] :: PsMessage -> DriverMessage
- GHC.Driver.Errors.Types: [DriverRedirectedNoMain] :: !ModuleName -> DriverMessage
+ GHC.Driver.Errors.Types: [DriverRedirectedNoMain] :: ModuleName -> DriverMessage
- GHC.Driver.Errors.Types: [DriverSafeHaskellIgnoredExtension] :: !Extension -> DriverMessage
+ GHC.Driver.Errors.Types: [DriverSafeHaskellIgnoredExtension] :: Extension -> DriverMessage
- GHC.Driver.Errors.Types: [DriverUnexpectedSignature] :: !ModuleName -> !BuildingCabalPackage -> GenInstantiations UnitId -> DriverMessage
+ GHC.Driver.Errors.Types: [DriverUnexpectedSignature] :: ModuleName -> BuildingCabalPackage -> GenInstantiations UnitId -> DriverMessage
- GHC.Driver.Errors.Types: [DriverUnknownMessage] :: UnknownDiagnostic (DiagnosticOpts DriverMessage) -> DriverMessage
+ GHC.Driver.Errors.Types: [DriverUnknownMessage] :: UnknownDiagnosticFor DriverMessage -> DriverMessage
- GHC.Driver.Errors.Types: [DriverUnnecessarySourceImports] :: !ModuleName -> DriverMessage
+ GHC.Driver.Errors.Types: [DriverUnnecessarySourceImports] :: ModuleName -> DriverMessage
- GHC.Driver.Errors.Types: [DriverUserDefinedRuleIgnored] :: !RuleDecl GhcTc -> DriverMessage
+ GHC.Driver.Errors.Types: [DriverUserDefinedRuleIgnored] :: RuleDecl GhcTc -> DriverMessage
- GHC.Driver.Errors.Types: [GhcUnknownMessage] :: UnknownDiagnostic (DiagnosticOpts GhcMessage) -> GhcMessage
+ GHC.Driver.Errors.Types: [GhcUnknownMessage] :: UnknownDiagnosticFor GhcMessage -> GhcMessage
- GHC.Driver.Errors.Types: ghcUnknownMessage :: (DiagnosticOpts a ~ NoDiagnosticOpts, Diagnostic a, Typeable a) => a -> GhcMessage
+ GHC.Driver.Errors.Types: ghcUnknownMessage :: (DiagnosticOpts a ~ NoDiagnosticOpts, DiagnosticHint a ~ DiagnosticHint GhcMessage, Diagnostic a, Typeable a) => a -> GhcMessage
- GHC.Driver.Flags: impliedXFlags :: [(Extension, TurnOnFlag, Extension)]
+ GHC.Driver.Flags: impliedXFlags :: [(Extension, OnOff Extension)]
- GHC.Driver.Main: HscRecomp :: CgGuts -> !ModLocation -> !PartialModIface -> !Maybe Fingerprint -> HscBackendAction
+ GHC.Driver.Main: HscRecomp :: CgGuts -> ModLocation -> PartialModIface -> Maybe Fingerprint -> HscBackendAction
- GHC.Driver.Main: [hscs_mod_location] :: HscBackendAction -> !ModLocation
+ GHC.Driver.Main: [hscs_mod_location] :: HscBackendAction -> ModLocation
- GHC.Driver.Main: [hscs_old_iface_hash] :: HscBackendAction -> !Maybe Fingerprint
+ GHC.Driver.Main: [hscs_old_iface_hash] :: HscBackendAction -> Maybe Fingerprint
- GHC.Driver.Main: [hscs_partial_iface] :: HscBackendAction -> !PartialModIface
+ GHC.Driver.Main: [hscs_partial_iface] :: HscBackendAction -> PartialModIface
- GHC.Driver.Make: FoundHome :: ModSummary -> SummariseResult
+ GHC.Driver.Make: FoundHome :: ModuleNodeInfo -> SummariseResult
- GHC.Driver.Make: LoadUpTo :: HomeUnitModule -> LoadHowMuch
+ GHC.Driver.Make: LoadUpTo :: [HomeUnitModule] -> LoadHowMuch
- GHC.Driver.Make: ModNodeKeyWithUid :: !ModuleNameWithIsBoot -> !UnitId -> ModNodeKeyWithUid
+ GHC.Driver.Make: ModNodeKeyWithUid :: ModuleNameWithIsBoot -> UnitId -> ModNodeKeyWithUid
- GHC.Driver.Make: [mnkModuleName] :: ModNodeKeyWithUid -> !ModuleNameWithIsBoot
+ GHC.Driver.Make: [mnkModuleName] :: ModNodeKeyWithUid -> ModuleNameWithIsBoot
- GHC.Driver.Make: [mnkUnitId] :: ModNodeKeyWithUid -> !UnitId
+ GHC.Driver.Make: [mnkUnitId] :: ModNodeKeyWithUid -> UnitId
- GHC.Driver.Make: depanalE :: GhcMonad m => [ModuleName] -> Bool -> m (DriverMessages, ModuleGraph)
+ GHC.Driver.Make: depanalE :: GhcMonad m => (GhcMessage -> AnyGhcDiagnostic) -> Maybe Messager -> [ModuleName] -> Bool -> m (DriverMessages, ModuleGraph)
- GHC.Driver.Make: depanalPartial :: GhcMonad m => [ModuleName] -> Bool -> m (DriverMessages, ModuleGraph)
+ GHC.Driver.Make: depanalPartial :: GhcMonad m => (GhcMessage -> AnyGhcDiagnostic) -> Maybe Messager -> [ModuleName] -> Bool -> m (DriverMessages, ModuleGraph)
- GHC.Driver.Make: downsweep :: HscEnv -> [ModSummary] -> [ModuleName] -> Bool -> IO ([DriverMessages], [ModuleGraphNode])
+ GHC.Driver.Make: downsweep :: HscEnv -> (GhcMessage -> AnyGhcDiagnostic) -> Maybe Messager -> [ModSummary] -> [ModuleName] -> Bool -> IO ([DriverMessages], ModuleGraph)
- GHC.Driver.Make: implicitRequirementsShallow :: HscEnv -> [(PkgQual, Located ModuleName)] -> IO ([ModuleName], [InstantiatedUnit])
+ GHC.Driver.Make: implicitRequirementsShallow :: HscEnv -> [(ImportLevel, PkgQual, Located ModuleName)] -> IO ([ModuleName], [InstantiatedUnit])
- GHC.Driver.Make: instantiationNodes :: UnitId -> UnitState -> [ModuleGraphNode]
+ GHC.Driver.Make: instantiationNodes :: UnitId -> UnitState -> [(UnitId, InstantiatedUnit)]
- GHC.Driver.Make: ms_home_imps :: ModSummary -> [(PkgQual, Located ModuleName)]
+ GHC.Driver.Make: ms_home_imps :: ModSummary -> [(ImportLevel, PkgQual, Located ModuleName)]
- GHC.Driver.Make: topSortModuleGraph :: Bool -> ModuleGraph -> Maybe HomeUnitModule -> [SCC ModuleGraphNode]
+ GHC.Driver.Make: topSortModuleGraph :: Bool -> ModuleGraph -> Maybe [HomeUnitModule] -> [SCC ModuleGraphNode]
- GHC.Driver.Make: type AnyGhcDiagnostic = UnknownDiagnostic DiagnosticOpts GhcMessage
+ GHC.Driver.Make: type AnyGhcDiagnostic = UnknownDiagnosticFor GhcMessage
- GHC.Driver.Monad: Session :: !IORef HscEnv -> Session
+ GHC.Driver.Monad: Session :: IORef HscEnv -> Session
- GHC.Driver.Pipeline.Execute: llvmOptions :: LlvmConfig -> Maybe LlvmVersion -> DynFlags -> [(String, String)]
+ GHC.Driver.Pipeline.Execute: llvmOptions :: LlvmConfig -> DynFlags -> [(String, String)]
- GHC.Driver.Pipeline.LogQueue: LogQueue :: !Int -> !IORef [Maybe (MessageClass, SrcSpan, SDoc, LogFlags)] -> !MVar () -> LogQueue
+ GHC.Driver.Pipeline.LogQueue: LogQueue :: Int -> IORef [Maybe (MessageClass, SrcSpan, SDoc, LogFlags)] -> MVar () -> LogQueue
- GHC.Driver.Pipeline.LogQueue: [logQueueId] :: LogQueue -> !Int
+ GHC.Driver.Pipeline.LogQueue: [logQueueId] :: LogQueue -> Int
- GHC.Driver.Pipeline.LogQueue: [logQueueMessages] :: LogQueue -> !IORef [Maybe (MessageClass, SrcSpan, SDoc, LogFlags)]
+ GHC.Driver.Pipeline.LogQueue: [logQueueMessages] :: LogQueue -> IORef [Maybe (MessageClass, SrcSpan, SDoc, LogFlags)]
- GHC.Driver.Pipeline.LogQueue: [logQueueSemaphore] :: LogQueue -> !MVar ()
+ GHC.Driver.Pipeline.LogQueue: [logQueueSemaphore] :: LogQueue -> MVar ()
- GHC.Driver.Plugins: Plugins :: ![StaticPlugin] -> ![ExternalPlugin] -> ![LoadedPlugin] -> !([Linkable], PkgsLoaded) -> Plugins
+ GHC.Driver.Plugins: Plugins :: [StaticPlugin] -> [ExternalPlugin] -> [LoadedPlugin] -> ([Linkable], PkgsLoaded) -> Plugins
- GHC.Driver.Plugins: [externalPlugins] :: Plugins -> ![ExternalPlugin]
+ GHC.Driver.Plugins: [externalPlugins] :: Plugins -> [ExternalPlugin]
- GHC.Driver.Plugins: [loadedPluginDeps] :: Plugins -> !([Linkable], PkgsLoaded)
+ GHC.Driver.Plugins: [loadedPluginDeps] :: Plugins -> ([Linkable], PkgsLoaded)
- GHC.Driver.Plugins: [loadedPlugins] :: Plugins -> ![LoadedPlugin]
+ GHC.Driver.Plugins: [loadedPlugins] :: Plugins -> [LoadedPlugin]
- GHC.Driver.Plugins: [staticPlugins] :: Plugins -> ![StaticPlugin]
+ GHC.Driver.Plugins: [staticPlugins] :: Plugins -> [StaticPlugin]
- GHC.Driver.Plugins.External: ExternalPluginSpec :: !FilePath -> !String -> !String -> ![String] -> ExternalPluginSpec
+ GHC.Driver.Plugins.External: ExternalPluginSpec :: FilePath -> String -> String -> [String] -> ExternalPluginSpec
- GHC.Driver.Plugins.External: [esp_args] :: ExternalPluginSpec -> ![String]
+ GHC.Driver.Plugins.External: [esp_args] :: ExternalPluginSpec -> [String]
- GHC.Driver.Plugins.External: [esp_lib] :: ExternalPluginSpec -> !FilePath
+ GHC.Driver.Plugins.External: [esp_lib] :: ExternalPluginSpec -> FilePath
- GHC.Driver.Plugins.External: [esp_module] :: ExternalPluginSpec -> !String
+ GHC.Driver.Plugins.External: [esp_module] :: ExternalPluginSpec -> String
- GHC.Driver.Plugins.External: [esp_unit_id] :: ExternalPluginSpec -> !String
+ GHC.Driver.Plugins.External: [esp_unit_id] :: ExternalPluginSpec -> String
- GHC.Driver.Session: DynFlags :: GhcMode -> GhcLink -> !Backend -> {-# UNPACK #-} !GhcNameVersion -> {-# UNPACK #-} !FileSettings -> Platform -> {-# UNPACK #-} !ToolSettings -> {-# UNPACK #-} !PlatformMisc -> [(String, String)] -> TempDir -> Int -> Int -> Int -> Int -> Int -> Maybe String -> [Int] -> Maybe ParMakeCount -> Bool -> Maybe Int -> Maybe Int -> Maybe Int -> Maybe Int -> Maybe Int -> Int -> Int -> Int -> !Int -> Int -> Maybe Int -> Maybe Int -> Int -> Maybe Word -> Maybe Int -> Maybe Int -> Maybe Int -> Maybe Int -> Bool -> Maybe Int -> Int -> [FilePath] -> ModuleName -> Maybe String -> IntWithInf -> IntWithInf -> Int -> Int -> Int -> UnitId -> Maybe UnitId -> [(ModuleName, Module)] -> Maybe FilePath -> Maybe String -> Set ModuleName -> [ReexportedModule] -> Ways -> Maybe (String, Int) -> Maybe String -> Maybe String -> Maybe String -> Maybe String -> Maybe String -> Maybe String -> String -> String -> String -> String -> String -> String -> Maybe String -> Maybe String -> Maybe String -> Maybe String -> DynLibLoader -> !Bool -> FilePath -> Maybe FilePath -> [Option] -> IncludeSpecs -> [String] -> [String] -> [String] -> Maybe String -> RtsOptsEnabled -> Bool -> String -> [ModuleName] -> [(ModuleName, String)] -> [String] -> [ExternalPluginSpec] -> FilePath -> Bool -> Bool -> [ModuleName] -> [String] -> [PackageDBFlag] -> [IgnorePackageFlag] -> [PackageFlag] -> [PackageFlag] -> [TrustFlag] -> Maybe FilePath -> EnumSet DumpFlag -> EnumSet GeneralFlag -> EnumSet WarningFlag -> EnumSet WarningFlag -> WarningCategorySet -> WarningCategorySet -> Maybe Language -> SafeHaskellMode -> Bool -> Bool -> SrcSpan -> SrcSpan -> SrcSpan -> SrcSpan -> SrcSpan -> SrcSpan -> SrcSpan -> SrcSpan -> SrcSpan -> [OnOff Extension] -> EnumSet Extension -> !UnfoldingOpts -> Int -> Int -> Int -> FlushOut -> Maybe FilePath -> Maybe String -> [String] -> Int -> Int -> Bool -> OverridingBool -> Bool -> OverridingBool -> Bool -> Scheme -> ProfAuto -> [CallerCcFilter] -> Maybe String -> Maybe SseVersion -> Maybe BmiVersion -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Int -> Int -> Int -> Bool -> Maybe Int -> Word64 -> Int -> Weights -> DynFlags
+ GHC.Driver.Session: DynFlags :: GhcMode -> GhcLink -> Backend -> GhcNameVersion -> FileSettings -> UnitSettings -> Platform -> ToolSettings -> PlatformMisc -> [(String, String)] -> TempDir -> Int -> Int -> Int -> Int -> Int -> Maybe String -> [Int] -> Maybe ParMakeCount -> Bool -> Maybe Int -> Maybe Int -> Maybe Int -> Maybe Int -> Maybe Int -> Int -> Int -> Int -> Int -> Int -> Maybe Int -> Maybe Int -> Int -> Maybe Word -> Maybe Int -> Maybe Int -> Maybe Int -> Maybe Int -> Bool -> Maybe Int -> Int -> [FilePath] -> ModuleName -> Maybe String -> IntWithInf -> IntWithInf -> Int -> Int -> Int -> UnitId -> Maybe UnitId -> [(ModuleName, Module)] -> Maybe FilePath -> Maybe String -> Set ModuleName -> [ReexportedModule] -> Ways -> Maybe (String, Int) -> Maybe String -> Maybe String -> Maybe String -> Maybe String -> Maybe String -> Maybe String -> String -> String -> String -> String -> String -> String -> Maybe String -> Maybe String -> Maybe String -> Maybe String -> DynLibLoader -> Bool -> FilePath -> Maybe FilePath -> [Option] -> IncludeSpecs -> [String] -> [String] -> [String] -> Maybe String -> RtsOptsEnabled -> Bool -> String -> [ModuleName] -> [(ModuleName, String)] -> [String] -> [ExternalPluginSpec] -> FilePath -> Bool -> Bool -> [ModuleName] -> [String] -> [PackageDBFlag] -> [IgnorePackageFlag] -> [PackageFlag] -> [PackageFlag] -> [TrustFlag] -> Maybe FilePath -> EnumSet DumpFlag -> EnumSet GeneralFlag -> EnumSet WarningFlag -> EnumSet WarningFlag -> WarningCategorySet -> WarningCategorySet -> Maybe Language -> SafeHaskellMode -> Bool -> Bool -> SrcSpan -> SrcSpan -> SrcSpan -> SrcSpan -> SrcSpan -> SrcSpan -> SrcSpan -> SrcSpan -> SrcSpan -> [OnOff Extension] -> EnumSet Extension -> UnfoldingOpts -> Int -> Int -> Int -> String -> Int -> Maybe String -> Maybe String -> Maybe String -> FlushOut -> Maybe FilePath -> Maybe String -> [String] -> Int -> Int -> Bool -> OverridingBool -> Bool -> OverridingBool -> Bool -> Scheme -> ProfAuto -> [CallerCcFilter] -> Maybe String -> Maybe SseVersion -> Maybe BmiVersion -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Int -> Int -> Int -> Bool -> Maybe Int -> Word64 -> Int -> Weights -> DynFlags
- GHC.Driver.Session: Settings :: {-# UNPACK #-} !GhcNameVersion -> {-# UNPACK #-} !FileSettings -> Platform -> {-# UNPACK #-} !ToolSettings -> {-# UNPACK #-} !PlatformMisc -> [(String, String)] -> Settings
+ GHC.Driver.Session: Settings :: GhcNameVersion -> FileSettings -> Platform -> ToolSettings -> PlatformMisc -> UnitSettings -> [(String, String)] -> Settings
- GHC.Driver.Session: WarningWithCategory :: !WarningCategory -> DiagnosticReason
+ GHC.Driver.Session: WarningWithCategory :: WarningCategory -> DiagnosticReason
- GHC.Driver.Session: WarningWithFlags :: !NonEmpty WarningFlag -> DiagnosticReason
+ GHC.Driver.Session: WarningWithFlags :: NonEmpty WarningFlag -> DiagnosticReason
- GHC.Driver.Session: [backend] :: DynFlags -> !Backend
+ GHC.Driver.Session: [backend] :: DynFlags -> Backend
- GHC.Driver.Session: [dmdUnboxWidth] :: DynFlags -> !Int
+ GHC.Driver.Session: [dmdUnboxWidth] :: DynFlags -> Int
- GHC.Driver.Session: [dynamicNow] :: DynFlags -> !Bool
+ GHC.Driver.Session: [dynamicNow] :: DynFlags -> Bool
- GHC.Driver.Session: [fileSettings] :: DynFlags -> {-# UNPACK #-} !FileSettings
+ GHC.Driver.Session: [fileSettings] :: DynFlags -> FileSettings
- GHC.Driver.Session: [ghcNameVersion] :: DynFlags -> {-# UNPACK #-} !GhcNameVersion
+ GHC.Driver.Session: [ghcNameVersion] :: DynFlags -> GhcNameVersion
- GHC.Driver.Session: [platformMisc] :: DynFlags -> {-# UNPACK #-} !PlatformMisc
+ GHC.Driver.Session: [platformMisc] :: DynFlags -> PlatformMisc
- GHC.Driver.Session: [sFileSettings] :: Settings -> {-# UNPACK #-} !FileSettings
+ GHC.Driver.Session: [sFileSettings] :: Settings -> FileSettings
- GHC.Driver.Session: [sGhcNameVersion] :: Settings -> {-# UNPACK #-} !GhcNameVersion
+ GHC.Driver.Session: [sGhcNameVersion] :: Settings -> GhcNameVersion
- GHC.Driver.Session: [sPlatformMisc] :: Settings -> {-# UNPACK #-} !PlatformMisc
+ GHC.Driver.Session: [sPlatformMisc] :: Settings -> PlatformMisc
- GHC.Driver.Session: [sToolSettings] :: Settings -> {-# UNPACK #-} !ToolSettings
+ GHC.Driver.Session: [sToolSettings] :: Settings -> ToolSettings
- GHC.Driver.Session: [toolSettings] :: DynFlags -> {-# UNPACK #-} !ToolSettings
+ GHC.Driver.Session: [toolSettings] :: DynFlags -> ToolSettings
- GHC.Driver.Session: [unfoldingOpts] :: DynFlags -> !UnfoldingOpts
+ GHC.Driver.Session: [unfoldingOpts] :: DynFlags -> UnfoldingOpts
- GHC.Driver.Session: impliedXFlags :: [(Extension, TurnOnFlag, Extension)]
+ GHC.Driver.Session: impliedXFlags :: [(Extension, OnOff Extension)]
- GHC.Driver.Session: makeDynFlagsConsistent :: DynFlags -> (DynFlags, [Warn])
+ GHC.Driver.Session: makeDynFlagsConsistent :: DynFlags -> (DynFlags, [Warn], [Located SDoc])
- GHC.Driver.Session: parseDynamicFilePragma :: MonadIO m => DynFlags -> [Located String] -> m (DynFlags, [Located String], Messages DriverMessage)
+ GHC.Driver.Session: parseDynamicFilePragma :: MonadIO m => Logger -> DynFlags -> [Located String] -> m (DynFlags, [Located String], Messages DriverMessage)
- GHC.Driver.Session: parseDynamicFlagsCmdLine :: MonadIO m => DynFlags -> [Located String] -> m (DynFlags, [Located String], Messages DriverMessage)
+ GHC.Driver.Session: parseDynamicFlagsCmdLine :: MonadIO m => Logger -> DynFlags -> [Located String] -> m (DynFlags, [Located String], Messages DriverMessage)
- GHC.Driver.Session: parseDynamicFlagsFull :: MonadIO m => [Flag (CmdLineP DynFlags)] -> Bool -> DynFlags -> [Located String] -> m (DynFlags, [Located String], Messages DriverMessage)
+ GHC.Driver.Session: parseDynamicFlagsFull :: MonadIO m => [Flag (CmdLineP DynFlags)] -> Bool -> Logger -> DynFlags -> [Located String] -> m (DynFlags, [Located String], Messages DriverMessage)
- GHC.Hs: XModule :: !XXModule p -> HsModule p
+ GHC.Hs: XModule :: XXModule p -> HsModule p
- GHC.Hs.Binds: AnnSpecSig :: EpaLocation -> EpToken "#-}" -> TokDcolon -> ActivationAnn -> AnnSpecSig
+ GHC.Hs.Binds: AnnSpecSig :: EpaLocation -> EpToken "#-}" -> Maybe TokDcolon -> ActivationAnn -> AnnSpecSig
- GHC.Hs.Binds: [ass_dcolon] :: AnnSpecSig -> TokDcolon
+ GHC.Hs.Binds: [ass_dcolon] :: AnnSpecSig -> Maybe TokDcolon
- GHC.Hs.Binds: pprMinimalSig :: OutputableBndr name => LBooleanFormula (GenLocated l name) -> SDoc
+ GHC.Hs.Binds: pprMinimalSig :: forall (p :: Pass). OutputableBndrId p => LBooleanFormula (GhcPass p) -> SDoc
- GHC.Hs.Decls: ConDeclGADT :: XConDeclGADT pass -> NonEmpty (LIdP pass) -> XRec pass (HsOuterSigTyVarBndrs pass) -> Maybe (LHsContext pass) -> HsConDeclGADTDetails pass -> LHsType pass -> Maybe (LHsDoc pass) -> ConDecl pass
+ GHC.Hs.Decls: ConDeclGADT :: XConDeclGADT pass -> NonEmpty (LIdP pass) -> XRec pass (HsOuterSigTyVarBndrs pass) -> [HsForAllTelescope pass] -> Maybe (LHsContext pass) -> HsConDeclGADTDetails pass -> LHsType pass -> Maybe (LHsDoc pass) -> ConDecl pass
- GHC.Hs.Decls: HsRule :: XHsRule pass -> XRec pass RuleName -> Activation -> Maybe [LHsTyVarBndr () (NoGhcTc pass)] -> [LRuleBndr pass] -> XRec pass (HsExpr pass) -> XRec pass (HsExpr pass) -> RuleDecl pass
+ GHC.Hs.Decls: HsRule :: XHsRule pass -> XRec pass RuleName -> Activation -> RuleBndrs pass -> XRec pass (HsExpr pass) -> XRec pass (HsExpr pass) -> RuleDecl pass
- GHC.Hs.Decls: PrefixConGADT :: !XPrefixConGADT pass -> [HsScaled pass (LBangType pass)] -> HsConDeclGADTDetails pass
+ GHC.Hs.Decls: PrefixConGADT :: XPrefixConGADT pass -> [HsConDeclField pass] -> HsConDeclGADTDetails pass
- GHC.Hs.Decls: RecConGADT :: !XRecConGADT pass -> XRec pass [LConDeclField pass] -> HsConDeclGADTDetails pass
+ GHC.Hs.Decls: RecConGADT :: XRecConGADT pass -> XRec pass [LHsConDeclRecField pass] -> HsConDeclGADTDetails pass
- GHC.Hs.Decls: XAnnDecl :: !XXAnnDecl pass -> AnnDecl pass
+ GHC.Hs.Decls: XAnnDecl :: XXAnnDecl pass -> AnnDecl pass
- GHC.Hs.Decls: XClsInstDecl :: !XXClsInstDecl pass -> ClsInstDecl pass
+ GHC.Hs.Decls: XClsInstDecl :: XXClsInstDecl pass -> ClsInstDecl pass
- GHC.Hs.Decls: XConDecl :: !XXConDecl pass -> ConDecl pass
+ GHC.Hs.Decls: XConDecl :: XXConDecl pass -> ConDecl pass
- GHC.Hs.Decls: XConDeclGADTDetails :: !XXConDeclGADTDetails pass -> HsConDeclGADTDetails pass
+ GHC.Hs.Decls: XConDeclGADTDetails :: XXConDeclGADTDetails pass -> HsConDeclGADTDetails pass
- GHC.Hs.Decls: XDefaultDecl :: !XXDefaultDecl pass -> DefaultDecl pass
+ GHC.Hs.Decls: XDefaultDecl :: XXDefaultDecl pass -> DefaultDecl pass
- GHC.Hs.Decls: XDerivClauseTys :: !XXDerivClauseTys pass -> DerivClauseTys pass
+ GHC.Hs.Decls: XDerivClauseTys :: XXDerivClauseTys pass -> DerivClauseTys pass
- GHC.Hs.Decls: XDerivDecl :: !XXDerivDecl pass -> DerivDecl pass
+ GHC.Hs.Decls: XDerivDecl :: XXDerivDecl pass -> DerivDecl pass
- GHC.Hs.Decls: XFamEqn :: !XXFamEqn pass rhs -> FamEqn pass rhs
+ GHC.Hs.Decls: XFamEqn :: XXFamEqn pass rhs -> FamEqn pass rhs
- GHC.Hs.Decls: XFamilyDecl :: !XXFamilyDecl pass -> FamilyDecl pass
+ GHC.Hs.Decls: XFamilyDecl :: XXFamilyDecl pass -> FamilyDecl pass
- GHC.Hs.Decls: XFamilyResultSig :: !XXFamilyResultSig pass -> FamilyResultSig pass
+ GHC.Hs.Decls: XFamilyResultSig :: XXFamilyResultSig pass -> FamilyResultSig pass
- GHC.Hs.Decls: XForeignDecl :: !XXForeignDecl pass -> ForeignDecl pass
+ GHC.Hs.Decls: XForeignDecl :: XXForeignDecl pass -> ForeignDecl pass
- GHC.Hs.Decls: XForeignExport :: !XXForeignExport pass -> ForeignExport pass
+ GHC.Hs.Decls: XForeignExport :: XXForeignExport pass -> ForeignExport pass
- GHC.Hs.Decls: XForeignImport :: !XXForeignImport pass -> ForeignImport pass
+ GHC.Hs.Decls: XForeignImport :: XXForeignImport pass -> ForeignImport pass
- GHC.Hs.Decls: XFunDep :: !XXFunDep pass -> FunDep pass
+ GHC.Hs.Decls: XFunDep :: XXFunDep pass -> FunDep pass
- GHC.Hs.Decls: XHsDataDefn :: !XXHsDataDefn pass -> HsDataDefn pass
+ GHC.Hs.Decls: XHsDataDefn :: XXHsDataDefn pass -> HsDataDefn pass
- GHC.Hs.Decls: XHsDecl :: !XXHsDecl p -> HsDecl p
+ GHC.Hs.Decls: XHsDecl :: XXHsDecl p -> HsDecl p
- GHC.Hs.Decls: XHsDerivingClause :: !XXHsDerivingClause pass -> HsDerivingClause pass
+ GHC.Hs.Decls: XHsDerivingClause :: XXHsDerivingClause pass -> HsDerivingClause pass
- GHC.Hs.Decls: XHsGroup :: !XXHsGroup p -> HsGroup p
+ GHC.Hs.Decls: XHsGroup :: XXHsGroup p -> HsGroup p
- GHC.Hs.Decls: XInjectivityAnn :: !XXInjectivityAnn pass -> InjectivityAnn pass
+ GHC.Hs.Decls: XInjectivityAnn :: XXInjectivityAnn pass -> InjectivityAnn pass
- GHC.Hs.Decls: XInstDecl :: !XXInstDecl pass -> InstDecl pass
+ GHC.Hs.Decls: XInstDecl :: XXInstDecl pass -> InstDecl pass
- GHC.Hs.Decls: XRoleAnnotDecl :: !XXRoleAnnotDecl pass -> RoleAnnotDecl pass
+ GHC.Hs.Decls: XRoleAnnotDecl :: XXRoleAnnotDecl pass -> RoleAnnotDecl pass
- GHC.Hs.Decls: XRuleBndr :: !XXRuleBndr pass -> RuleBndr pass
+ GHC.Hs.Decls: XRuleBndr :: XXRuleBndr pass -> RuleBndr pass
- GHC.Hs.Decls: XRuleDecl :: !XXRuleDecl pass -> RuleDecl pass
+ GHC.Hs.Decls: XRuleDecl :: XXRuleDecl pass -> RuleDecl pass
- GHC.Hs.Decls: XRuleDecls :: !XXRuleDecls pass -> RuleDecls pass
+ GHC.Hs.Decls: XRuleDecls :: XXRuleDecls pass -> RuleDecls pass
- GHC.Hs.Decls: XSpliceDecl :: !XXSpliceDecl p -> SpliceDecl p
+ GHC.Hs.Decls: XSpliceDecl :: XXSpliceDecl p -> SpliceDecl p
- GHC.Hs.Decls: XStandaloneKindSig :: !XXStandaloneKindSig pass -> StandaloneKindSig pass
+ GHC.Hs.Decls: XStandaloneKindSig :: XXStandaloneKindSig pass -> StandaloneKindSig pass
- GHC.Hs.Decls: XTyClDecl :: !XXTyClDecl pass -> TyClDecl pass
+ GHC.Hs.Decls: XTyClDecl :: XXTyClDecl pass -> TyClDecl pass
- GHC.Hs.Decls: XTyClGroup :: !XXTyClGroup pass -> TyClGroup pass
+ GHC.Hs.Decls: XTyClGroup :: XXTyClGroup pass -> TyClGroup pass
- GHC.Hs.Decls: XTyFamInstDecl :: !XXTyFamInstDecl pass -> TyFamInstDecl pass
+ GHC.Hs.Decls: XTyFamInstDecl :: XXTyFamInstDecl pass -> TyFamInstDecl pass
- GHC.Hs.Decls: XWarnDecl :: !XXWarnDecl pass -> WarnDecl pass
+ GHC.Hs.Decls: XWarnDecl :: XXWarnDecl pass -> WarnDecl pass
- GHC.Hs.Decls: XWarnDecls :: !XXWarnDecls pass -> WarnDecls pass
+ GHC.Hs.Decls: XWarnDecls :: XXWarnDecls pass -> WarnDecls pass
- GHC.Hs.Decls: familyDeclLName :: forall (p :: Pass). FamilyDecl (GhcPass p) -> XRec (GhcPass p) (IdP (GhcPass p))
+ GHC.Hs.Decls: familyDeclLName :: forall (p :: Pass). FamilyDecl (GhcPass p) -> XRecGhc (IdGhcP p)
- GHC.Hs.Decls: getRecConArgs_maybe :: ConDecl GhcRn -> Maybe (LocatedL [LConDeclField GhcRn])
+ GHC.Hs.Decls: getRecConArgs_maybe :: ConDecl GhcRn -> Maybe (LocatedL [LHsConDeclRecField GhcRn])
- GHC.Hs.Decls: hsGroupInstDecls :: HsGroup id -> [LInstDecl id]
+ GHC.Hs.Decls: hsGroupInstDecls :: forall (p :: Pass). HsGroup (GhcPass p) -> [LInstDecl (GhcPass p)]
- GHC.Hs.Decls: pp_vanilla_decl_head :: forall (p :: Pass). OutputableBndrId p => XRec (GhcPass p) (IdP (GhcPass p)) -> LHsQTyVars (GhcPass p) -> LexicalFixity -> Maybe (LHsContext (GhcPass p)) -> SDoc
+ GHC.Hs.Decls: pp_vanilla_decl_head :: forall (p :: Pass). OutputableBndrId p => XRecGhc (IdGhcP p) -> LHsQTyVars (GhcPass p) -> LexicalFixity -> Maybe (LHsContext (GhcPass p)) -> SDoc
- GHC.Hs.Decls: tyClDeclTyVars :: TyClDecl pass -> LHsQTyVars pass
+ GHC.Hs.Decls: tyClDeclTyVars :: forall (p :: Pass). TyClDecl (GhcPass p) -> LHsQTyVars (GhcPass p)
- GHC.Hs.Decls: tyClGroupInstDecls :: [TyClGroup pass] -> [LInstDecl pass]
+ GHC.Hs.Decls: tyClGroupInstDecls :: forall (p :: Pass). [TyClGroup (GhcPass p)] -> [LInstDecl (GhcPass p)]
- GHC.Hs.Decls: tyClGroupKindSigs :: [TyClGroup pass] -> [LStandaloneKindSig pass]
+ GHC.Hs.Decls: tyClGroupKindSigs :: forall (p :: Pass). [TyClGroup (GhcPass p)] -> [LStandaloneKindSig (GhcPass p)]
- GHC.Hs.Decls: tyClGroupRoleDecls :: [TyClGroup pass] -> [LRoleAnnotDecl pass]
+ GHC.Hs.Decls: tyClGroupRoleDecls :: forall (p :: Pass). [TyClGroup (GhcPass p)] -> [LRoleAnnotDecl (GhcPass p)]
- GHC.Hs.Decls: tyClGroupTyClDecls :: [TyClGroup pass] -> [LTyClDecl pass]
+ GHC.Hs.Decls: tyClGroupTyClDecls :: forall (p :: Pass). [TyClGroup (GhcPass p)] -> [LTyClDecl (GhcPass p)]
- GHC.Hs.Decls: type HsConDeclH98Details pass = HsConDetails Void HsScaled pass LBangType pass XRec pass [LConDeclField pass]
+ GHC.Hs.Decls: type HsConDeclH98Details pass = HsConDetails HsConDeclField pass XRec pass [LHsConDeclRecField pass]
- GHC.Hs.Doc: DsiDocChunk :: !HsDoc GhcRn -> DocStructureItem
+ GHC.Hs.Doc: DsiDocChunk :: HsDoc GhcRn -> DocStructureItem
- GHC.Hs.Doc: DsiExports :: !DetOrdAvails -> DocStructureItem
+ GHC.Hs.Doc: DsiExports :: DetOrdAvails -> DocStructureItem
- GHC.Hs.Doc: DsiModExport :: !NonEmpty ModuleName -> !DetOrdAvails -> DocStructureItem
+ GHC.Hs.Doc: DsiModExport :: NonEmpty ModuleName -> DetOrdAvails -> DocStructureItem
- GHC.Hs.Doc: DsiNamedChunkRef :: !String -> DocStructureItem
+ GHC.Hs.Doc: DsiNamedChunkRef :: String -> DocStructureItem
- GHC.Hs.Doc: DsiSectionHeading :: !Int -> !HsDoc GhcRn -> DocStructureItem
+ GHC.Hs.Doc: DsiSectionHeading :: Int -> HsDoc GhcRn -> DocStructureItem
- GHC.Hs.Doc: WithHsDocIdentifiers :: !a -> ![Located (IdP pass)] -> WithHsDocIdentifiers a pass
+ GHC.Hs.Doc: WithHsDocIdentifiers :: a -> [Located (IdP pass)] -> WithHsDocIdentifiers a pass
- GHC.Hs.Doc: [hsDocIdentifiers] :: WithHsDocIdentifiers a pass -> ![Located (IdP pass)]
+ GHC.Hs.Doc: [hsDocIdentifiers] :: WithHsDocIdentifiers a pass -> [Located (IdP pass)]
- GHC.Hs.Doc: [hsDocString] :: WithHsDocIdentifiers a pass -> !a
+ GHC.Hs.Doc: [hsDocString] :: WithHsDocIdentifiers a pass -> a
- GHC.Hs.DocString: HsDocStringGroup :: !Int -> HsDocStringDecorator
+ GHC.Hs.DocString: HsDocStringGroup :: Int -> HsDocStringDecorator
- GHC.Hs.DocString: HsDocStringNamed :: !String -> HsDocStringDecorator
+ GHC.Hs.DocString: HsDocStringNamed :: String -> HsDocStringDecorator
- GHC.Hs.DocString: MultiLineDocString :: !HsDocStringDecorator -> !NonEmpty LHsDocStringChunk -> HsDocString
+ GHC.Hs.DocString: MultiLineDocString :: HsDocStringDecorator -> NonEmpty LHsDocStringChunk -> HsDocString
- GHC.Hs.DocString: NestedDocString :: !HsDocStringDecorator -> LHsDocStringChunk -> HsDocString
+ GHC.Hs.DocString: NestedDocString :: HsDocStringDecorator -> LHsDocStringChunk -> HsDocString
- GHC.Hs.Expr: PendingRnSplice :: UntypedSpliceFlavour -> SplicePointName -> LHsExpr GhcRn -> PendingRnSplice
+ GHC.Hs.Expr: PendingRnSplice :: SplicePointName -> HsUntypedSplice GhcRn -> PendingRnSplice
- GHC.Hs.Expr: PopErrCtxt :: {-# UNPACK #-} !LHsExpr GhcRn -> XXExprGhcRn
+ GHC.Hs.Expr: PopErrCtxt :: LHsExpr GhcRn -> XXExprGhcRn
- GHC.Hs.Expr: XApplicativeArg :: !XXApplicativeArg idL -> ApplicativeArg idL
+ GHC.Hs.Expr: XApplicativeArg :: XXApplicativeArg idL -> ApplicativeArg idL
- GHC.Hs.Expr: pprMatchContext :: Outputable fn => HsMatchContext fn -> SDoc
+ GHC.Hs.Expr: pprMatchContext :: Outputable p => HsMatchContext p -> SDoc
- GHC.Hs.Expr: pprTypedSplice :: forall (p :: Pass). OutputableBndrId p => Maybe SplicePointName -> LHsExpr (GhcPass p) -> SDoc
+ GHC.Hs.Expr: pprTypedSplice :: forall (p :: Pass). OutputableBndrId p => Maybe SplicePointName -> HsTypedSplice (GhcPass p) -> SDoc
- GHC.Hs.Extension: type IsSrcSpanAnn (p :: Pass) a = (Anno IdGhcP p ~ EpAnn a, NoAnn a, IsPass p)
+ GHC.Hs.Extension: type IsSrcSpanAnn (p :: Pass) a = (Anno IdGhcP p ~ EpAnn a, Anno IdOccGhcP p ~ EpAnn a, NoAnn a, IsPass p)
- GHC.Hs.Extension: type OutputableBndrId (pass :: Pass) = (OutputableBndr IdGhcP pass, OutputableBndr IdGhcP NoGhcTcPass pass, Outputable GenLocated Anno IdGhcP pass IdGhcP pass, Outputable GenLocated Anno IdGhcP NoGhcTcPass pass IdGhcP NoGhcTcPass pass, IsPass pass)
+ GHC.Hs.Extension: type OutputableBndrId (pass :: Pass) = (OutputableBndr IdGhcP pass, OutputableBndr IdOccGhcP pass, OutputableBndr IdGhcP NoGhcTcPass pass, OutputableBndr IdOccGhcP NoGhcTcPass pass, Outputable LIdGhcP pass, Outputable LIdOccGhcP pass, Outputable LIdGhcP NoGhcTcPass pass, Outputable LIdOccGhcP NoGhcTcPass pass, IsPass pass)
- GHC.Hs.ImpExp: EpAnnImportDecl :: EpToken "import" -> Maybe (EpaLocation, EpToken "#-}") -> Maybe (EpToken "safe") -> Maybe (EpToken "qualified") -> Maybe EpaLocation -> Maybe (EpToken "as") -> EpAnnImportDecl
+ GHC.Hs.ImpExp: EpAnnImportDecl :: EpToken "import" -> Maybe (EpaLocation, EpToken "#-}") -> Maybe (EpToken "safe") -> Maybe EpAnnLevel -> Maybe (EpToken "qualified") -> Maybe EpaLocation -> Maybe (EpToken "as") -> EpAnnImportDecl
- GHC.Hs.Lit: convertLit :: forall (p1 :: Pass) (p2 :: Pass). HsLit (GhcPass p1) -> HsLit (GhcPass p2)
+ GHC.Hs.Lit: convertLit :: forall (p :: Pass) (p' :: Pass). XXLit (GhcPass p) ~ DataConCantHappen => HsLit (GhcPass p) -> HsLit (GhcPass p')
- GHC.Hs.Lit: hsLitNeedsParens :: PprPrec -> HsLit x -> Bool
+ GHC.Hs.Lit: hsLitNeedsParens :: forall (x :: Pass). IsPass x => PprPrec -> HsLit (GhcPass x) -> Bool
- GHC.Hs.Lit: pmPprHsLit :: forall (x :: Pass). HsLit (GhcPass x) -> SDoc
+ GHC.Hs.Lit: pmPprHsLit :: forall (p :: Pass). IsPass p => HsLit (GhcPass p) -> SDoc
- GHC.Hs.Pat: HsRecFields :: !XHsRecFields p -> [LHsRecField p arg] -> Maybe (XRec p RecFieldsDotDot) -> HsRecFields p arg
+ GHC.Hs.Pat: HsRecFields :: XHsRecFields p -> [LHsRecField p arg] -> Maybe (XRec p RecFieldsDotDot) -> HsRecFields p arg
- GHC.Hs.Pat: XPat :: !XXPat p -> Pat p
+ GHC.Hs.Pat: XPat :: XXPat p -> Pat p
- GHC.Hs.Pat: [rec_ext] :: HsRecFields p arg -> !XHsRecFields p
+ GHC.Hs.Pat: [rec_ext] :: HsRecFields p arg -> XHsRecFields p
- GHC.Hs.Pat: hsRecFieldSel :: UnXRec p => HsRecField p arg -> IdP p
+ GHC.Hs.Pat: hsRecFieldSel :: forall (p :: Pass) arg. HsRecField (GhcPass p) arg -> IdGhcP p
- GHC.Hs.Pat: hsRecFields :: UnXRec p => HsRecFields p arg -> [IdP p]
+ GHC.Hs.Pat: hsRecFields :: forall (p :: Pass) arg. HsRecFields (GhcPass p) arg -> [IdGhcP p]
- GHC.Hs.Pat: hsRecFieldsArgs :: UnXRec p => HsRecFields p arg -> [arg]
+ GHC.Hs.Pat: hsRecFieldsArgs :: forall (p :: Pass) arg. HsRecFields (GhcPass p) arg -> [arg]
- GHC.Hs.Pat: type HsConPatDetails p = HsConDetails HsConPatTyArg NoGhcTc p LPat p HsRecFields p LPat p
+ GHC.Hs.Pat: type HsConPatDetails p = HsConDetails LPat p HsRecFields p LPat p
- GHC.Hs.Syn.Type: hsLitType :: forall (p :: Pass). HsLit (GhcPass p) -> Type
+ GHC.Hs.Syn.Type: hsLitType :: forall (p :: Pass). IsPass p => HsLit (GhcPass p) -> Type
- GHC.Hs.Type: EpLolly :: !EpToken "\8888" -> EpLinearArrow
+ GHC.Hs.Type: EpLolly :: EpToken "\8888" -> EpLinear
- GHC.Hs.Type: EpPct1 :: !EpToken "%1" -> !TokRarrow -> EpLinearArrow
+ GHC.Hs.Type: EpPct1 :: EpToken "%1" -> EpArrowOrColon -> EpLinear
- GHC.Hs.Type: HsArgPar :: !XArgPar p -> HsArg p tm ty
+ GHC.Hs.Type: HsArgPar :: XArgPar p -> HsArg p tm ty
- GHC.Hs.Type: HsBangTy :: XBangTy pass -> HsBang -> LHsType pass -> HsType pass
+ GHC.Hs.Type: HsBangTy :: (EpaLocation, EpToken "#-}", EpaLocation) -> HsSrcBang -> LHsType GhcPs -> HsTypeGhcPsExt
- GHC.Hs.Type: HsBndrInvisible :: !XBndrInvisible pass -> HsBndrVis pass
+ GHC.Hs.Type: HsBndrInvisible :: XBndrInvisible pass -> HsBndrVis pass
- GHC.Hs.Type: HsBndrKind :: !XBndrKind pass -> LHsKind pass -> HsBndrKind pass
+ GHC.Hs.Type: HsBndrKind :: XBndrKind pass -> LHsKind pass -> HsBndrKind pass
- GHC.Hs.Type: HsBndrNoKind :: !XBndrNoKind pass -> HsBndrKind pass
+ GHC.Hs.Type: HsBndrNoKind :: XBndrNoKind pass -> HsBndrKind pass
- GHC.Hs.Type: HsBndrRequired :: !XBndrRequired pass -> HsBndrVis pass
+ GHC.Hs.Type: HsBndrRequired :: XBndrRequired pass -> HsBndrVis pass
- GHC.Hs.Type: HsBndrVar :: !XBndrVar pass -> !LIdP pass -> HsBndrVar pass
+ GHC.Hs.Type: HsBndrVar :: XBndrVar pass -> LIdP pass -> HsBndrVar pass
- GHC.Hs.Type: HsBndrWildCard :: !XBndrWildCard pass -> HsBndrVar pass
+ GHC.Hs.Type: HsBndrWildCard :: XBndrWildCard pass -> HsBndrVar pass
- GHC.Hs.Type: HsExplicitMult :: !XExplicitMult mult pass -> !mult -> HsArrowOf mult pass
+ GHC.Hs.Type: HsExplicitMult :: XExplicitMult mult pass -> mult -> HsMultAnnOf mult pass
- GHC.Hs.Type: HsFunTy :: XFunTy pass -> HsArrow pass -> LHsType pass -> LHsType pass -> HsType pass
+ GHC.Hs.Type: HsFunTy :: XFunTy pass -> HsMultAnn pass -> LHsType pass -> LHsType pass -> HsType pass
- GHC.Hs.Type: HsOpTy :: XOpTy pass -> PromotionFlag -> LHsType pass -> LIdP pass -> LHsType pass -> HsType pass
+ GHC.Hs.Type: HsOpTy :: XOpTy pass -> PromotionFlag -> LHsType pass -> LIdOccP pass -> LHsType pass -> HsType pass
- GHC.Hs.Type: HsRecTy :: XRecTy pass -> [LConDeclField pass] -> HsType pass
+ GHC.Hs.Type: HsRecTy :: AnnList () -> [LHsConDeclRecField GhcPs] -> HsTypeGhcPsExt
- GHC.Hs.Type: HsSrcBang :: SourceText -> HsBang -> HsSrcBang
+ GHC.Hs.Type: HsSrcBang :: SourceText -> SrcUnpackedness -> SrcStrictness -> HsSrcBang
- GHC.Hs.Type: HsTyVar :: XTyVar pass -> PromotionFlag -> LIdP pass -> HsType pass
+ GHC.Hs.Type: HsTyVar :: XTyVar pass -> PromotionFlag -> LIdOccP pass -> HsType pass
- GHC.Hs.Type: HsTypeArg :: !XTypeArg p -> ty -> HsArg p tm ty
+ GHC.Hs.Type: HsTypeArg :: XTypeArg p -> ty -> HsArg p tm ty
- GHC.Hs.Type: HsValArg :: !XValArg p -> tm -> HsArg p tm ty
+ GHC.Hs.Type: HsValArg :: XValArg p -> tm -> HsArg p tm ty
- GHC.Hs.Type: InfixCon :: arg -> arg -> HsConDetails tyarg arg rec
+ GHC.Hs.Type: InfixCon :: arg -> arg -> HsConDetails arg rec
- GHC.Hs.Type: NormalOp :: Name -> OpName
+ GHC.Hs.Type: NormalOp :: WithUserRdr Name -> OpName
- GHC.Hs.Type: PrefixCon :: [tyarg] -> [arg] -> HsConDetails tyarg arg rec
+ GHC.Hs.Type: PrefixCon :: [arg] -> HsConDetails arg rec
- GHC.Hs.Type: RecCon :: rec -> HsConDetails tyarg arg rec
+ GHC.Hs.Type: RecCon :: rec -> HsConDetails arg rec
- GHC.Hs.Type: XArg :: !XXArg p -> HsArg p tm ty
+ GHC.Hs.Type: XArg :: XXArg p -> HsArg p tm ty
- GHC.Hs.Type: XBndrKind :: !XXBndrKind pass -> HsBndrKind pass
+ GHC.Hs.Type: XBndrKind :: XXBndrKind pass -> HsBndrKind pass
- GHC.Hs.Type: XBndrVar :: !XXBndrVar pass -> HsBndrVar pass
+ GHC.Hs.Type: XBndrVar :: XXBndrVar pass -> HsBndrVar pass
- GHC.Hs.Type: XBndrVis :: !XXBndrVis pass -> HsBndrVis pass
+ GHC.Hs.Type: XBndrVis :: XXBndrVis pass -> HsBndrVis pass
- GHC.Hs.Type: XFieldOcc :: !XXFieldOcc pass -> FieldOcc pass
+ GHC.Hs.Type: XFieldOcc :: XXFieldOcc pass -> FieldOcc pass
- GHC.Hs.Type: XHsForAllTelescope :: !XXHsForAllTelescope pass -> HsForAllTelescope pass
+ GHC.Hs.Type: XHsForAllTelescope :: XXHsForAllTelescope pass -> HsForAllTelescope pass
- GHC.Hs.Type: XHsOuterTyVarBndrs :: !XXHsOuterTyVarBndrs pass -> HsOuterTyVarBndrs flag pass
+ GHC.Hs.Type: XHsOuterTyVarBndrs :: XXHsOuterTyVarBndrs pass -> HsOuterTyVarBndrs flag pass
- GHC.Hs.Type: XHsPatSigType :: !XXHsPatSigType pass -> HsPatSigType pass
+ GHC.Hs.Type: XHsPatSigType :: XXHsPatSigType pass -> HsPatSigType pass
- GHC.Hs.Type: XHsSigType :: !XXHsSigType pass -> HsSigType pass
+ GHC.Hs.Type: XHsSigType :: XXHsSigType pass -> HsSigType pass
- GHC.Hs.Type: XHsTyPat :: !XXHsTyPat pass -> HsTyPat pass
+ GHC.Hs.Type: XHsTyPat :: XXHsTyPat pass -> HsTyPat pass
- GHC.Hs.Type: XHsType :: !XXType pass -> HsType pass
+ GHC.Hs.Type: XHsType :: XXType pass -> HsType pass
- GHC.Hs.Type: XHsWildCardBndrs :: !XXHsWildCardBndrs pass thing -> HsWildCardBndrs pass thing
+ GHC.Hs.Type: XHsWildCardBndrs :: XXHsWildCardBndrs pass thing -> HsWildCardBndrs pass thing
- GHC.Hs.Type: XLHsQTyVars :: !XXLHsQTyVars pass -> LHsQTyVars pass
+ GHC.Hs.Type: XLHsQTyVars :: XXLHsQTyVars pass -> LHsQTyVars pass
- GHC.Hs.Type: XTyLit :: !XXTyLit pass -> HsTyLit pass
+ GHC.Hs.Type: XTyLit :: XXTyLit pass -> HsTyLit pass
- GHC.Hs.Type: XTyVarBndr :: !XXTyVarBndr pass -> HsTyVarBndr flag pass
+ GHC.Hs.Type: XTyVarBndr :: XXTyVarBndr pass -> HsTyVarBndr flag pass
- GHC.Hs.Type: data HsConDetails tyarg arg rec
+ GHC.Hs.Type: data HsConDetails arg rec
- GHC.Hs.Type: dropWildCards :: LHsSigWcType pass -> LHsSigType pass
+ GHC.Hs.Type: dropWildCards :: forall (p :: Pass). LHsSigWcType (GhcPass p) -> LHsSigType (GhcPass p)
- GHC.Hs.Type: getLHsInstDeclClass_maybe :: forall (p :: Pass). Anno (IdGhcP p) ~ SrcSpanAnnN => LHsSigType (GhcPass p) -> Maybe (LocatedN (IdP (GhcPass p)))
+ GHC.Hs.Type: getLHsInstDeclClass_maybe :: forall (p :: Pass). Anno (IdOccGhcP p) ~ SrcSpanAnnN => LHsSigType (GhcPass p) -> Maybe (LocatedN (IdOccP (GhcPass p)))
- GHC.Hs.Type: hsPatSigType :: HsPatSigType pass -> LHsType pass
+ GHC.Hs.Type: hsPatSigType :: forall (p :: Pass). HsPatSigType (GhcPass p) -> LHsType (GhcPass p)
- GHC.Hs.Type: hsSigWcType :: UnXRec p => LHsSigWcType p -> LHsType p
+ GHC.Hs.Type: hsSigWcType :: forall (p :: Pass). LHsSigWcType (GhcPass p) -> LHsType (GhcPass p)
- GHC.Hs.Type: hsTyGetAppHead_maybe :: forall (p :: Pass). Anno (IdGhcP p) ~ SrcSpanAnnN => LHsType (GhcPass p) -> Maybe (LocatedN (IdP (GhcPass p)))
+ GHC.Hs.Type: hsTyGetAppHead_maybe :: forall (p :: Pass). Anno (IdOccGhcP p) ~ SrcSpanAnnN => LHsType (GhcPass p) -> Maybe (LocatedN (IdOccP (GhcPass p)))
- GHC.Hs.Type: hsTypeNeedsParens :: forall (p :: Pass). PprPrec -> HsType (GhcPass p) -> Bool
+ GHC.Hs.Type: hsTypeNeedsParens :: forall (p :: Pass). IsPass p => PprPrec -> HsType (GhcPass p) -> Bool
- GHC.Hs.Type: mkHsOpTy :: forall (p :: Pass). Anno (IdGhcP p) ~ SrcSpanAnnN => PromotionFlag -> LHsType (GhcPass p) -> LocatedN (IdP (GhcPass p)) -> LHsType (GhcPass p) -> HsType (GhcPass p)
+ GHC.Hs.Type: mkHsOpTy :: forall (p :: Pass). Anno (IdOccGhcP p) ~ SrcSpanAnnN => PromotionFlag -> LHsType (GhcPass p) -> LocatedN (IdOccP (GhcPass p)) -> LHsType (GhcPass p) -> HsType (GhcPass p)
- GHC.Hs.Type: parenthesizeHsContext :: forall (p :: Pass). PprPrec -> LHsContext (GhcPass p) -> LHsContext (GhcPass p)
+ GHC.Hs.Type: parenthesizeHsContext :: forall (p :: Pass). IsPass p => PprPrec -> LHsContext (GhcPass p) -> LHsContext (GhcPass p)
- GHC.Hs.Type: parenthesizeHsType :: forall (p :: Pass). PprPrec -> LHsType (GhcPass p) -> LHsType (GhcPass p)
+ GHC.Hs.Type: parenthesizeHsType :: forall (p :: Pass). IsPass p => PprPrec -> LHsType (GhcPass p) -> LHsType (GhcPass p)
- GHC.Hs.Type: pprHsArrow :: forall mult (pass :: Pass). (Outputable mult, OutputableBndrId pass) => HsArrowOf mult (GhcPass pass) -> SDoc
+ GHC.Hs.Type: pprHsArrow :: forall mult (pass :: Pass). (Outputable mult, OutputableBndrId pass) => HsMultAnnOf mult (GhcPass pass) -> SDoc
- GHC.Hs.Type: splitHsFunType :: forall (p :: Pass). LHsType (GhcPass p) -> (([EpToken "("], [EpToken ")"]), EpAnnComments, [HsScaled (GhcPass p) (LHsType (GhcPass p))], LHsType (GhcPass p))
+ GHC.Hs.Type: splitHsFunType :: LHsType GhcPs -> (([EpToken "("], [EpToken ")"]), EpAnnComments, [HsConDeclField GhcPs], LHsType GhcPs)
- GHC.Hs.Type: splitLHsGadtTy :: LHsSigType GhcPs -> (HsOuterSigTyVarBndrs GhcPs, Maybe (LHsContext GhcPs), LHsType GhcPs)
+ GHC.Hs.Type: splitLHsGadtTy :: LHsSigType GhcPs -> (HsOuterSigTyVarBndrs GhcPs, [HsForAllTelescope GhcPs], Maybe (LHsContext GhcPs), LHsType GhcPs)
- GHC.Hs.Utils: TyDeclBinders :: !(LocatedA (IdP (GhcPass p)), TyConFlavour ()) -> ![(LocatedA (IdP (GhcPass p)), TyConFlavour ())] -> ![LocatedA (IdP (GhcPass p))] -> !LConsWithFields p -> TyDeclBinders (p :: Pass)
+ GHC.Hs.Utils: TyDeclBinders :: (LocatedA (IdP (GhcPass p)), TyConFlavour ()) -> [(LocatedA (IdP (GhcPass p)), TyConFlavour ())] -> [LocatedA (IdP (GhcPass p))] -> LConsWithFields p -> TyDeclBinders (p :: Pass)
- GHC.Hs.Utils: [tyDeclATs] :: TyDeclBinders (p :: Pass) -> ![(LocatedA (IdP (GhcPass p)), TyConFlavour ())]
+ GHC.Hs.Utils: [tyDeclATs] :: TyDeclBinders (p :: Pass) -> [(LocatedA (IdP (GhcPass p)), TyConFlavour ())]
- GHC.Hs.Utils: [tyDeclConsWithFields] :: TyDeclBinders (p :: Pass) -> !LConsWithFields p
+ GHC.Hs.Utils: [tyDeclConsWithFields] :: TyDeclBinders (p :: Pass) -> LConsWithFields p
- GHC.Hs.Utils: [tyDeclMainBinder] :: TyDeclBinders (p :: Pass) -> !(LocatedA (IdP (GhcPass p)), TyConFlavour ())
+ GHC.Hs.Utils: [tyDeclMainBinder] :: TyDeclBinders (p :: Pass) -> (LocatedA (IdP (GhcPass p)), TyConFlavour ())
- GHC.Hs.Utils: [tyDeclOpSigs] :: TyDeclBinders (p :: Pass) -> ![LocatedA (IdP (GhcPass p))]
+ GHC.Hs.Utils: [tyDeclOpSigs] :: TyDeclBinders (p :: Pass) -> [LocatedA (IdP (GhcPass p))]
- GHC.Hs.Utils: isInfixFunBind :: forall id1 id2. UnXRec id2 => HsBindLR id1 id2 -> Bool
+ GHC.Hs.Utils: isInfixFunBind :: forall (p1 :: Pass) (p2 :: Pass). HsBindLR (GhcPass p1) (GhcPass p2) -> Bool
- GHC.Hs.Utils: nlHsTyConApp :: forall (p :: Pass) a. IsSrcSpanAnn p a => PromotionFlag -> LexicalFixity -> IdP (GhcPass p) -> [LHsTypeArg (GhcPass p)] -> LHsType (GhcPass p)
+ GHC.Hs.Utils: nlHsTyConApp :: forall (p :: Pass) a. IsSrcSpanAnn p a => PromotionFlag -> LexicalFixity -> IdOccP (GhcPass p) -> [LHsTypeArg (GhcPass p)] -> LHsType (GhcPass p)
- GHC.Hs.Utils: unguardedRHS :: forall (p :: Pass) body. Anno (GRHS (GhcPass p) (LocatedA (body (GhcPass p)))) ~ EpAnn NoEpAnns => EpAnn GrhsAnn -> SrcSpan -> LocatedA (body (GhcPass p)) -> [LGRHS (GhcPass p) (LocatedA (body (GhcPass p)))]
+ GHC.Hs.Utils: unguardedRHS :: forall (p :: Pass) body. Anno (GRHS (GhcPass p) (LocatedA (body (GhcPass p)))) ~ EpAnn NoEpAnns => EpAnn GrhsAnn -> SrcSpan -> LocatedA (body (GhcPass p)) -> NonEmpty (LGRHS (GhcPass p) (LocatedA (body (GhcPass p))))
- GHC.HsToCore.Breakpoints: mkModBreaks :: Interp -> Module -> SizedSeq Tick -> IO ModBreaks
+ GHC.HsToCore.Breakpoints: mkModBreaks :: Bool -> Module -> SizedSeq Tick -> ModBreaks
- GHC.HsToCore.Docs: con_arg_docs :: Int -> [HsType GhcRn] -> IntMap (HsDoc GhcRn)
+ GHC.HsToCore.Docs: con_arg_docs :: Int -> [Maybe (LHsDoc GhcRn)] -> IntMap (HsDoc GhcRn)
- GHC.HsToCore.Docs: mkDecls :: (struct -> [GenLocated l decl]) -> (decl -> hsDecl) -> struct -> [GenLocated l hsDecl]
+ GHC.HsToCore.Docs: mkDecls :: (decl -> hsDecl) -> [GenLocated l decl] -> [GenLocated l hsDecl]
- GHC.HsToCore.Errors.Types: DsAnotherRuleMightFireFirst :: !RuleName -> !RuleName -> !Var -> DsMessage
+ GHC.HsToCore.Errors.Types: DsAnotherRuleMightFireFirst :: RuleName -> RuleName -> Var -> DsMessage
- GHC.HsToCore.Errors.Types: DsCannotMixPolyAndUnliftedBindings :: !HsBindLR GhcTc GhcTc -> DsMessage
+ GHC.HsToCore.Errors.Types: DsCannotMixPolyAndUnliftedBindings :: HsBindLR GhcTc GhcTc -> DsMessage
- GHC.HsToCore.Errors.Types: DsIdentitiesFound :: !Id -> !Type -> DsMessage
+ GHC.HsToCore.Errors.Types: DsIdentitiesFound :: Id -> Type -> DsMessage
- GHC.HsToCore.Errors.Types: DsInaccessibleRhs :: !HsMatchContextRn -> !SDoc -> DsMessage
+ GHC.HsToCore.Errors.Types: DsInaccessibleRhs :: HsMatchContextRn -> SDoc -> DsMessage
- GHC.HsToCore.Errors.Types: DsIncompleteRecordSelector :: !Name -> ![ConLike] -> !Bool -> DsMessage
+ GHC.HsToCore.Errors.Types: DsIncompleteRecordSelector :: Name -> [ConLike] -> Int -> DsMessage
- GHC.HsToCore.Errors.Types: DsMaxPmCheckModelsReached :: !MaxPmCheckModels -> DsMessage
+ GHC.HsToCore.Errors.Types: DsMaxPmCheckModelsReached :: MaxPmCheckModels -> DsMessage
- GHC.HsToCore.Errors.Types: DsNonExhaustivePatterns :: !HsMatchContextRn -> !ExhaustivityCheckType -> !MaxUncoveredPatterns -> [Id] -> [Nabla] -> DsMessage
+ GHC.HsToCore.Errors.Types: DsNonExhaustivePatterns :: HsMatchContextRn -> ExhaustivityCheckType -> MaxUncoveredPatterns -> [Id] -> [Nabla] -> DsMessage
- GHC.HsToCore.Errors.Types: DsNotYetHandledByTH :: !ThRejectionReason -> DsMessage
+ GHC.HsToCore.Errors.Types: DsNotYetHandledByTH :: ThRejectionReason -> DsMessage
- GHC.HsToCore.Errors.Types: DsOrphanRule :: !CoreRule -> DsMessage
+ GHC.HsToCore.Errors.Types: DsOrphanRule :: CoreRule -> DsMessage
- GHC.HsToCore.Errors.Types: DsOverflowedLiterals :: !Integer -> !Name -> !Maybe (MinBound, MaxBound) -> !NegLiteralExtEnabled -> DsMessage
+ GHC.HsToCore.Errors.Types: DsOverflowedLiterals :: Integer -> Name -> Maybe (MinBound, MaxBound) -> NegLiteralExtEnabled -> DsMessage
- GHC.HsToCore.Errors.Types: DsOverlappingPatterns :: !HsMatchContextRn -> !SDoc -> DsMessage
+ GHC.HsToCore.Errors.Types: DsOverlappingPatterns :: HsMatchContextRn -> SDoc -> DsMessage
- GHC.HsToCore.Errors.Types: DsRecBindsNotAllowedForUnliftedTys :: ![LHsBindLR GhcTc GhcTc] -> DsMessage
+ GHC.HsToCore.Errors.Types: DsRecBindsNotAllowedForUnliftedTys :: [LHsBindLR GhcTc GhcTc] -> DsMessage
- GHC.HsToCore.Errors.Types: DsRedundantBangPatterns :: !HsMatchContextRn -> !SDoc -> DsMessage
+ GHC.HsToCore.Errors.Types: DsRedundantBangPatterns :: HsMatchContextRn -> SDoc -> DsMessage
- GHC.HsToCore.Errors.Types: DsRuleBindersNotBound :: ![Var] -> ![Var] -> !CoreExpr -> !CoreExpr -> DsMessage
+ GHC.HsToCore.Errors.Types: DsRuleBindersNotBound :: [Var] -> [Var] -> CoreExpr -> CoreExpr -> DsMessage
- GHC.HsToCore.Errors.Types: DsRuleIgnoredDueToConstructor :: !DataCon -> DsMessage
+ GHC.HsToCore.Errors.Types: DsRuleIgnoredDueToConstructor :: DataCon -> DsMessage
- GHC.HsToCore.Errors.Types: DsRuleLhsTooComplicated :: !CoreExpr -> !CoreExpr -> DsMessage
+ GHC.HsToCore.Errors.Types: DsRuleLhsTooComplicated :: CoreExpr -> CoreExpr -> DsMessage
- GHC.HsToCore.Errors.Types: DsRuleMightInlineFirst :: !RuleName -> !Var -> !Activation -> DsMessage
+ GHC.HsToCore.Errors.Types: DsRuleMightInlineFirst :: RuleName -> Var -> Activation -> DsMessage
- GHC.HsToCore.Errors.Types: DsTopLevelBindsNotAllowed :: !BindsType -> !HsBindLR GhcTc GhcTc -> DsMessage
+ GHC.HsToCore.Errors.Types: DsTopLevelBindsNotAllowed :: BindsType -> HsBindLR GhcTc GhcTc -> DsMessage
- GHC.HsToCore.Errors.Types: DsUnbangedStrictPatterns :: !HsBindLR GhcTc GhcTc -> DsMessage
+ GHC.HsToCore.Errors.Types: DsUnbangedStrictPatterns :: HsBindLR GhcTc GhcTc -> DsMessage
- GHC.HsToCore.Errors.Types: DsUnknownMessage :: UnknownDiagnostic (DiagnosticOpts DsMessage) -> DsMessage
+ GHC.HsToCore.Errors.Types: DsUnknownMessage :: UnknownDiagnosticFor DsMessage -> DsMessage
- GHC.HsToCore.Errors.Types: DsUnusedDoBind :: !LHsExpr GhcTc -> !Type -> DsMessage
+ GHC.HsToCore.Errors.Types: DsUnusedDoBind :: LHsExpr GhcTc -> Type -> DsMessage
- GHC.HsToCore.Errors.Types: DsWrongDoBind :: !LHsExpr GhcTc -> !Type -> DsMessage
+ GHC.HsToCore.Errors.Types: DsWrongDoBind :: LHsExpr GhcTc -> Type -> DsMessage
- GHC.HsToCore.Errors.Types: ThAbstractClosedTypeFamily :: !LFamilyDecl GhcRn -> ThRejectionReason
+ GHC.HsToCore.Errors.Types: ThAbstractClosedTypeFamily :: LFamilyDecl GhcRn -> ThRejectionReason
- GHC.HsToCore.Errors.Types: ThAmbiguousRecordSelectors :: !HsExpr GhcRn -> ThRejectionReason
+ GHC.HsToCore.Errors.Types: ThAmbiguousRecordSelectors :: HsExpr GhcRn -> ThRejectionReason
- GHC.HsToCore.Errors.Types: ThAmbiguousRecordUpdates :: !HsRecUpdField GhcRn GhcRn -> ThRejectionReason
+ GHC.HsToCore.Errors.Types: ThAmbiguousRecordUpdates :: HsRecUpdField GhcRn GhcRn -> ThRejectionReason
- GHC.HsToCore.Errors.Types: ThCostCentres :: !HsExpr GhcRn -> ThRejectionReason
+ GHC.HsToCore.Errors.Types: ThCostCentres :: HsExpr GhcRn -> ThRejectionReason
- GHC.HsToCore.Errors.Types: ThExoticFormOfType :: !HsType GhcRn -> ThRejectionReason
+ GHC.HsToCore.Errors.Types: ThExoticFormOfType :: HsType GhcRn -> ThRejectionReason
- GHC.HsToCore.Errors.Types: ThExoticLiteral :: !HsLit GhcRn -> ThRejectionReason
+ GHC.HsToCore.Errors.Types: ThExoticLiteral :: HsLit GhcRn -> ThRejectionReason
- GHC.HsToCore.Errors.Types: ThExoticPattern :: !Pat GhcRn -> ThRejectionReason
+ GHC.HsToCore.Errors.Types: ThExoticPattern :: Pat GhcRn -> ThRejectionReason
- GHC.HsToCore.Errors.Types: ThExpressionForm :: !HsExpr GhcRn -> ThRejectionReason
+ GHC.HsToCore.Errors.Types: ThExpressionForm :: HsExpr GhcRn -> ThRejectionReason
- GHC.HsToCore.Errors.Types: ThForeignExport :: !LForeignDecl GhcRn -> ThRejectionReason
+ GHC.HsToCore.Errors.Types: ThForeignExport :: LForeignDecl GhcRn -> ThRejectionReason
- GHC.HsToCore.Errors.Types: ThForeignLabel :: !CLabelString -> ThRejectionReason
+ GHC.HsToCore.Errors.Types: ThForeignLabel :: CLabelString -> ThRejectionReason
- GHC.HsToCore.Errors.Types: ThGuardedLambdas :: !Match GhcRn (LHsExpr GhcRn) -> ThRejectionReason
+ GHC.HsToCore.Errors.Types: ThGuardedLambdas :: Match GhcRn (LHsExpr GhcRn) -> ThRejectionReason
- GHC.HsToCore.Errors.Types: ThMonadComprehensionSyntax :: !HsExpr GhcRn -> ThRejectionReason
+ GHC.HsToCore.Errors.Types: ThMonadComprehensionSyntax :: HsExpr GhcRn -> ThRejectionReason
- GHC.HsToCore.Errors.Types: ThNegativeOverloadedPatterns :: !Pat GhcRn -> ThRejectionReason
+ GHC.HsToCore.Errors.Types: ThNegativeOverloadedPatterns :: Pat GhcRn -> ThRejectionReason
- GHC.HsToCore.Expr: dsLit :: HsLit GhcRn -> DsM CoreExpr
+ GHC.HsToCore.Expr: dsLit :: forall (p :: Pass). IsPass p => HsLit (GhcPass p) -> DsM CoreExpr
- GHC.HsToCore.Match.Literal: dsLit :: HsLit GhcRn -> DsM CoreExpr
+ GHC.HsToCore.Match.Literal: dsLit :: forall (p :: Pass). IsPass p => HsLit (GhcPass p) -> DsM CoreExpr
- GHC.HsToCore.Monad: addUnspecables :: Set EvId -> DsM a -> DsM a
+ GHC.HsToCore.Monad: addUnspecables :: [EvVar] -> DsM a -> DsM a
- GHC.HsToCore.Monad: getUnspecables :: DsM (Set EvId)
+ GHC.HsToCore.Monad: getUnspecables :: DsM (Maybe VarSet)
- GHC.HsToCore.Pmc.Solver: PhiBotCt :: !Id -> PhiCt
+ GHC.HsToCore.Pmc.Solver: PhiBotCt :: Id -> PhiCt
- GHC.HsToCore.Pmc.Solver: PhiConCt :: !Id -> !PmAltCon -> ![TyVar] -> ![PredType] -> ![Id] -> PhiCt
+ GHC.HsToCore.Pmc.Solver: PhiConCt :: Id -> PmAltCon -> [TyVar] -> [PredType] -> [Id] -> PhiCt
- GHC.HsToCore.Pmc.Solver: PhiCoreCt :: !Id -> !CoreExpr -> PhiCt
+ GHC.HsToCore.Pmc.Solver: PhiCoreCt :: Id -> CoreExpr -> PhiCt
- GHC.HsToCore.Pmc.Solver: PhiNotBotCt :: !Id -> PhiCt
+ GHC.HsToCore.Pmc.Solver: PhiNotBotCt :: Id -> PhiCt
- GHC.HsToCore.Pmc.Solver: PhiNotConCt :: !Id -> !PmAltCon -> PhiCt
+ GHC.HsToCore.Pmc.Solver: PhiNotConCt :: Id -> PmAltCon -> PhiCt
- GHC.HsToCore.Pmc.Solver: PhiTyCt :: !PredType -> PhiCt
+ GHC.HsToCore.Pmc.Solver: PhiTyCt :: PredType -> PhiCt
- GHC.HsToCore.Pmc.Solver.Types: MkNabla :: !TyState -> !TmState -> Nabla
+ GHC.HsToCore.Pmc.Solver.Types: MkNabla :: TyState -> TmState -> Nabla
- GHC.HsToCore.Pmc.Solver.Types: PACA :: !PmAltCon -> ![TyVar] -> ![Id] -> PmAltConApp
+ GHC.HsToCore.Pmc.Solver.Types: PACA :: PmAltCon -> [TyVar] -> [Id] -> PmAltConApp
- GHC.HsToCore.Pmc.Solver.Types: RCM :: !Maybe DsCompleteMatch -> !Maybe DsCompleteMatches -> ResidualCompleteMatches
+ GHC.HsToCore.Pmc.Solver.Types: RCM :: Maybe DsCompleteMatch -> Maybe DsCompleteMatches -> ResidualCompleteMatches
- GHC.HsToCore.Pmc.Solver.Types: TmSt :: !UniqSDFM Id VarInfo -> !CoreMap Id -> !DIdSet -> TmState
+ GHC.HsToCore.Pmc.Solver.Types: TmSt :: UniqSDFM Id VarInfo -> CoreMap Id -> DIdSet -> TmState
- GHC.HsToCore.Pmc.Solver.Types: TySt :: !Int -> !InertSet -> TyState
+ GHC.HsToCore.Pmc.Solver.Types: TySt :: Int -> InertSet -> TyState
- GHC.HsToCore.Pmc.Solver.Types: VI :: !Id -> ![PmAltConApp] -> !PmAltConSet -> BotInfo -> !ResidualCompleteMatches -> VarInfo
+ GHC.HsToCore.Pmc.Solver.Types: VI :: Id -> [PmAltConApp] -> PmAltConSet -> BotInfo -> ResidualCompleteMatches -> VarInfo
- GHC.HsToCore.Pmc.Solver.Types: [nabla_tm_st] :: Nabla -> !TmState
+ GHC.HsToCore.Pmc.Solver.Types: [nabla_tm_st] :: Nabla -> TmState
- GHC.HsToCore.Pmc.Solver.Types: [nabla_ty_st] :: Nabla -> !TyState
+ GHC.HsToCore.Pmc.Solver.Types: [nabla_ty_st] :: Nabla -> TyState
- GHC.HsToCore.Pmc.Solver.Types: [paca_con] :: PmAltConApp -> !PmAltCon
+ GHC.HsToCore.Pmc.Solver.Types: [paca_con] :: PmAltConApp -> PmAltCon
- GHC.HsToCore.Pmc.Solver.Types: [paca_ids] :: PmAltConApp -> ![Id]
+ GHC.HsToCore.Pmc.Solver.Types: [paca_ids] :: PmAltConApp -> [Id]
- GHC.HsToCore.Pmc.Solver.Types: [paca_tvs] :: PmAltConApp -> ![TyVar]
+ GHC.HsToCore.Pmc.Solver.Types: [paca_tvs] :: PmAltConApp -> [TyVar]
- GHC.HsToCore.Pmc.Solver.Types: [rcm_pragmas] :: ResidualCompleteMatches -> !Maybe DsCompleteMatches
+ GHC.HsToCore.Pmc.Solver.Types: [rcm_pragmas] :: ResidualCompleteMatches -> Maybe DsCompleteMatches
- GHC.HsToCore.Pmc.Solver.Types: [rcm_vanilla] :: ResidualCompleteMatches -> !Maybe DsCompleteMatch
+ GHC.HsToCore.Pmc.Solver.Types: [rcm_vanilla] :: ResidualCompleteMatches -> Maybe DsCompleteMatch
- GHC.HsToCore.Pmc.Solver.Types: [ts_dirty] :: TmState -> !DIdSet
+ GHC.HsToCore.Pmc.Solver.Types: [ts_dirty] :: TmState -> DIdSet
- GHC.HsToCore.Pmc.Solver.Types: [ts_facts] :: TmState -> !UniqSDFM Id VarInfo
+ GHC.HsToCore.Pmc.Solver.Types: [ts_facts] :: TmState -> UniqSDFM Id VarInfo
- GHC.HsToCore.Pmc.Solver.Types: [ts_reps] :: TmState -> !CoreMap Id
+ GHC.HsToCore.Pmc.Solver.Types: [ts_reps] :: TmState -> CoreMap Id
- GHC.HsToCore.Pmc.Solver.Types: [ty_st_inert] :: TyState -> !InertSet
+ GHC.HsToCore.Pmc.Solver.Types: [ty_st_inert] :: TyState -> InertSet
- GHC.HsToCore.Pmc.Solver.Types: [ty_st_n] :: TyState -> !Int
+ GHC.HsToCore.Pmc.Solver.Types: [ty_st_n] :: TyState -> Int
- GHC.HsToCore.Pmc.Solver.Types: [vi_id] :: VarInfo -> !Id
+ GHC.HsToCore.Pmc.Solver.Types: [vi_id] :: VarInfo -> Id
- GHC.HsToCore.Pmc.Solver.Types: [vi_neg] :: VarInfo -> !PmAltConSet
+ GHC.HsToCore.Pmc.Solver.Types: [vi_neg] :: VarInfo -> PmAltConSet
- GHC.HsToCore.Pmc.Solver.Types: [vi_pos] :: VarInfo -> ![PmAltConApp]
+ GHC.HsToCore.Pmc.Solver.Types: [vi_pos] :: VarInfo -> [PmAltConApp]
- GHC.HsToCore.Pmc.Solver.Types: [vi_rcm] :: VarInfo -> !ResidualCompleteMatches
+ GHC.HsToCore.Pmc.Solver.Types: [vi_rcm] :: VarInfo -> ResidualCompleteMatches
- GHC.HsToCore.Pmc.Types: CheckResult :: !a -> !Nablas -> !Precision -> CheckResult a
+ GHC.HsToCore.Pmc.Types: CheckResult :: a -> Nablas -> Precision -> CheckResult a
- GHC.HsToCore.Pmc.Types: GdAlt :: !GrdDag -> !GrdDag -> GrdDag
+ GHC.HsToCore.Pmc.Types: GdAlt :: GrdDag -> GrdDag -> GrdDag
- GHC.HsToCore.Pmc.Types: GdOne :: !PmGrd -> GrdDag
+ GHC.HsToCore.Pmc.Types: GdOne :: PmGrd -> GrdDag
- GHC.HsToCore.Pmc.Types: GdSeq :: !GrdDag -> !GrdDag -> GrdDag
+ GHC.HsToCore.Pmc.Types: GdSeq :: GrdDag -> GrdDag -> GrdDag
- GHC.HsToCore.Pmc.Types: PmBang :: !Id -> !Maybe SrcInfo -> PmGrd
+ GHC.HsToCore.Pmc.Types: PmBang :: Id -> Maybe SrcInfo -> PmGrd
- GHC.HsToCore.Pmc.Types: PmCon :: !Id -> !PmAltCon -> ![TyVar] -> ![EvVar] -> ![Id] -> PmGrd
+ GHC.HsToCore.Pmc.Types: PmCon :: Id -> PmAltCon -> [TyVar] -> [EvVar] -> [Id] -> PmGrd
- GHC.HsToCore.Pmc.Types: PmGRHS :: !p -> !SrcInfo -> PmGRHS p
+ GHC.HsToCore.Pmc.Types: PmGRHS :: p -> SrcInfo -> PmGRHS p
- GHC.HsToCore.Pmc.Types: PmGRHSs :: !p -> !NonEmpty (PmGRHS p) -> PmGRHSs p
+ GHC.HsToCore.Pmc.Types: PmGRHSs :: p -> NonEmpty (PmGRHS p) -> PmGRHSs p
- GHC.HsToCore.Pmc.Types: PmLet :: !Id -> !CoreExpr -> PmGrd
+ GHC.HsToCore.Pmc.Types: PmLet :: Id -> CoreExpr -> PmGrd
- GHC.HsToCore.Pmc.Types: PmMatch :: !p -> !PmGRHSs p -> PmMatch p
+ GHC.HsToCore.Pmc.Types: PmMatch :: p -> PmGRHSs p -> PmMatch p
- GHC.HsToCore.Pmc.Types: RedSets :: !Nablas -> !Nablas -> !OrdList (Nablas, SrcInfo) -> RedSets
+ GHC.HsToCore.Pmc.Types: RedSets :: Nablas -> Nablas -> OrdList (Nablas, SrcInfo) -> RedSets
- GHC.HsToCore.Pmc.Types: [_pm_let_expr] :: PmGrd -> !CoreExpr
+ GHC.HsToCore.Pmc.Types: [_pm_let_expr] :: PmGrd -> CoreExpr
- GHC.HsToCore.Pmc.Types: [_pm_loc] :: PmGrd -> !Maybe SrcInfo
+ GHC.HsToCore.Pmc.Types: [_pm_loc] :: PmGrd -> Maybe SrcInfo
- GHC.HsToCore.Pmc.Types: [cr_approx] :: CheckResult a -> !Precision
+ GHC.HsToCore.Pmc.Types: [cr_approx] :: CheckResult a -> Precision
- GHC.HsToCore.Pmc.Types: [cr_ret] :: CheckResult a -> !a
+ GHC.HsToCore.Pmc.Types: [cr_ret] :: CheckResult a -> a
- GHC.HsToCore.Pmc.Types: [cr_uncov] :: CheckResult a -> !Nablas
+ GHC.HsToCore.Pmc.Types: [cr_uncov] :: CheckResult a -> Nablas
- GHC.HsToCore.Pmc.Types: [pg_grds] :: PmGRHS p -> !p
+ GHC.HsToCore.Pmc.Types: [pg_grds] :: PmGRHS p -> p
- GHC.HsToCore.Pmc.Types: [pg_rhs] :: PmGRHS p -> !SrcInfo
+ GHC.HsToCore.Pmc.Types: [pg_rhs] :: PmGRHS p -> SrcInfo
- GHC.HsToCore.Pmc.Types: [pgs_grhss] :: PmGRHSs p -> !NonEmpty (PmGRHS p)
+ GHC.HsToCore.Pmc.Types: [pgs_grhss] :: PmGRHSs p -> NonEmpty (PmGRHS p)
- GHC.HsToCore.Pmc.Types: [pgs_lcls] :: PmGRHSs p -> !p
+ GHC.HsToCore.Pmc.Types: [pgs_lcls] :: PmGRHSs p -> p
- GHC.HsToCore.Pmc.Types: [pm_con_args] :: PmGrd -> ![Id]
+ GHC.HsToCore.Pmc.Types: [pm_con_args] :: PmGrd -> [Id]
- GHC.HsToCore.Pmc.Types: [pm_con_con] :: PmGrd -> !PmAltCon
+ GHC.HsToCore.Pmc.Types: [pm_con_con] :: PmGrd -> PmAltCon
- GHC.HsToCore.Pmc.Types: [pm_con_dicts] :: PmGrd -> ![EvVar]
+ GHC.HsToCore.Pmc.Types: [pm_con_dicts] :: PmGrd -> [EvVar]
- GHC.HsToCore.Pmc.Types: [pm_con_tvs] :: PmGrd -> ![TyVar]
+ GHC.HsToCore.Pmc.Types: [pm_con_tvs] :: PmGrd -> [TyVar]
- GHC.HsToCore.Pmc.Types: [pm_grhss] :: PmMatch p -> !PmGRHSs p
+ GHC.HsToCore.Pmc.Types: [pm_grhss] :: PmMatch p -> PmGRHSs p
- GHC.HsToCore.Pmc.Types: [pm_id] :: PmGrd -> !Id
+ GHC.HsToCore.Pmc.Types: [pm_id] :: PmGrd -> Id
- GHC.HsToCore.Pmc.Types: [pm_pats] :: PmMatch p -> !p
+ GHC.HsToCore.Pmc.Types: [pm_pats] :: PmMatch p -> p
- GHC.HsToCore.Pmc.Types: [rs_bangs] :: RedSets -> !OrdList (Nablas, SrcInfo)
+ GHC.HsToCore.Pmc.Types: [rs_bangs] :: RedSets -> OrdList (Nablas, SrcInfo)
- GHC.HsToCore.Pmc.Types: [rs_cov] :: RedSets -> !Nablas
+ GHC.HsToCore.Pmc.Types: [rs_cov] :: RedSets -> Nablas
- GHC.HsToCore.Pmc.Types: [rs_div] :: RedSets -> !Nablas
+ GHC.HsToCore.Pmc.Types: [rs_div] :: RedSets -> Nablas
- GHC.HsToCore.Ticks: TicksConfig :: ![TickishType] -> !ProfAuto -> !Bool -> TicksConfig
+ GHC.HsToCore.Ticks: TicksConfig :: [TickishType] -> ProfAuto -> Bool -> TicksConfig
- GHC.HsToCore.Ticks: [ticks_countEntries] :: TicksConfig -> !Bool
+ GHC.HsToCore.Ticks: [ticks_countEntries] :: TicksConfig -> Bool
- GHC.HsToCore.Ticks: [ticks_passes] :: TicksConfig -> ![TickishType]
+ GHC.HsToCore.Ticks: [ticks_passes] :: TicksConfig -> [TickishType]
- GHC.HsToCore.Ticks: [ticks_profAuto] :: TicksConfig -> !ProfAuto
+ GHC.HsToCore.Ticks: [ticks_profAuto] :: TicksConfig -> ProfAuto
- GHC.HsToCore.Types: DsLclEnv :: DsMetaEnv -> RealSrcSpan -> Nablas -> Set EvVar -> DsLclEnv
+ GHC.HsToCore.Types: DsLclEnv :: DsMetaEnv -> RealSrcSpan -> Nablas -> Maybe VarSet -> DsLclEnv
- GHC.HsToCore.Types: [dsl_unspecables] :: DsLclEnv -> Set EvVar
+ GHC.HsToCore.Types: [dsl_unspecables] :: DsLclEnv -> Maybe VarSet
- GHC.HsToCore.Usage: UsageConfig :: !Bool -> UsageConfig
+ GHC.HsToCore.Usage: UsageConfig :: Bool -> UsageConfig
- GHC.HsToCore.Usage: [uc_safe_implicit_imps_req] :: UsageConfig -> !Bool
+ GHC.HsToCore.Usage: [uc_safe_implicit_imps_req] :: UsageConfig -> Bool
- GHC.HsToCore.Usage: mkUsageInfo :: UsageConfig -> Plugins -> FinderCache -> UnitEnv -> Module -> ImportedMods -> NameSet -> [FilePath] -> [(Module, Fingerprint)] -> [Linkable] -> PkgsLoaded -> IfG [Usage]
+ GHC.HsToCore.Usage: mkUsageInfo :: UsageConfig -> Plugins -> FinderCache -> UnitEnv -> Module -> ImportedMods -> [ImportUserSpec] -> NameSet -> [FilePath] -> [(Module, Fingerprint)] -> [Linkable] -> PkgsLoaded -> IfG [Usage]
- GHC.Iface.Binary: BinSymbolTable :: !FastMutInt -> !IORef (UniqFM Name (Int, Name)) -> BinSymbolTable
+ GHC.Iface.Binary: BinSymbolTable :: FastMutInt -> IORef (UniqFM Name (Int, Name)) -> BinSymbolTable
- GHC.Iface.Binary: [bin_symtab_map] :: BinSymbolTable -> !IORef (UniqFM Name (Int, Name))
+ GHC.Iface.Binary: [bin_symtab_map] :: BinSymbolTable -> IORef (UniqFM Name (Int, Name))
- GHC.Iface.Binary: [bin_symtab_next] :: BinSymbolTable -> !FastMutInt
+ GHC.Iface.Binary: [bin_symtab_next] :: BinSymbolTable -> FastMutInt
- GHC.Iface.Binary: readBinIfaceHeader :: Profile -> NameCache -> CheckHiWay -> TraceBinIFace -> FilePath -> IO (Fingerprint, ReadBinHandle)
+ GHC.Iface.Binary: readBinIfaceHeader :: Profile -> NameCache -> CheckHiWay -> TraceBinIFace -> FilePath -> IO ReadBinHandle
- GHC.Iface.Errors.Ppr: IfaceMessageOpts :: !Bool -> !BuildingCabalPackage -> IfaceMessageOpts
+ GHC.Iface.Errors.Ppr: IfaceMessageOpts :: Bool -> BuildingCabalPackage -> IfaceMessageOpts
- GHC.Iface.Errors.Ppr: [ifaceBuildingCabalPackage] :: IfaceMessageOpts -> !BuildingCabalPackage
+ GHC.Iface.Errors.Ppr: [ifaceBuildingCabalPackage] :: IfaceMessageOpts -> BuildingCabalPackage
- GHC.Iface.Errors.Ppr: [ifaceShowTriedFiles] :: IfaceMessageOpts -> !Bool
+ GHC.Iface.Errors.Ppr: [ifaceShowTriedFiles] :: IfaceMessageOpts -> Bool
- GHC.Iface.Errors.Types: BadSourceImport :: !Module -> MissingInterfaceError
+ GHC.Iface.Errors.Types: BadSourceImport :: Module -> MissingInterfaceError
- GHC.Iface.Errors.Types: CantFindErr :: !UnitState -> FindingModuleOrInterface -> CantFindInstalled -> MissingInterfaceError
+ GHC.Iface.Errors.Types: CantFindErr :: UnitState -> FindingModuleOrInterface -> CantFindInstalled -> MissingInterfaceError
- GHC.Iface.Errors.Types: CircularImport :: !Module -> IfaceMessage
+ GHC.Iface.Errors.Types: CircularImport :: Module -> IfaceMessage
- GHC.Iface.Errors.Types: DynamicHashMismatchError :: !Module -> !ModLocation -> MissingInterfaceError
+ GHC.Iface.Errors.Types: DynamicHashMismatchError :: Module -> ModLocation -> MissingInterfaceError
- GHC.Iface.Errors.Types: HomeModError :: !InstalledModule -> !ModLocation -> MissingInterfaceError
+ GHC.Iface.Errors.Types: HomeModError :: InstalledModule -> ModLocation -> MissingInterfaceError
- GHC.Iface.Errors.Types: IfaceMessageOpts :: !Bool -> !BuildingCabalPackage -> IfaceMessageOpts
+ GHC.Iface.Errors.Types: IfaceMessageOpts :: Bool -> BuildingCabalPackage -> IfaceMessageOpts
- GHC.Iface.Errors.Types: LookingForHiBoot :: !Module -> InterfaceLookingFor
+ GHC.Iface.Errors.Types: LookingForHiBoot :: Module -> InterfaceLookingFor
- GHC.Iface.Errors.Types: LookingForModule :: !ModuleName -> !IsBootInterface -> InterfaceLookingFor
+ GHC.Iface.Errors.Types: LookingForModule :: ModuleName -> IsBootInterface -> InterfaceLookingFor
- GHC.Iface.Errors.Types: LookingForName :: !Name -> InterfaceLookingFor
+ GHC.Iface.Errors.Types: LookingForName :: Name -> InterfaceLookingFor
- GHC.Iface.Errors.Types: LookingForSig :: !InstalledModule -> InterfaceLookingFor
+ GHC.Iface.Errors.Types: LookingForSig :: InstalledModule -> InterfaceLookingFor
- GHC.Iface.Errors.Types: [ifaceBuildingCabalPackage] :: IfaceMessageOpts -> !BuildingCabalPackage
+ GHC.Iface.Errors.Types: [ifaceBuildingCabalPackage] :: IfaceMessageOpts -> BuildingCabalPackage
- GHC.Iface.Errors.Types: [ifaceShowTriedFiles] :: IfaceMessageOpts -> !Bool
+ GHC.Iface.Errors.Types: [ifaceShowTriedFiles] :: IfaceMessageOpts -> Bool
- GHC.Iface.Ext.Binary: ExternalName :: !Module -> !OccName -> !SrcSpan -> HieName
+ GHC.Iface.Ext.Binary: ExternalName :: Module -> OccName -> SrcSpan -> HieName
- GHC.Iface.Ext.Binary: KnownKeyName :: !Unique -> HieName
+ GHC.Iface.Ext.Binary: KnownKeyName :: Unique -> HieName
- GHC.Iface.Ext.Binary: LocalName :: !OccName -> !SrcSpan -> HieName
+ GHC.Iface.Ext.Binary: LocalName :: OccName -> SrcSpan -> HieName
- GHC.Iface.Ext.Types: ExternalName :: !Module -> !OccName -> !SrcSpan -> HieName
+ GHC.Iface.Ext.Types: ExternalName :: Module -> OccName -> SrcSpan -> HieName
- GHC.Iface.Ext.Types: KnownKeyName :: !Unique -> HieName
+ GHC.Iface.Ext.Types: KnownKeyName :: Unique -> HieName
- GHC.Iface.Ext.Types: LocalName :: !OccName -> !SrcSpan -> HieName
+ GHC.Iface.Ext.Types: LocalName :: OccName -> SrcSpan -> HieName
- GHC.Iface.Ext.Types: NodeAnnotation :: !FastString -> !FastString -> NodeAnnotation
+ GHC.Iface.Ext.Types: NodeAnnotation :: FastString -> FastString -> NodeAnnotation
- GHC.Iface.Ext.Types: [nodeAnnotConstr] :: NodeAnnotation -> !FastString
+ GHC.Iface.Ext.Types: [nodeAnnotConstr] :: NodeAnnotation -> FastString
- GHC.Iface.Ext.Types: [nodeAnnotType] :: NodeAnnotation -> !FastString
+ GHC.Iface.Ext.Types: [nodeAnnotType] :: NodeAnnotation -> FastString
- GHC.Iface.Ext.Utils: HTS :: !TypeMap TypeIndex -> !IntMap HieTypeFlat -> !TypeIndex -> HieTypeState
+ GHC.Iface.Ext.Utils: HTS :: TypeMap TypeIndex -> IntMap HieTypeFlat -> TypeIndex -> HieTypeState
- GHC.Iface.Ext.Utils: [freshIndex] :: HieTypeState -> !TypeIndex
+ GHC.Iface.Ext.Utils: [freshIndex] :: HieTypeState -> TypeIndex
- GHC.Iface.Ext.Utils: [htyTable] :: HieTypeState -> !IntMap HieTypeFlat
+ GHC.Iface.Ext.Utils: [htyTable] :: HieTypeState -> IntMap HieTypeFlat
- GHC.Iface.Ext.Utils: [tyMap] :: HieTypeState -> !TypeMap TypeIndex
+ GHC.Iface.Ext.Utils: [tyMap] :: HieTypeState -> TypeMap TypeIndex
- GHC.Iface.Load: readIface :: DynFlags -> NameCache -> Module -> FilePath -> IO (MaybeErr ReadInterfaceError ModIface)
+ GHC.Iface.Load: readIface :: Hooks -> Logger -> DynFlags -> NameCache -> Module -> FilePath -> IO (MaybeErr ReadInterfaceError ModIface)
- GHC.Iface.Make: mkPartialIface :: HscEnv -> CoreProgram -> ModDetails -> ModSummary -> [ImportUserSpec] -> ModGuts -> PartialModIface
+ GHC.Iface.Make: mkPartialIface :: HscEnv -> CoreProgram -> ModDetails -> ModSummary -> [ImportUserSpec] -> ModGuts -> IO PartialModIface
- GHC.Iface.Recomp: ModuleAdded :: (UnitId, ModuleName) -> RecompReason
+ GHC.Iface.Recomp: ModuleAdded :: (ImportLevel, UnitId, ModuleName) -> RecompReason
- GHC.Iface.Recomp: ModuleRemoved :: (UnitId, ModuleName) -> RecompReason
+ GHC.Iface.Recomp: ModuleRemoved :: (ImportLevel, UnitId, ModuleName) -> RecompReason
- GHC.Iface.Recomp: NeedsRecompile :: !CompileReason -> RecompileRequired
+ GHC.Iface.Recomp: NeedsRecompile :: CompileReason -> RecompileRequired
- GHC.Iface.Recomp: OutOfDateItem :: !CompileReason -> Maybe a -> MaybeValidated a
+ GHC.Iface.Recomp: OutOfDateItem :: CompileReason -> Maybe a -> MaybeValidated a
- GHC.Iface.Recomp: RecompBecause :: !RecompReason -> CompileReason
+ GHC.Iface.Recomp: RecompBecause :: RecompReason -> CompileReason
- GHC.Iface.Recomp: UnitDepRemoved :: UnitId -> RecompReason
+ GHC.Iface.Recomp: UnitDepRemoved :: (ImportLevel, UnitId) -> RecompReason
- GHC.Iface.Recomp.Binary: computeFingerprint :: Binary a => (WriteBinHandle -> Name -> IO ()) -> a -> IO Fingerprint
+ GHC.Iface.Recomp.Binary: computeFingerprint :: Binary a => (WriteBinHandle -> Name -> IO ()) -> a -> Fingerprint
- GHC.Iface.Recomp.Flags: fingerprintDynFlags :: HscEnv -> Module -> (WriteBinHandle -> Name -> IO ()) -> IO Fingerprint
+ GHC.Iface.Recomp.Flags: fingerprintDynFlags :: HscEnv -> Module -> (WriteBinHandle -> Name -> IO ()) -> (Fingerprint, IfaceDynFlags)
- GHC.Iface.Recomp.Flags: fingerprintHpcFlags :: DynFlags -> (WriteBinHandle -> Name -> IO ()) -> IO Fingerprint
+ GHC.Iface.Recomp.Flags: fingerprintHpcFlags :: DynFlags -> (WriteBinHandle -> Name -> IO ()) -> Fingerprint
- GHC.Iface.Recomp.Flags: fingerprintOptFlags :: DynFlags -> (WriteBinHandle -> Name -> IO ()) -> IO Fingerprint
+ GHC.Iface.Recomp.Flags: fingerprintOptFlags :: DynFlags -> (WriteBinHandle -> Name -> IO ()) -> Fingerprint
- GHC.Iface.Syntax: IfCon :: IfaceTopBndr -> Bool -> Bool -> [IfaceBndr] -> [IfaceForAllSpecBndr] -> IfaceEqSpec -> IfaceContext -> [(IfaceMult, IfaceType)] -> [FieldLabel] -> [IfaceBang] -> [IfaceSrcBang] -> IfaceConDecl
+ GHC.Iface.Syntax: IfCon :: IfaceTopBndr -> Bool -> Bool -> [IfaceBndr] -> [IfaceForAllBndr] -> IfaceEqSpec -> IfaceContext -> [(IfaceMult, IfaceType)] -> [FieldLabel] -> [IfaceBang] -> [IfaceSrcBang] -> IfaceConDecl
- GHC.Iface.Syntax: IfConcreteClass :: IfaceContext -> [IfaceAT] -> [IfaceClassOp] -> IfaceBooleanFormula -> IfaceClassBody
+ GHC.Iface.Syntax: IfConcreteClass :: IfaceContext -> [IfaceAT] -> [IfaceClassOp] -> IfaceBooleanFormula -> Bool -> IfaceClassBody
- GHC.Iface.Syntax: IfDataTyCon :: !Bool -> [IfaceConDecl] -> IfaceConDecls
+ GHC.Iface.Syntax: IfDataTyCon :: Bool -> [IfaceConDecl] -> IfaceConDecls
- GHC.Iface.Syntax: IfLFCon :: !Name -> IfaceLFInfo
+ GHC.Iface.Syntax: IfLFCon :: Name -> IfaceLFInfo
- GHC.Iface.Syntax: IfLFReEntrant :: !RepArity -> IfaceLFInfo
+ GHC.Iface.Syntax: IfLFReEntrant :: RepArity -> IfaceLFInfo
- GHC.Iface.Syntax: IfLFThunk :: !Bool -> !Bool -> IfaceLFInfo
+ GHC.Iface.Syntax: IfLFThunk :: Bool -> Bool -> IfaceLFInfo
- GHC.Iface.Syntax: IfLFUnknown :: !Bool -> IfaceLFInfo
+ GHC.Iface.Syntax: IfLFUnknown :: Bool -> IfaceLFInfo
- GHC.Iface.Syntax: IfaceBreakpoint :: Int -> [IfaceExpr] -> Module -> IfaceTickish
+ GHC.Iface.Syntax: IfaceBreakpoint :: BreakpointId -> [IfaceExpr] -> IfaceTickish
- GHC.Iface.Syntax: ImpIfaceEverythingBut :: !NameSet -> ImpIfaceList
+ GHC.Iface.Syntax: ImpIfaceEverythingBut :: [Name] -> ImpIfaceList
- GHC.Iface.Syntax: ImpIfaceExplicit :: !IfGlobalRdrEnv -> ImpIfaceList
+ GHC.Iface.Syntax: ImpIfaceExplicit :: DetOrdAvails -> [Name] -> ImpIfaceList
- GHC.Iface.Syntax: [ifConUserTvBinders] :: IfaceConDecl -> [IfaceForAllSpecBndr]
+ GHC.Iface.Syntax: [ifConUserTvBinders] :: IfaceConDecl -> [IfaceForAllBndr]
- GHC.Iface.Tidy: TidyOpts :: !NameCache -> !Bool -> !UnfoldingOpts -> !UnfoldingExposure -> !Bool -> !Bool -> !Maybe StaticPtrOpts -> !Bool -> TidyOpts
+ GHC.Iface.Tidy: TidyOpts :: NameCache -> Bool -> UnfoldingOpts -> UnfoldingExposure -> Bool -> Bool -> Maybe StaticPtrOpts -> Bool -> TidyOpts
- GHC.Iface.Tidy: [opt_collect_ccs] :: TidyOpts -> !Bool
+ GHC.Iface.Tidy: [opt_collect_ccs] :: TidyOpts -> Bool
- GHC.Iface.Tidy: [opt_expose_rules] :: TidyOpts -> !Bool
+ GHC.Iface.Tidy: [opt_expose_rules] :: TidyOpts -> Bool
- GHC.Iface.Tidy: [opt_expose_unfoldings] :: TidyOpts -> !UnfoldingExposure
+ GHC.Iface.Tidy: [opt_expose_unfoldings] :: TidyOpts -> UnfoldingExposure
- GHC.Iface.Tidy: [opt_keep_auto_rules] :: TidyOpts -> !Bool
+ GHC.Iface.Tidy: [opt_keep_auto_rules] :: TidyOpts -> Bool
- GHC.Iface.Tidy: [opt_name_cache] :: TidyOpts -> !NameCache
+ GHC.Iface.Tidy: [opt_name_cache] :: TidyOpts -> NameCache
- GHC.Iface.Tidy: [opt_static_ptr_opts] :: TidyOpts -> !Maybe StaticPtrOpts
+ GHC.Iface.Tidy: [opt_static_ptr_opts] :: TidyOpts -> Maybe StaticPtrOpts
- GHC.Iface.Tidy: [opt_trim_ids] :: TidyOpts -> !Bool
+ GHC.Iface.Tidy: [opt_trim_ids] :: TidyOpts -> Bool
- GHC.Iface.Tidy: [opt_unfolding_opts] :: TidyOpts -> !UnfoldingOpts
+ GHC.Iface.Tidy: [opt_unfolding_opts] :: TidyOpts -> UnfoldingOpts
- GHC.Iface.Tidy.StaticPtrTable: StaticPtrOpts :: !Platform -> !Bool -> !MkStringIds -> !DataCon -> !DataCon -> StaticPtrOpts
+ GHC.Iface.Tidy.StaticPtrTable: StaticPtrOpts :: Platform -> Bool -> MkStringIds -> DataCon -> DataCon -> StaticPtrOpts
- GHC.Iface.Tidy.StaticPtrTable: [opt_gen_cstub] :: StaticPtrOpts -> !Bool
+ GHC.Iface.Tidy.StaticPtrTable: [opt_gen_cstub] :: StaticPtrOpts -> Bool
- GHC.Iface.Tidy.StaticPtrTable: [opt_mk_string] :: StaticPtrOpts -> !MkStringIds
+ GHC.Iface.Tidy.StaticPtrTable: [opt_mk_string] :: StaticPtrOpts -> MkStringIds
- GHC.Iface.Tidy.StaticPtrTable: [opt_platform] :: StaticPtrOpts -> !Platform
+ GHC.Iface.Tidy.StaticPtrTable: [opt_platform] :: StaticPtrOpts -> Platform
- GHC.Iface.Tidy.StaticPtrTable: [opt_static_ptr_datacon] :: StaticPtrOpts -> !DataCon
+ GHC.Iface.Tidy.StaticPtrTable: [opt_static_ptr_datacon] :: StaticPtrOpts -> DataCon
- GHC.Iface.Tidy.StaticPtrTable: [opt_static_ptr_info_datacon] :: StaticPtrOpts -> !DataCon
+ GHC.Iface.Tidy.StaticPtrTable: [opt_static_ptr_info_datacon] :: StaticPtrOpts -> DataCon
- GHC.Iface.Type: IfaceForAllCo :: IfaceBndr -> !ForAllTyFlag -> !ForAllTyFlag -> IfaceCoercion -> IfaceCoercion -> IfaceCoercion
+ GHC.Iface.Type: IfaceForAllCo :: IfaceBndr -> ForAllTyFlag -> ForAllTyFlag -> IfaceCoercion -> IfaceCoercion -> IfaceCoercion
- GHC.Iface.Type: IfaceIdBndr :: {-# UNPACK #-} !IfaceIdBndr -> IfaceBndr
+ GHC.Iface.Type: IfaceIdBndr :: IfaceIdBndr -> IfaceBndr
- GHC.Iface.Type: IfaceSumTyCon :: !Arity -> IfaceTyConSort
+ GHC.Iface.Type: IfaceSumTyCon :: Arity -> IfaceTyConSort
- GHC.Iface.Type: IfaceTupleTyCon :: !Arity -> !TupleSort -> IfaceTyConSort
+ GHC.Iface.Type: IfaceTupleTyCon :: Arity -> TupleSort -> IfaceTyConSort
- GHC.Iface.Type: IfaceTvBndr :: {-# UNPACK #-} !IfaceTvBndr -> IfaceBndr
+ GHC.Iface.Type: IfaceTvBndr :: IfaceTvBndr -> IfaceBndr
- GHC.Iface.Type: IfaceTyCon :: IfExtName -> !IfaceTyConInfo -> IfaceTyCon
+ GHC.Iface.Type: IfaceTyCon :: IfExtName -> IfaceTyConInfo -> IfaceTyCon
- GHC.Iface.Type: Invisible :: !Specificity -> ForAllTyFlag
+ GHC.Iface.Type: Invisible :: Specificity -> ForAllTyFlag
- GHC.Iface.Type: [ifaceTyConInfo] :: IfaceTyCon -> !IfaceTyConInfo
+ GHC.Iface.Type: [ifaceTyConInfo] :: IfaceTyCon -> IfaceTyConInfo
- GHC.Iface.Type: suppressIfaceInvisibles :: PrintExplicitKinds -> [IfaceTyConBinder] -> [a] -> [a]
+ GHC.Iface.Type: suppressIfaceInvisibles :: PrintArityInvisibles -> PrintExplicitKinds -> Set IfLclName -> [IfaceTyConBinder] -> [a] -> [a]
- GHC.IfaceToCore: tcIfaceImport :: HscEnv -> IfaceImport -> ImportUserSpec
+ GHC.IfaceToCore: tcIfaceImport :: IfaceImport -> ImportUserSpec
- GHC.JS.JStg.Syntax: DeclStat :: !Ident -> !Maybe JStgExpr -> JStgStat
+ GHC.JS.JStg.Syntax: DeclStat :: Ident -> Maybe JStgExpr -> JStgStat
- GHC.JS.JStg.Syntax: FuncStat :: !Ident -> [Ident] -> JStgStat -> JStgStat
+ GHC.JS.JStg.Syntax: FuncStat :: Ident -> [Ident] -> JStgStat -> JStgStat
- GHC.JS.Ppr: RenderJs :: !JsRender doc => RenderJs doc -> JStat -> doc -> !JsRender doc => RenderJs doc -> JExpr -> doc -> !JsRender doc => RenderJs doc -> JVal -> doc -> !JsRender doc => RenderJs doc -> Ident -> doc -> RenderJs doc
+ GHC.JS.Ppr: RenderJs :: (JsRender doc => RenderJs doc -> JStat -> doc) -> (JsRender doc => RenderJs doc -> JExpr -> doc) -> (JsRender doc => RenderJs doc -> JVal -> doc) -> (JsRender doc => RenderJs doc -> Ident -> doc) -> RenderJs doc
- GHC.JS.Ppr: [renderJsE] :: RenderJs doc -> !JsRender doc => RenderJs doc -> JExpr -> doc
+ GHC.JS.Ppr: [renderJsE] :: RenderJs doc -> JsRender doc => RenderJs doc -> JExpr -> doc
- GHC.JS.Ppr: [renderJsI] :: RenderJs doc -> !JsRender doc => RenderJs doc -> Ident -> doc
+ GHC.JS.Ppr: [renderJsI] :: RenderJs doc -> JsRender doc => RenderJs doc -> Ident -> doc
- GHC.JS.Ppr: [renderJsS] :: RenderJs doc -> !JsRender doc => RenderJs doc -> JStat -> doc
+ GHC.JS.Ppr: [renderJsS] :: RenderJs doc -> JsRender doc => RenderJs doc -> JStat -> doc
- GHC.JS.Ppr: [renderJsV] :: RenderJs doc -> !JsRender doc => RenderJs doc -> JVal -> doc
+ GHC.JS.Ppr: [renderJsV] :: RenderJs doc -> JsRender doc => RenderJs doc -> JVal -> doc
- GHC.JS.Syntax: DeclStat :: !Ident -> !Maybe JExpr -> JStat
+ GHC.JS.Syntax: DeclStat :: Ident -> Maybe JExpr -> JStat
- GHC.JS.Syntax: FuncStat :: !Ident -> [Ident] -> JStat -> JStat
+ GHC.JS.Syntax: FuncStat :: Ident -> [Ident] -> JStat -> JStat
- GHC.Linker.Config: LinkerConfig :: String -> [Option] -> [Option] -> TempDir -> (String -> String) -> LinkerConfig
+ GHC.Linker.Config: LinkerConfig :: String -> [Option] -> [Option] -> TempDir -> ([String] -> [String]) -> LinkerConfig
- GHC.Linker.Config: [linkerFilter] :: LinkerConfig -> String -> String
+ GHC.Linker.Config: [linkerFilter] :: LinkerConfig -> [String] -> [String]
- GHC.Linker.Deps: LinkDepsOpts :: !String -> !Bool -> !Bool -> !ModuleGraph -> !UnitEnv -> !SDocContext -> !Bool -> !DiagnosticOpts IfaceMessage -> !Ways -> !FinderCache -> !FinderOpts -> !SDoc -> Module -> IO (MaybeErr MissingInterfaceError ModIface) -> !Module -> IO (Maybe Linkable) -> LinkDepsOpts
+ GHC.Linker.Deps: LinkDepsOpts :: String -> Bool -> UnitEnv -> SDocContext -> Bool -> DiagnosticOpts IfaceMessage -> Ways -> FinderCache -> FinderOpts -> (Module -> IO (Maybe Linkable)) -> ([Module] -> IO ([Module], UniqDSet UnitId)) -> LinkDepsOpts
- GHC.Linker.Deps: [ldFinderCache] :: LinkDepsOpts -> !FinderCache
+ GHC.Linker.Deps: [ldFinderCache] :: LinkDepsOpts -> FinderCache
- GHC.Linker.Deps: [ldFinderOpts] :: LinkDepsOpts -> !FinderOpts
+ GHC.Linker.Deps: [ldFinderOpts] :: LinkDepsOpts -> FinderOpts
- GHC.Linker.Deps: [ldForceDyn] :: LinkDepsOpts -> !Bool
+ GHC.Linker.Deps: [ldForceDyn] :: LinkDepsOpts -> Bool
- GHC.Linker.Deps: [ldLoadByteCode] :: LinkDepsOpts -> !Module -> IO (Maybe Linkable)
+ GHC.Linker.Deps: [ldLoadByteCode] :: LinkDepsOpts -> Module -> IO (Maybe Linkable)
- GHC.Linker.Deps: [ldMsgOpts] :: LinkDepsOpts -> !DiagnosticOpts IfaceMessage
+ GHC.Linker.Deps: [ldMsgOpts] :: LinkDepsOpts -> DiagnosticOpts IfaceMessage
- GHC.Linker.Deps: [ldObjSuffix] :: LinkDepsOpts -> !String
+ GHC.Linker.Deps: [ldObjSuffix] :: LinkDepsOpts -> String
- GHC.Linker.Deps: [ldPprOpts] :: LinkDepsOpts -> !SDocContext
+ GHC.Linker.Deps: [ldPprOpts] :: LinkDepsOpts -> SDocContext
- GHC.Linker.Deps: [ldUnitEnv] :: LinkDepsOpts -> !UnitEnv
+ GHC.Linker.Deps: [ldUnitEnv] :: LinkDepsOpts -> UnitEnv
- GHC.Linker.Deps: [ldUseByteCode] :: LinkDepsOpts -> !Bool
+ GHC.Linker.Deps: [ldUseByteCode] :: LinkDepsOpts -> Bool
- GHC.Linker.Deps: [ldWays] :: LinkDepsOpts -> !Ways
+ GHC.Linker.Deps: [ldWays] :: LinkDepsOpts -> Ways
- GHC.Linker.External: LinkerConfig :: String -> [Option] -> [Option] -> TempDir -> (String -> String) -> LinkerConfig
+ GHC.Linker.External: LinkerConfig :: String -> [Option] -> [Option] -> TempDir -> ([String] -> [String]) -> LinkerConfig
- GHC.Linker.External: [linkerFilter] :: LinkerConfig -> String -> String
+ GHC.Linker.External: [linkerFilter] :: LinkerConfig -> [String] -> [String]
- GHC.Linker.Loader: LoaderState :: !LinkerEnv -> !LinkableSet -> !LinkableSet -> !PkgsLoaded -> ![(FilePath, String)] -> LoaderState
+ GHC.Linker.Loader: LoaderState :: LinkerEnv -> LinkableSet -> LinkableSet -> PkgsLoaded -> [(FilePath, String)] -> LinkedBreaks -> LoaderState
- GHC.Linker.Loader: [bcos_loaded] :: LoaderState -> !LinkableSet
+ GHC.Linker.Loader: [bcos_loaded] :: LoaderState -> LinkableSet
- GHC.Linker.Loader: [linker_env] :: LoaderState -> !LinkerEnv
+ GHC.Linker.Loader: [linker_env] :: LoaderState -> LinkerEnv
- GHC.Linker.Loader: [objs_loaded] :: LoaderState -> !LinkableSet
+ GHC.Linker.Loader: [objs_loaded] :: LoaderState -> LinkableSet
- GHC.Linker.Loader: [pkgs_loaded] :: LoaderState -> !PkgsLoaded
+ GHC.Linker.Loader: [pkgs_loaded] :: LoaderState -> PkgsLoaded
- GHC.Linker.Loader: [temp_sos] :: LoaderState -> ![(FilePath, String)]
+ GHC.Linker.Loader: [temp_sos] :: LoaderState -> [(FilePath, String)]
- GHC.Linker.Types: Linkable :: !UTCTime -> !Module -> NonEmpty LinkablePart -> Linkable
+ GHC.Linker.Types: Linkable :: UTCTime -> Module -> NonEmpty LinkablePart -> Linkable
- GHC.Linker.Types: LinkerEnv :: !ClosureEnv -> !ItblEnv -> !AddrEnv -> LinkerEnv
+ GHC.Linker.Types: LinkerEnv :: ClosureEnv -> ItblEnv -> AddrEnv -> LinkerEnv
- GHC.Linker.Types: LoadedPkgInfo :: !UnitId -> ![LibrarySpec] -> ![LibrarySpec] -> ![RemotePtr LoadedDLL] -> UniqDSet UnitId -> LoadedPkgInfo
+ GHC.Linker.Types: LoadedPkgInfo :: UnitId -> [LibrarySpec] -> [LibrarySpec] -> [RemotePtr LoadedDLL] -> UniqDSet UnitId -> LoadedPkgInfo
- GHC.Linker.Types: LoaderState :: !LinkerEnv -> !LinkableSet -> !LinkableSet -> !PkgsLoaded -> ![(FilePath, String)] -> LoaderState
+ GHC.Linker.Types: LoaderState :: LinkerEnv -> LinkableSet -> LinkableSet -> PkgsLoaded -> [(FilePath, String)] -> LinkedBreaks -> LoaderState
- GHC.Linker.Types: [addr_env] :: LinkerEnv -> !AddrEnv
+ GHC.Linker.Types: [addr_env] :: LinkerEnv -> AddrEnv
- GHC.Linker.Types: [bcos_loaded] :: LoaderState -> !LinkableSet
+ GHC.Linker.Types: [bcos_loaded] :: LoaderState -> LinkableSet
- GHC.Linker.Types: [closure_env] :: LinkerEnv -> !ClosureEnv
+ GHC.Linker.Types: [closure_env] :: LinkerEnv -> ClosureEnv
- GHC.Linker.Types: [itbl_env] :: LinkerEnv -> !ItblEnv
+ GHC.Linker.Types: [itbl_env] :: LinkerEnv -> ItblEnv
- GHC.Linker.Types: [linkableModule] :: Linkable -> !Module
+ GHC.Linker.Types: [linkableModule] :: Linkable -> Module
- GHC.Linker.Types: [linkableTime] :: Linkable -> !UTCTime
+ GHC.Linker.Types: [linkableTime] :: Linkable -> UTCTime
- GHC.Linker.Types: [linker_env] :: LoaderState -> !LinkerEnv
+ GHC.Linker.Types: [linker_env] :: LoaderState -> LinkerEnv
- GHC.Linker.Types: [loaded_pkg_hs_dlls] :: LoadedPkgInfo -> ![RemotePtr LoadedDLL]
+ GHC.Linker.Types: [loaded_pkg_hs_dlls] :: LoadedPkgInfo -> [RemotePtr LoadedDLL]
- GHC.Linker.Types: [loaded_pkg_hs_objs] :: LoadedPkgInfo -> ![LibrarySpec]
+ GHC.Linker.Types: [loaded_pkg_hs_objs] :: LoadedPkgInfo -> [LibrarySpec]
- GHC.Linker.Types: [loaded_pkg_non_hs_objs] :: LoadedPkgInfo -> ![LibrarySpec]
+ GHC.Linker.Types: [loaded_pkg_non_hs_objs] :: LoadedPkgInfo -> [LibrarySpec]
- GHC.Linker.Types: [loaded_pkg_uid] :: LoadedPkgInfo -> !UnitId
+ GHC.Linker.Types: [loaded_pkg_uid] :: LoadedPkgInfo -> UnitId
- GHC.Linker.Types: [objs_loaded] :: LoaderState -> !LinkableSet
+ GHC.Linker.Types: [objs_loaded] :: LoaderState -> LinkableSet
- GHC.Linker.Types: [pkgs_loaded] :: LoaderState -> !PkgsLoaded
+ GHC.Linker.Types: [pkgs_loaded] :: LoaderState -> PkgsLoaded
- GHC.Linker.Types: [temp_sos] :: LoaderState -> ![(FilePath, String)]
+ GHC.Linker.Types: [temp_sos] :: LoaderState -> [(FilePath, String)]
- GHC.Llvm: MetaLit :: !LlvmLit -> MetaExpr
+ GHC.Llvm: MetaLit :: LlvmLit -> MetaExpr
- GHC.Llvm: MetaNamed :: !LMString -> [MetaId] -> MetaDecl
+ GHC.Llvm: MetaNamed :: LMString -> [MetaId] -> MetaDecl
- GHC.Llvm: MetaNode :: !MetaId -> MetaExpr
+ GHC.Llvm: MetaNode :: MetaId -> MetaExpr
- GHC.Llvm: MetaStr :: !LMString -> MetaExpr
+ GHC.Llvm: MetaStr :: LMString -> MetaExpr
- GHC.Llvm: MetaUnnamed :: !MetaId -> !MetaExpr -> MetaDecl
+ GHC.Llvm: MetaUnnamed :: MetaId -> MetaExpr -> MetaDecl
- GHC.Llvm: MetaVar :: !LlvmVar -> MetaExpr
+ GHC.Llvm: MetaVar :: LlvmVar -> MetaExpr
- GHC.Llvm.MetaData: MetaLit :: !LlvmLit -> MetaExpr
+ GHC.Llvm.MetaData: MetaLit :: LlvmLit -> MetaExpr
- GHC.Llvm.MetaData: MetaNamed :: !LMString -> [MetaId] -> MetaDecl
+ GHC.Llvm.MetaData: MetaNamed :: LMString -> [MetaId] -> MetaDecl
- GHC.Llvm.MetaData: MetaNode :: !MetaId -> MetaExpr
+ GHC.Llvm.MetaData: MetaNode :: MetaId -> MetaExpr
- GHC.Llvm.MetaData: MetaStr :: !LMString -> MetaExpr
+ GHC.Llvm.MetaData: MetaStr :: LMString -> MetaExpr
- GHC.Llvm.MetaData: MetaUnnamed :: !MetaId -> !MetaExpr -> MetaDecl
+ GHC.Llvm.MetaData: MetaUnnamed :: MetaId -> MetaExpr -> MetaDecl
- GHC.Llvm.MetaData: MetaVar :: !LlvmVar -> MetaExpr
+ GHC.Llvm.MetaData: MetaVar :: LlvmVar -> MetaExpr
- GHC.Parser.Annotation: AnnList :: !Maybe EpaLocation -> !AnnListBrackets -> [EpToken ";"] -> !a -> ![TrailingAnn] -> AnnList a
+ GHC.Parser.Annotation: AnnList :: Maybe EpaLocation -> AnnListBrackets -> [EpToken ";"] -> a -> [TrailingAnn] -> AnnList a
- GHC.Parser.Annotation: DifferentLine :: !Int -> !Int -> DeltaPos
+ GHC.Parser.Annotation: DifferentLine :: Int -> Int -> DeltaPos
- GHC.Parser.Annotation: EpAnn :: !EpaLocation -> !ann -> !EpAnnComments -> EpAnn ann
+ GHC.Parser.Annotation: EpAnn :: EpaLocation -> ann -> EpAnnComments -> EpAnn ann
- GHC.Parser.Annotation: EpExplicitBraces :: !EpToken "{" -> !EpToken "}" -> EpLayout
+ GHC.Parser.Annotation: EpExplicitBraces :: EpToken "{" -> EpToken "}" -> EpLayout
- GHC.Parser.Annotation: EpTok :: !EpaLocation -> EpToken (tok :: Symbol)
+ GHC.Parser.Annotation: EpTok :: EpaLocation -> EpToken (tok :: Symbol)
- GHC.Parser.Annotation: EpUniTok :: !EpaLocation -> !IsUnicodeSyntax -> EpUniToken (tok :: Symbol) (utok :: Symbol)
+ GHC.Parser.Annotation: EpUniTok :: EpaLocation -> IsUnicodeSyntax -> EpUniToken (tok :: Symbol) (utok :: Symbol)
- GHC.Parser.Annotation: EpVirtualBraces :: !Int -> EpLayout
+ GHC.Parser.Annotation: EpVirtualBraces :: Int -> EpLayout
- GHC.Parser.Annotation: EpaComments :: ![LEpaComment] -> EpAnnComments
+ GHC.Parser.Annotation: EpaComments :: [LEpaComment] -> EpAnnComments
- GHC.Parser.Annotation: EpaCommentsBalanced :: ![LEpaComment] -> ![LEpaComment] -> EpAnnComments
+ GHC.Parser.Annotation: EpaCommentsBalanced :: [LEpaComment] -> [LEpaComment] -> EpAnnComments
- GHC.Parser.Annotation: EpaDelta :: !SrcSpan -> !DeltaPos -> !a -> EpaLocation' a
+ GHC.Parser.Annotation: EpaDelta :: SrcSpan -> DeltaPos -> a -> EpaLocation' a
- GHC.Parser.Annotation: EpaSpan :: !SrcSpan -> EpaLocation' a
+ GHC.Parser.Annotation: EpaSpan :: SrcSpan -> EpaLocation' a
- GHC.Parser.Annotation: SameLine :: !Int -> DeltaPos
+ GHC.Parser.Annotation: SameLine :: Int -> DeltaPos
- GHC.Parser.Annotation: [al_anchor] :: AnnList a -> !Maybe EpaLocation
+ GHC.Parser.Annotation: [al_anchor] :: AnnList a -> Maybe EpaLocation
- GHC.Parser.Annotation: [al_brackets] :: AnnList a -> !AnnListBrackets
+ GHC.Parser.Annotation: [al_brackets] :: AnnList a -> AnnListBrackets
- GHC.Parser.Annotation: [al_rest] :: AnnList a -> !a
+ GHC.Parser.Annotation: [al_rest] :: AnnList a -> a
- GHC.Parser.Annotation: [al_trailing] :: AnnList a -> ![TrailingAnn]
+ GHC.Parser.Annotation: [al_trailing] :: AnnList a -> [TrailingAnn]
- GHC.Parser.Annotation: [anns] :: EpAnn ann -> !ann
+ GHC.Parser.Annotation: [anns] :: EpAnn ann -> ann
- GHC.Parser.Annotation: [comments] :: EpAnn ann -> !EpAnnComments
+ GHC.Parser.Annotation: [comments] :: EpAnn ann -> EpAnnComments
- GHC.Parser.Annotation: [deltaColumn] :: DeltaPos -> !Int
+ GHC.Parser.Annotation: [deltaColumn] :: DeltaPos -> Int
- GHC.Parser.Annotation: [deltaLine] :: DeltaPos -> !Int
+ GHC.Parser.Annotation: [deltaLine] :: DeltaPos -> Int
- GHC.Parser.Annotation: [entry] :: EpAnn ann -> !EpaLocation
+ GHC.Parser.Annotation: [entry] :: EpAnn ann -> EpaLocation
- GHC.Parser.Annotation: [followingComments] :: EpAnnComments -> ![LEpaComment]
+ GHC.Parser.Annotation: [followingComments] :: EpAnnComments -> [LEpaComment]
- GHC.Parser.Annotation: [priorComments] :: EpAnnComments -> ![LEpaComment]
+ GHC.Parser.Annotation: [priorComments] :: EpAnnComments -> [LEpaComment]
- GHC.Parser.Errors.Types: CmmUnknownCConv :: !String -> CmmParserError
+ GHC.Parser.Errors.Types: CmmUnknownCConv :: String -> CmmParserError
- GHC.Parser.Errors.Types: CmmUnknownMacro :: !FastString -> CmmParserError
+ GHC.Parser.Errors.Types: CmmUnknownMacro :: FastString -> CmmParserError
- GHC.Parser.Errors.Types: CmmUnknownPrimitive :: !FastString -> CmmParserError
+ GHC.Parser.Errors.Types: CmmUnknownPrimitive :: FastString -> CmmParserError
- GHC.Parser.Errors.Types: CmmUnrecognisedHint :: !String -> CmmParserError
+ GHC.Parser.Errors.Types: CmmUnrecognisedHint :: String -> CmmParserError
- GHC.Parser.Errors.Types: CmmUnrecognisedSafety :: !String -> CmmParserError
+ GHC.Parser.Errors.Types: CmmUnrecognisedSafety :: String -> CmmParserError
- GHC.Parser.Errors.Types: LexErrKind_Char :: !Char -> LexErrKind
+ GHC.Parser.Errors.Types: LexErrKind_Char :: Char -> LexErrKind
- GHC.Parser.Errors.Types: PEIP_OtherPatDetails :: !ParseContext -> PsErrInPatDetails
+ GHC.Parser.Errors.Types: PEIP_OtherPatDetails :: ParseContext -> PsErrInPatDetails
- GHC.Parser.Errors.Types: PEIP_RecPattern :: [LPat GhcPs] -> !PatIsRecursive -> !ParseContext -> PsErrInPatDetails
+ GHC.Parser.Errors.Types: PEIP_RecPattern :: [LPat GhcPs] -> PatIsRecursive -> ParseContext -> PsErrInPatDetails
- GHC.Parser.Errors.Types: PETS_ConstraintContext :: !LocatedA (PatBuilder GhcPs) -> PsErrTypeSyntaxDetails
+ GHC.Parser.Errors.Types: PETS_ConstraintContext :: LocatedA (PatBuilder GhcPs) -> PsErrTypeSyntaxDetails
- GHC.Parser.Errors.Types: PETS_ForallTelescope :: !HsForAllTelescope GhcPs -> !LocatedA (PatBuilder GhcPs) -> PsErrTypeSyntaxDetails
+ GHC.Parser.Errors.Types: PETS_ForallTelescope :: HsForAllTelescope GhcPs -> LocatedA (PatBuilder GhcPs) -> PsErrTypeSyntaxDetails
- GHC.Parser.Errors.Types: PETS_FunctionArrow :: !LocatedA (PatBuilder GhcPs) -> !HsArrowOf (LocatedA (PatBuilder GhcPs)) GhcPs -> !LocatedA (PatBuilder GhcPs) -> PsErrTypeSyntaxDetails
+ GHC.Parser.Errors.Types: PETS_FunctionArrow :: LocatedA (PatBuilder GhcPs) -> HsMultAnnOf (LocatedA (PatBuilder GhcPs)) GhcPs -> LocatedA (PatBuilder GhcPs) -> PsErrTypeSyntaxDetails
- GHC.Parser.Errors.Types: PETS_Multiplicity :: !EpToken "%" -> !LocatedA (PatBuilder GhcPs) -> PsErrTypeSyntaxDetails
+ GHC.Parser.Errors.Types: PETS_Multiplicity :: EpToken "%" -> LocatedA (PatBuilder GhcPs) -> PsErrTypeSyntaxDetails
- GHC.Parser.Errors.Types: ParseContext :: !Maybe RdrName -> !PatIncompleteDoBlock -> ParseContext
+ GHC.Parser.Errors.Types: ParseContext :: Maybe RdrName -> PatIncompleteDoBlock -> ParseContext
- GHC.Parser.Errors.Types: PsErrArrowCmdInExpr :: !HsCmd GhcPs -> PsMessage
+ GHC.Parser.Errors.Types: PsErrArrowCmdInExpr :: HsCmd GhcPs -> PsMessage
- GHC.Parser.Errors.Types: PsErrArrowCmdInPat :: !HsCmd GhcPs -> PsMessage
+ GHC.Parser.Errors.Types: PsErrArrowCmdInPat :: HsCmd GhcPs -> PsMessage
- GHC.Parser.Errors.Types: PsErrArrowExprInPat :: !HsExpr GhcPs -> PsMessage
+ GHC.Parser.Errors.Types: PsErrArrowExprInPat :: HsExpr GhcPs -> PsMessage
- GHC.Parser.Errors.Types: PsErrBangPatWithoutSpace :: !LHsExpr GhcPs -> PsMessage
+ GHC.Parser.Errors.Types: PsErrBangPatWithoutSpace :: LHsExpr GhcPs -> PsMessage
- GHC.Parser.Errors.Types: PsErrCaseCmdInFunAppCmd :: !LHsCmd GhcPs -> PsMessage
+ GHC.Parser.Errors.Types: PsErrCaseCmdInFunAppCmd :: LHsCmd GhcPs -> PsMessage
- GHC.Parser.Errors.Types: PsErrCaseInFunAppExpr :: !LHsExpr GhcPs -> PsMessage
+ GHC.Parser.Errors.Types: PsErrCaseInFunAppExpr :: LHsExpr GhcPs -> PsMessage
- GHC.Parser.Errors.Types: PsErrCmmParser :: !CmmParserError -> PsMessage
+ GHC.Parser.Errors.Types: PsErrCmmParser :: CmmParserError -> PsMessage
- GHC.Parser.Errors.Types: PsErrDeclSpliceNotAtTopLevel :: !SpliceDecl GhcPs -> PsMessage
+ GHC.Parser.Errors.Types: PsErrDeclSpliceNotAtTopLevel :: SpliceDecl GhcPs -> PsMessage
- GHC.Parser.Errors.Types: PsErrDoCmdInFunAppCmd :: !LHsCmd GhcPs -> PsMessage
+ GHC.Parser.Errors.Types: PsErrDoCmdInFunAppCmd :: LHsCmd GhcPs -> PsMessage
- GHC.Parser.Errors.Types: PsErrDoInFunAppExpr :: !Maybe ModuleName -> !LHsExpr GhcPs -> PsMessage
+ GHC.Parser.Errors.Types: PsErrDoInFunAppExpr :: Maybe ModuleName -> LHsExpr GhcPs -> PsMessage
- GHC.Parser.Errors.Types: PsErrEmptyDoubleQuotes :: !Bool -> PsMessage
+ GHC.Parser.Errors.Types: PsErrEmptyDoubleQuotes :: Bool -> PsMessage
- GHC.Parser.Errors.Types: PsErrEmptyWhereInPatSynDecl :: !RdrName -> PsMessage
+ GHC.Parser.Errors.Types: PsErrEmptyWhereInPatSynDecl :: RdrName -> PsMessage
- GHC.Parser.Errors.Types: PsErrExplicitForall :: !Bool -> PsMessage
+ GHC.Parser.Errors.Types: PsErrExplicitForall :: Bool -> PsMessage
- GHC.Parser.Errors.Types: PsErrIfCmdInFunAppCmd :: !LHsCmd GhcPs -> PsMessage
+ GHC.Parser.Errors.Types: PsErrIfCmdInFunAppCmd :: LHsCmd GhcPs -> PsMessage
- GHC.Parser.Errors.Types: PsErrIfInFunAppExpr :: !LHsExpr GhcPs -> PsMessage
+ GHC.Parser.Errors.Types: PsErrIfInFunAppExpr :: LHsExpr GhcPs -> PsMessage
- GHC.Parser.Errors.Types: PsErrIllegalBangPattern :: !Pat GhcPs -> PsMessage
+ GHC.Parser.Errors.Types: PsErrIllegalBangPattern :: Pat GhcPs -> PsMessage
- GHC.Parser.Errors.Types: PsErrIllegalDataTypeContext :: !LHsContext GhcPs -> PsMessage
+ GHC.Parser.Errors.Types: PsErrIllegalDataTypeContext :: LHsContext GhcPs -> PsMessage
- GHC.Parser.Errors.Types: PsErrIllegalExplicitNamespace :: PsMessage
+ GHC.Parser.Errors.Types: PsErrIllegalExplicitNamespace :: ExplicitNamespaceKeyword -> PsMessage
- GHC.Parser.Errors.Types: PsErrIllegalGadtRecordMultiplicity :: !HsArrow GhcPs -> PsMessage
+ GHC.Parser.Errors.Types: PsErrIllegalGadtRecordMultiplicity :: HsMultAnn GhcPs -> PsMessage
- GHC.Parser.Errors.Types: PsErrIllegalPromotionQuoteDataCon :: !RdrName -> PsMessage
+ GHC.Parser.Errors.Types: PsErrIllegalPromotionQuoteDataCon :: RdrName -> PsMessage
- GHC.Parser.Errors.Types: PsErrIllegalQualifiedDo :: !SDoc -> PsMessage
+ GHC.Parser.Errors.Types: PsErrIllegalQualifiedDo :: SDoc -> PsMessage
- GHC.Parser.Errors.Types: PsErrIllegalRoleName :: !FastString -> [Role] -> PsMessage
+ GHC.Parser.Errors.Types: PsErrIllegalRoleName :: FastString -> [Role] -> PsMessage
- GHC.Parser.Errors.Types: PsErrIllegalTraditionalRecordSyntax :: !SDoc -> PsMessage
+ GHC.Parser.Errors.Types: PsErrIllegalTraditionalRecordSyntax :: SDoc -> PsMessage
- GHC.Parser.Errors.Types: PsErrIllegalUnboxedFloatingLitInPat :: !HsLit GhcPs -> PsMessage
+ GHC.Parser.Errors.Types: PsErrIllegalUnboxedFloatingLitInPat :: HsLit GhcPs -> PsMessage
- GHC.Parser.Errors.Types: PsErrIllegalUnboxedStringInPat :: !HsLit GhcPs -> PsMessage
+ GHC.Parser.Errors.Types: PsErrIllegalUnboxedStringInPat :: HsLit GhcPs -> PsMessage
- GHC.Parser.Errors.Types: PsErrInPat :: !PatBuilder GhcPs -> !PsErrInPatDetails -> PsMessage
+ GHC.Parser.Errors.Types: PsErrInPat :: PatBuilder GhcPs -> PsErrInPatDetails -> PsMessage
- GHC.Parser.Errors.Types: PsErrInvalidDataCon :: !HsType GhcPs -> PsMessage
+ GHC.Parser.Errors.Types: PsErrInvalidDataCon :: HsType GhcPs -> PsMessage
- GHC.Parser.Errors.Types: PsErrInvalidInfixDataCon :: !HsType GhcPs -> !RdrName -> !HsType GhcPs -> PsMessage
+ GHC.Parser.Errors.Types: PsErrInvalidInfixDataCon :: HsType GhcPs -> RdrName -> HsType GhcPs -> PsMessage
- GHC.Parser.Errors.Types: PsErrInvalidPackageName :: !FastString -> PsMessage
+ GHC.Parser.Errors.Types: PsErrInvalidPackageName :: FastString -> PsMessage
- GHC.Parser.Errors.Types: PsErrInvalidPun :: !PsErrPunDetails -> PsMessage
+ GHC.Parser.Errors.Types: PsErrInvalidPun :: PsErrPunDetails -> PsMessage
- GHC.Parser.Errors.Types: PsErrInvalidRecordCon :: !PatBuilder GhcPs -> PsMessage
+ GHC.Parser.Errors.Types: PsErrInvalidRecordCon :: PatBuilder GhcPs -> PsMessage
- GHC.Parser.Errors.Types: PsErrInvalidTypeSignature :: !PsInvalidTypeSignature -> !LHsExpr GhcPs -> PsMessage
+ GHC.Parser.Errors.Types: PsErrInvalidTypeSignature :: PsInvalidTypeSignature -> LHsExpr GhcPs -> PsMessage
- GHC.Parser.Errors.Types: PsErrInvalidWhereBindInPatSynDecl :: !RdrName -> !HsDecl GhcPs -> PsMessage
+ GHC.Parser.Errors.Types: PsErrInvalidWhereBindInPatSynDecl :: RdrName -> HsDecl GhcPs -> PsMessage
- GHC.Parser.Errors.Types: PsErrLambdaCmdInFunAppCmd :: !HsLamVariant -> !LHsCmd GhcPs -> PsMessage
+ GHC.Parser.Errors.Types: PsErrLambdaCmdInFunAppCmd :: HsLamVariant -> LHsCmd GhcPs -> PsMessage
- GHC.Parser.Errors.Types: PsErrLambdaInFunAppExpr :: !HsLamVariant -> !LHsExpr GhcPs -> PsMessage
+ GHC.Parser.Errors.Types: PsErrLambdaInFunAppExpr :: HsLamVariant -> LHsExpr GhcPs -> PsMessage
- GHC.Parser.Errors.Types: PsErrLazyPatWithoutSpace :: !LHsExpr GhcPs -> PsMessage
+ GHC.Parser.Errors.Types: PsErrLazyPatWithoutSpace :: LHsExpr GhcPs -> PsMessage
- GHC.Parser.Errors.Types: PsErrLetCmdInFunAppCmd :: !LHsCmd GhcPs -> PsMessage
+ GHC.Parser.Errors.Types: PsErrLetCmdInFunAppCmd :: LHsCmd GhcPs -> PsMessage
- GHC.Parser.Errors.Types: PsErrLetInFunAppExpr :: !LHsExpr GhcPs -> PsMessage
+ GHC.Parser.Errors.Types: PsErrLetInFunAppExpr :: LHsExpr GhcPs -> PsMessage
- GHC.Parser.Errors.Types: PsErrLexer :: !LexErr -> !LexErrKind -> PsMessage
+ GHC.Parser.Errors.Types: PsErrLexer :: LexErr -> LexErrKind -> PsMessage
- GHC.Parser.Errors.Types: PsErrMDoInFunAppExpr :: !Maybe ModuleName -> !LHsExpr GhcPs -> PsMessage
+ GHC.Parser.Errors.Types: PsErrMDoInFunAppExpr :: Maybe ModuleName -> LHsExpr GhcPs -> PsMessage
- GHC.Parser.Errors.Types: PsErrMalformedDecl :: !SDoc -> !RdrName -> PsMessage
+ GHC.Parser.Errors.Types: PsErrMalformedDecl :: SDoc -> RdrName -> PsMessage
- GHC.Parser.Errors.Types: PsErrMalformedTyOrClDecl :: !LHsType GhcPs -> PsMessage
+ GHC.Parser.Errors.Types: PsErrMalformedTyOrClDecl :: LHsType GhcPs -> PsMessage
- GHC.Parser.Errors.Types: PsErrMultipleConForNewtype :: !RdrName -> !Int -> PsMessage
+ GHC.Parser.Errors.Types: PsErrMultipleConForNewtype :: RdrName -> Int -> PsMessage
- GHC.Parser.Errors.Types: PsErrNoSingleWhereBindInPatSynDecl :: !RdrName -> !HsDecl GhcPs -> PsMessage
+ GHC.Parser.Errors.Types: PsErrNoSingleWhereBindInPatSynDecl :: RdrName -> HsDecl GhcPs -> PsMessage
- GHC.Parser.Errors.Types: PsErrNotADataCon :: !RdrName -> PsMessage
+ GHC.Parser.Errors.Types: PsErrNotADataCon :: RdrName -> PsMessage
- GHC.Parser.Errors.Types: PsErrNumUnderscores :: !NumUnderscoreReason -> PsMessage
+ GHC.Parser.Errors.Types: PsErrNumUnderscores :: NumUnderscoreReason -> PsMessage
- GHC.Parser.Errors.Types: PsErrOpFewArgs :: !StarIsType -> !RdrName -> PsMessage
+ GHC.Parser.Errors.Types: PsErrOpFewArgs :: StarIsType -> RdrName -> PsMessage
- GHC.Parser.Errors.Types: PsErrOrPatInExpr :: !LPat GhcPs -> PsMessage
+ GHC.Parser.Errors.Types: PsErrOrPatInExpr :: LPat GhcPs -> PsMessage
- GHC.Parser.Errors.Types: PsErrParse :: !String -> !PsErrParseDetails -> PsMessage
+ GHC.Parser.Errors.Types: PsErrParse :: String -> PsErrParseDetails -> PsMessage
- GHC.Parser.Errors.Types: PsErrParseDetails :: !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> PsErrParseDetails
+ GHC.Parser.Errors.Types: PsErrParseDetails :: Bool -> Bool -> Bool -> Bool -> Bool -> PsErrParseDetails
- GHC.Parser.Errors.Types: PsErrParseErrorInCmd :: !SDoc -> PsMessage
+ GHC.Parser.Errors.Types: PsErrParseErrorInCmd :: SDoc -> PsMessage
- GHC.Parser.Errors.Types: PsErrParseErrorOnInput :: !OccName -> PsMessage
+ GHC.Parser.Errors.Types: PsErrParseErrorOnInput :: OccName -> PsMessage
- GHC.Parser.Errors.Types: PsErrParseOptionsPragma :: !String -> PsHeaderMessage
+ GHC.Parser.Errors.Types: PsErrParseOptionsPragma :: String -> PsHeaderMessage
- GHC.Parser.Errors.Types: PsErrParseRightOpSectionInPat :: !RdrName -> !PatBuilder GhcPs -> PsMessage
+ GHC.Parser.Errors.Types: PsErrParseRightOpSectionInPat :: RdrName -> PatBuilder GhcPs -> PsMessage
- GHC.Parser.Errors.Types: PsErrPrecedenceOutOfRange :: !Int -> PsMessage
+ GHC.Parser.Errors.Types: PsErrPrecedenceOutOfRange :: Int -> PsMessage
- GHC.Parser.Errors.Types: PsErrProcInFunAppExpr :: !LHsExpr GhcPs -> PsMessage
+ GHC.Parser.Errors.Types: PsErrProcInFunAppExpr :: LHsExpr GhcPs -> PsMessage
- GHC.Parser.Errors.Types: PsErrQualifiedDoInCmd :: !ModuleName -> PsMessage
+ GHC.Parser.Errors.Types: PsErrQualifiedDoInCmd :: ModuleName -> PsMessage
- GHC.Parser.Errors.Types: PsErrRecordSyntaxInPatSynDecl :: !LPat GhcPs -> PsMessage
+ GHC.Parser.Errors.Types: PsErrRecordSyntaxInPatSynDecl :: LPat GhcPs -> PsMessage
- GHC.Parser.Errors.Types: PsErrSemiColonsInCondCmd :: !HsExpr GhcPs -> !Bool -> !HsCmd GhcPs -> !Bool -> !HsCmd GhcPs -> PsMessage
+ GHC.Parser.Errors.Types: PsErrSemiColonsInCondCmd :: HsExpr GhcPs -> Bool -> HsCmd GhcPs -> Bool -> HsCmd GhcPs -> PsMessage
- GHC.Parser.Errors.Types: PsErrSemiColonsInCondExpr :: !HsExpr GhcPs -> !Bool -> !HsExpr GhcPs -> !Bool -> !HsExpr GhcPs -> PsMessage
+ GHC.Parser.Errors.Types: PsErrSemiColonsInCondExpr :: HsExpr GhcPs -> Bool -> HsExpr GhcPs -> Bool -> HsExpr GhcPs -> PsMessage
- GHC.Parser.Errors.Types: PsErrTypeAppWithoutSpace :: !RdrName -> !LHsExpr GhcPs -> PsMessage
+ GHC.Parser.Errors.Types: PsErrTypeAppWithoutSpace :: RdrName -> LHsExpr GhcPs -> PsMessage
- GHC.Parser.Errors.Types: PsErrTypeSyntaxInPat :: !PsErrTypeSyntaxDetails -> PsMessage
+ GHC.Parser.Errors.Types: PsErrTypeSyntaxInPat :: PsErrTypeSyntaxDetails -> PsMessage
- GHC.Parser.Errors.Types: PsErrUnallowedPragma :: !HsPragE GhcPs -> PsMessage
+ GHC.Parser.Errors.Types: PsErrUnallowedPragma :: HsPragE GhcPs -> PsMessage
- GHC.Parser.Errors.Types: PsErrUnexpectedKindAppInDataCon :: !DataConBuilder -> !HsType GhcPs -> PsMessage
+ GHC.Parser.Errors.Types: PsErrUnexpectedKindAppInDataCon :: DataConBuilder -> HsType GhcPs -> PsMessage
- GHC.Parser.Errors.Types: PsErrUnexpectedQualifiedConstructor :: !RdrName -> PsMessage
+ GHC.Parser.Errors.Types: PsErrUnexpectedQualifiedConstructor :: RdrName -> PsMessage
- GHC.Parser.Errors.Types: PsErrUnexpectedTypeInDecl :: !LHsType GhcPs -> !SDoc -> !RdrName -> [LHsTypeArg GhcPs] -> !SDoc -> PsMessage
+ GHC.Parser.Errors.Types: PsErrUnexpectedTypeInDecl :: LHsType GhcPs -> SDoc -> RdrName -> [LHsTypeArg GhcPs] -> SDoc -> PsMessage
- GHC.Parser.Errors.Types: PsErrUnknownOptionsPragma :: !String -> PsHeaderMessage
+ GHC.Parser.Errors.Types: PsErrUnknownOptionsPragma :: String -> PsHeaderMessage
- GHC.Parser.Errors.Types: PsErrUnsupportedBoxedSumExpr :: !SumOrTuple (HsExpr GhcPs) -> PsMessage
+ GHC.Parser.Errors.Types: PsErrUnsupportedBoxedSumExpr :: SumOrTuple (HsExpr GhcPs) -> PsMessage
- GHC.Parser.Errors.Types: PsErrUnsupportedBoxedSumPat :: !SumOrTuple (PatBuilder GhcPs) -> PsMessage
+ GHC.Parser.Errors.Types: PsErrUnsupportedBoxedSumPat :: SumOrTuple (PatBuilder GhcPs) -> PsMessage
- GHC.Parser.Errors.Types: PsErrUnsupportedExt :: !String -> ![String] -> PsHeaderMessage
+ GHC.Parser.Errors.Types: PsErrUnsupportedExt :: String -> [String] -> PsHeaderMessage
- GHC.Parser.Errors.Types: PsErrVarForTyCon :: !RdrName -> PsMessage
+ GHC.Parser.Errors.Types: PsErrVarForTyCon :: RdrName -> PsMessage
- GHC.Parser.Errors.Types: PsHeaderMessage :: !PsHeaderMessage -> PsMessage
+ GHC.Parser.Errors.Types: PsHeaderMessage :: PsHeaderMessage -> PsMessage
- GHC.Parser.Errors.Types: PsUnknownMessage :: UnknownDiagnostic (DiagnosticOpts PsMessage) -> PsMessage
+ GHC.Parser.Errors.Types: PsUnknownMessage :: UnknownDiagnosticFor PsMessage -> PsMessage
- GHC.Parser.Errors.Types: PsWarnMisplacedPragma :: !FileHeaderPragmaType -> PsMessage
+ GHC.Parser.Errors.Types: PsWarnMisplacedPragma :: FileHeaderPragmaType -> PsMessage
- GHC.Parser.Errors.Types: PsWarnOperatorWhitespace :: !FastString -> !OperatorWhitespaceOccurrence -> PsMessage
+ GHC.Parser.Errors.Types: PsWarnOperatorWhitespace :: FastString -> OperatorWhitespaceOccurrence -> PsMessage
- GHC.Parser.Errors.Types: PsWarnOperatorWhitespaceExtConflict :: !OperatorWhitespaceSymbol -> PsMessage
+ GHC.Parser.Errors.Types: PsWarnOperatorWhitespaceExtConflict :: OperatorWhitespaceSymbol -> PsMessage
- GHC.Parser.Errors.Types: PsWarnTab :: !Word -> PsMessage
+ GHC.Parser.Errors.Types: PsWarnTab :: Word -> PsMessage
- GHC.Parser.Errors.Types: PsWarnTransitionalLayout :: !TransLayoutReason -> PsMessage
+ GHC.Parser.Errors.Types: PsWarnTransitionalLayout :: TransLayoutReason -> PsMessage
- GHC.Parser.Errors.Types: PsWarnUnrecognisedPragma :: !String -> ![String] -> PsMessage
+ GHC.Parser.Errors.Types: PsWarnUnrecognisedPragma :: String -> [String] -> PsMessage
- GHC.Parser.Errors.Types: PsWarnViewPatternSignatures :: !LPat GhcPs -> !LPat GhcPs -> PsMessage
+ GHC.Parser.Errors.Types: PsWarnViewPatternSignatures :: LPat GhcPs -> LPat GhcPs -> PsMessage
- GHC.Parser.Errors.Types: [incomplete_do_block] :: ParseContext -> !PatIncompleteDoBlock
+ GHC.Parser.Errors.Types: [incomplete_do_block] :: ParseContext -> PatIncompleteDoBlock
- GHC.Parser.Errors.Types: [is_infix] :: ParseContext -> !Maybe RdrName
+ GHC.Parser.Errors.Types: [is_infix] :: ParseContext -> Maybe RdrName
- GHC.Parser.Errors.Types: [ped_do_in_last_100] :: PsErrParseDetails -> !Bool
+ GHC.Parser.Errors.Types: [ped_do_in_last_100] :: PsErrParseDetails -> Bool
- GHC.Parser.Errors.Types: [ped_mdo_in_last_100] :: PsErrParseDetails -> !Bool
+ GHC.Parser.Errors.Types: [ped_mdo_in_last_100] :: PsErrParseDetails -> Bool
- GHC.Parser.Errors.Types: [ped_pat_syn_enabled] :: PsErrParseDetails -> !Bool
+ GHC.Parser.Errors.Types: [ped_pat_syn_enabled] :: PsErrParseDetails -> Bool
- GHC.Parser.Errors.Types: [ped_pattern_parsed] :: PsErrParseDetails -> !Bool
+ GHC.Parser.Errors.Types: [ped_pattern_parsed] :: PsErrParseDetails -> Bool
- GHC.Parser.Errors.Types: [ped_th_enabled] :: PsErrParseDetails -> !Bool
+ GHC.Parser.Errors.Types: [ped_th_enabled] :: PsErrParseDetails -> Bool
- GHC.Parser.Header: getImports :: ParserOpts -> Bool -> StringBuffer -> FilePath -> FilePath -> IO (Either (Messages PsMessage) ([(RawPkgQual, Located ModuleName)], [(RawPkgQual, Located ModuleName)], Bool, Located ModuleName))
+ GHC.Parser.Header: getImports :: ParserOpts -> Bool -> StringBuffer -> FilePath -> FilePath -> IO (Either (Messages PsMessage) ([Located ModuleName], [(ImportLevel, RawPkgQual, Located ModuleName)], Located ModuleName))
- GHC.Parser.Header: getOptions :: ParserOpts -> StringBuffer -> FilePath -> (Messages PsMessage, [Located String])
+ GHC.Parser.Header: getOptions :: ParserOpts -> [String] -> StringBuffer -> FilePath -> (Messages PsMessage, [Located String])
- GHC.Parser.Header: getOptionsFromFile :: ParserOpts -> FilePath -> IO (Messages PsMessage, [Located String])
+ GHC.Parser.Header: getOptionsFromFile :: ParserOpts -> [String] -> FilePath -> IO (Messages PsMessage, [Located String])
- GHC.Parser.Lexer: ITqQuasiQuote :: (FastString, FastString, FastString, PsSpan) -> Token
+ GHC.Parser.Lexer: ITqQuasiQuote :: (FastString, FastString, PsSpan, FastString, PsSpan) -> Token
- GHC.Parser.Lexer: ITquasiQuote :: (FastString, FastString, PsSpan) -> Token
+ GHC.Parser.Lexer: ITquasiQuote :: (FastString, PsSpan, FastString, PsSpan) -> Token
- GHC.Parser.Lexer: PState :: StringBuffer -> ParserOpts -> Messages PsMessage -> Messages PsMessage -> Maybe RealSrcSpan -> !Word -> Maybe (PsLocated Token) -> PsSpan -> PsSpan -> !Int -> PsLoc -> [LayoutContext] -> [Int] -> [FastString] -> [PsLocated Token] -> Maybe (PsLocated Token) -> PsSpan -> [ALRContext] -> Maybe ALRLayout -> Bool -> Maybe (Pair RealSrcSpan RealSrcSpan) -> Maybe [LEpaComment] -> [LEpaComment] -> OrdList (PsLocated HdkComment) -> PState
+ GHC.Parser.Lexer: PState :: StringBuffer -> ParserOpts -> Messages PsMessage -> Messages PsMessage -> Maybe RealSrcSpan -> Word -> Maybe (PsLocated Token) -> PsSpan -> PsSpan -> Int -> PsLoc -> [LayoutContext] -> [Int] -> [FastString] -> [PsLocated Token] -> Maybe (PsLocated Token) -> PsSpan -> [ALRContext] -> Maybe ALRLayout -> Bool -> Maybe (Pair RealSrcSpan RealSrcSpan) -> Maybe [LEpaComment] -> [LEpaComment] -> OrdList (PsLocated HdkComment) -> PState
- GHC.Parser.Lexer: ParserOpts :: !ExtsBitmap -> !DiagOpts -> [String] -> ParserOpts
+ GHC.Parser.Lexer: ParserOpts :: ExtsBitmap -> DiagOpts -> ParserOpts
- GHC.Parser.Lexer: [last_len] :: PState -> !Int
+ GHC.Parser.Lexer: [last_len] :: PState -> Int
- GHC.Parser.Lexer: [pDiagOpts] :: ParserOpts -> !DiagOpts
+ GHC.Parser.Lexer: [pDiagOpts] :: ParserOpts -> DiagOpts
- GHC.Parser.Lexer: [pExtsBitmap] :: ParserOpts -> !ExtsBitmap
+ GHC.Parser.Lexer: [pExtsBitmap] :: ParserOpts -> ExtsBitmap
- GHC.Parser.Lexer: [tab_count] :: PState -> !Word
+ GHC.Parser.Lexer: [tab_count] :: PState -> Word
- GHC.Parser.Lexer: mkParserOpts :: EnumSet Extension -> DiagOpts -> [String] -> Bool -> Bool -> Bool -> Bool -> ParserOpts
+ GHC.Parser.Lexer: mkParserOpts :: EnumSet Extension -> DiagOpts -> Bool -> Bool -> Bool -> Bool -> ParserOpts
- GHC.Parser.Lexer.Interface: AI :: !PsLoc -> !StringBuffer -> AlexInput
+ GHC.Parser.Lexer.Interface: AI :: PsLoc -> StringBuffer -> AlexInput
- GHC.Parser.Lexer.String: AlexError :: !AlexInput -> AlexReturn a
+ GHC.Parser.Lexer.String: AlexError :: AlexInput -> AlexReturn a
- GHC.Parser.Lexer.String: AlexSkip :: !AlexInput -> !Int -> AlexReturn a
+ GHC.Parser.Lexer.String: AlexSkip :: AlexInput -> Int -> AlexReturn a
- GHC.Parser.Lexer.String: AlexToken :: !AlexInput -> !Int -> a -> AlexReturn a
+ GHC.Parser.Lexer.String: AlexToken :: AlexInput -> Int -> a -> AlexReturn a
- GHC.Parser.PostProcess: ImpExpQcName :: LocatedN RdrName -> ImpExpQcSpec
+ GHC.Parser.PostProcess: ImpExpQcName :: Maybe ExplicitNamespaceKeyword -> LocatedN RdrName -> ImpExpQcSpec
- GHC.Parser.PostProcess: ParseContext :: !Maybe RdrName -> !PatIncompleteDoBlock -> ParseContext
+ GHC.Parser.PostProcess: ParseContext :: Maybe RdrName -> PatIncompleteDoBlock -> ParseContext
- GHC.Parser.PostProcess: [incomplete_do_block] :: ParseContext -> !PatIncompleteDoBlock
+ GHC.Parser.PostProcess: [incomplete_do_block] :: ParseContext -> PatIncompleteDoBlock
- GHC.Parser.PostProcess: [is_infix] :: ParseContext -> !Maybe RdrName
+ GHC.Parser.PostProcess: [is_infix] :: ParseContext -> Maybe RdrName
- GHC.Parser.PostProcess: checkImportDecl :: Maybe (EpToken "qualified") -> Maybe (EpToken "qualified") -> P ()
+ GHC.Parser.PostProcess: checkImportDecl :: Maybe (EpToken "qualified") -> Maybe (EpToken "qualified") -> Maybe EpAnnLevel -> Maybe EpAnnLevel -> P ((Maybe (EpToken "qualified"), ImportDeclQualifiedStyle), (Maybe EpAnnLevel, ImportDeclLevelStyle))
- GHC.Parser.PostProcess: checkRuleTyVarBndrNames :: [LHsTyVarBndr flag GhcPs] -> P ()
+ GHC.Parser.PostProcess: checkRuleTyVarBndrNames :: [LRuleTyTmVar] -> P ()
- GHC.Parser.PostProcess: mkHsArrowPV :: DisambECP b => SrcSpan -> ArrowParsingMode lhs b -> LocatedA lhs -> HsArrowOf (LocatedA b) GhcPs -> LocatedA b -> PV (LocatedA b)
+ GHC.Parser.PostProcess: mkHsArrowPV :: DisambECP b => SrcSpan -> ArrowParsingMode lhs b -> LocatedA lhs -> HsMultAnnOf (LocatedA b) GhcPs -> LocatedA b -> PV (LocatedA b)
- GHC.Parser.PostProcess: mkHsInfixHolePV :: DisambInfixOp b => LocatedN (HsExpr GhcPs) -> PV (LocatedN b)
+ GHC.Parser.PostProcess: mkHsInfixHolePV :: DisambInfixOp b => LocatedN RdrName -> PV (LocatedN b)
- GHC.Parser.PostProcess: mkHsMultPV :: DisambECP b => EpToken "%" -> LocatedA b -> PV (TokRarrow -> HsArrowOf (LocatedA b) GhcPs)
+ GHC.Parser.PostProcess: mkHsMultPV :: DisambECP b => EpToken "%" -> LocatedA b -> PV (TokRarrow -> HsMultAnnOf (LocatedA b) GhcPs)
- GHC.Parser.PostProcess: mkHsProjUpdatePV :: DisambECP b => SrcSpan -> Located [LocatedAn NoEpAnns (DotFieldOcc GhcPs)] -> LocatedA b -> Bool -> Maybe (EpToken "=") -> PV (LHsRecProj GhcPs (LocatedA b))
+ GHC.Parser.PostProcess: mkHsProjUpdatePV :: DisambECP b => SrcSpan -> Located (NonEmpty (LocatedAn NoEpAnns (DotFieldOcc GhcPs))) -> LocatedA b -> Bool -> Maybe (EpToken "=") -> PV (LHsRecProj GhcPs (LocatedA b))
- GHC.Parser.PostProcess: mkMultAnn :: EpToken "%" -> LHsType GhcPs -> HsMultAnn GhcPs
+ GHC.Parser.PostProcess: mkMultAnn :: EpToken "%" -> LHsType GhcPs -> EpArrowOrColon -> HsMultAnn GhcPs
- GHC.Parser.PostProcess: mkRuleBndrs :: [LRuleTyTmVar] -> [LRuleBndr GhcPs]
+ GHC.Parser.PostProcess: mkRuleBndrs :: HsRuleBndrsAnn -> Maybe [LRuleTyTmVar] -> [LRuleTyTmVar] -> RuleBndrs GhcPs
- GHC.Parser.PostProcess: mkTypeImpExp :: LocatedN RdrName -> P (LocatedN RdrName)
+ GHC.Parser.PostProcess: mkTypeImpExp :: EpToken "type" -> LocatedN RdrName -> P ImpExpQcSpec
- GHC.Platform: Platform :: !ArchOS -> !PlatformWordSize -> !ByteOrder -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Maybe PlatformConstants -> Platform
+ GHC.Platform: Platform :: ArchOS -> PlatformWordSize -> ByteOrder -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Maybe PlatformConstants -> Platform
- GHC.Platform: PlatformConstants :: {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> !Integer -> !Integer -> !Integer -> !Bool -> PlatformConstants
+ GHC.Platform: PlatformConstants :: Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Integer -> Integer -> Integer -> Bool -> PlatformConstants
- GHC.Platform: [pc_AP_STACK_SPLIM] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_AP_STACK_SPLIM] :: PlatformConstants -> Int
- GHC.Platform: [pc_BITMAP_BITS_SHIFT] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_BITMAP_BITS_SHIFT] :: PlatformConstants -> Int
- GHC.Platform: [pc_BLOCKS_PER_MBLOCK] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_BLOCKS_PER_MBLOCK] :: PlatformConstants -> Int
- GHC.Platform: [pc_BLOCK_SIZE] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_BLOCK_SIZE] :: PlatformConstants -> Int
- GHC.Platform: [pc_CINT_SIZE] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_CINT_SIZE] :: PlatformConstants -> Int
- GHC.Platform: [pc_CLONG_LONG_SIZE] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_CLONG_LONG_SIZE] :: PlatformConstants -> Int
- GHC.Platform: [pc_CLONG_SIZE] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_CLONG_SIZE] :: PlatformConstants -> Int
- GHC.Platform: [pc_CONTROL_GROUP_CONST_291] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_CONTROL_GROUP_CONST_291] :: PlatformConstants -> Int
- GHC.Platform: [pc_ILDV_CREATE_MASK] :: PlatformConstants -> !Integer
+ GHC.Platform: [pc_ILDV_CREATE_MASK] :: PlatformConstants -> Integer
- GHC.Platform: [pc_ILDV_STATE_CREATE] :: PlatformConstants -> !Integer
+ GHC.Platform: [pc_ILDV_STATE_CREATE] :: PlatformConstants -> Integer
- GHC.Platform: [pc_ILDV_STATE_USE] :: PlatformConstants -> !Integer
+ GHC.Platform: [pc_ILDV_STATE_USE] :: PlatformConstants -> Integer
- GHC.Platform: [pc_LDV_SHIFT] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_LDV_SHIFT] :: PlatformConstants -> Int
- GHC.Platform: [pc_MAX_CHARLIKE] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_MAX_CHARLIKE] :: PlatformConstants -> Int
- GHC.Platform: [pc_MAX_Double_REG] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_MAX_Double_REG] :: PlatformConstants -> Int
- GHC.Platform: [pc_MAX_Float_REG] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_MAX_Float_REG] :: PlatformConstants -> Int
- GHC.Platform: [pc_MAX_INTLIKE] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_MAX_INTLIKE] :: PlatformConstants -> Int
- GHC.Platform: [pc_MAX_Long_REG] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_MAX_Long_REG] :: PlatformConstants -> Int
- GHC.Platform: [pc_MAX_Real_Double_REG] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_MAX_Real_Double_REG] :: PlatformConstants -> Int
- GHC.Platform: [pc_MAX_Real_Float_REG] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_MAX_Real_Float_REG] :: PlatformConstants -> Int
- GHC.Platform: [pc_MAX_Real_Long_REG] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_MAX_Real_Long_REG] :: PlatformConstants -> Int
- GHC.Platform: [pc_MAX_Real_Vanilla_REG] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_MAX_Real_Vanilla_REG] :: PlatformConstants -> Int
- GHC.Platform: [pc_MAX_Real_XMM_REG] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_MAX_Real_XMM_REG] :: PlatformConstants -> Int
- GHC.Platform: [pc_MAX_SPEC_AP_SIZE] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_MAX_SPEC_AP_SIZE] :: PlatformConstants -> Int
- GHC.Platform: [pc_MAX_SPEC_SELECTEE_SIZE] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_MAX_SPEC_SELECTEE_SIZE] :: PlatformConstants -> Int
- GHC.Platform: [pc_MAX_Vanilla_REG] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_MAX_Vanilla_REG] :: PlatformConstants -> Int
- GHC.Platform: [pc_MAX_XMM_REG] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_MAX_XMM_REG] :: PlatformConstants -> Int
- GHC.Platform: [pc_MIN_CHARLIKE] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_MIN_CHARLIKE] :: PlatformConstants -> Int
- GHC.Platform: [pc_MIN_INTLIKE] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_MIN_INTLIKE] :: PlatformConstants -> Int
- GHC.Platform: [pc_MIN_PAYLOAD_SIZE] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_MIN_PAYLOAD_SIZE] :: PlatformConstants -> Int
- GHC.Platform: [pc_MUT_ARR_PTRS_CARD_BITS] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_MUT_ARR_PTRS_CARD_BITS] :: PlatformConstants -> Int
- GHC.Platform: [pc_OFFSET_Capability_r] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_OFFSET_Capability_r] :: PlatformConstants -> Int
- GHC.Platform: [pc_OFFSET_CostCentreStack_mem_alloc] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_OFFSET_CostCentreStack_mem_alloc] :: PlatformConstants -> Int
- GHC.Platform: [pc_OFFSET_CostCentreStack_scc_count] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_OFFSET_CostCentreStack_scc_count] :: PlatformConstants -> Int
- GHC.Platform: [pc_OFFSET_StgArrBytes_bytes] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_OFFSET_StgArrBytes_bytes] :: PlatformConstants -> Int
- GHC.Platform: [pc_OFFSET_StgEntCounter_allocd] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_OFFSET_StgEntCounter_allocd] :: PlatformConstants -> Int
- GHC.Platform: [pc_OFFSET_StgEntCounter_allocs] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_OFFSET_StgEntCounter_allocs] :: PlatformConstants -> Int
- GHC.Platform: [pc_OFFSET_StgEntCounter_entry_count] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_OFFSET_StgEntCounter_entry_count] :: PlatformConstants -> Int
- GHC.Platform: [pc_OFFSET_StgEntCounter_link] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_OFFSET_StgEntCounter_link] :: PlatformConstants -> Int
- GHC.Platform: [pc_OFFSET_StgEntCounter_registeredp] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_OFFSET_StgEntCounter_registeredp] :: PlatformConstants -> Int
- GHC.Platform: [pc_OFFSET_StgFunInfoExtraFwd_arity] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_OFFSET_StgFunInfoExtraFwd_arity] :: PlatformConstants -> Int
- GHC.Platform: [pc_OFFSET_StgFunInfoExtraRev_arity] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_OFFSET_StgFunInfoExtraRev_arity] :: PlatformConstants -> Int
- GHC.Platform: [pc_OFFSET_StgHeader_ccs] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_OFFSET_StgHeader_ccs] :: PlatformConstants -> Int
- GHC.Platform: [pc_OFFSET_StgHeader_ldvw] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_OFFSET_StgHeader_ldvw] :: PlatformConstants -> Int
- GHC.Platform: [pc_OFFSET_StgMutArrPtrs_ptrs] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_OFFSET_StgMutArrPtrs_ptrs] :: PlatformConstants -> Int
- GHC.Platform: [pc_OFFSET_StgMutArrPtrs_size] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_OFFSET_StgMutArrPtrs_size] :: PlatformConstants -> Int
- GHC.Platform: [pc_OFFSET_StgOrigThunkInfoFrame_info_ptr] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_OFFSET_StgOrigThunkInfoFrame_info_ptr] :: PlatformConstants -> Int
- GHC.Platform: [pc_OFFSET_StgRegTable_rCCCS] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_OFFSET_StgRegTable_rCCCS] :: PlatformConstants -> Int
- GHC.Platform: [pc_OFFSET_StgRegTable_rCurrentNursery] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_OFFSET_StgRegTable_rCurrentNursery] :: PlatformConstants -> Int
- GHC.Platform: [pc_OFFSET_StgRegTable_rCurrentTSO] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_OFFSET_StgRegTable_rCurrentTSO] :: PlatformConstants -> Int
- GHC.Platform: [pc_OFFSET_StgRegTable_rD1] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_OFFSET_StgRegTable_rD1] :: PlatformConstants -> Int
- GHC.Platform: [pc_OFFSET_StgRegTable_rD2] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_OFFSET_StgRegTable_rD2] :: PlatformConstants -> Int
- GHC.Platform: [pc_OFFSET_StgRegTable_rD3] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_OFFSET_StgRegTable_rD3] :: PlatformConstants -> Int
- GHC.Platform: [pc_OFFSET_StgRegTable_rD4] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_OFFSET_StgRegTable_rD4] :: PlatformConstants -> Int
- GHC.Platform: [pc_OFFSET_StgRegTable_rD5] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_OFFSET_StgRegTable_rD5] :: PlatformConstants -> Int
- GHC.Platform: [pc_OFFSET_StgRegTable_rD6] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_OFFSET_StgRegTable_rD6] :: PlatformConstants -> Int
- GHC.Platform: [pc_OFFSET_StgRegTable_rF1] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_OFFSET_StgRegTable_rF1] :: PlatformConstants -> Int
- GHC.Platform: [pc_OFFSET_StgRegTable_rF2] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_OFFSET_StgRegTable_rF2] :: PlatformConstants -> Int
- GHC.Platform: [pc_OFFSET_StgRegTable_rF3] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_OFFSET_StgRegTable_rF3] :: PlatformConstants -> Int
- GHC.Platform: [pc_OFFSET_StgRegTable_rF4] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_OFFSET_StgRegTable_rF4] :: PlatformConstants -> Int
- GHC.Platform: [pc_OFFSET_StgRegTable_rF5] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_OFFSET_StgRegTable_rF5] :: PlatformConstants -> Int
- GHC.Platform: [pc_OFFSET_StgRegTable_rF6] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_OFFSET_StgRegTable_rF6] :: PlatformConstants -> Int
- GHC.Platform: [pc_OFFSET_StgRegTable_rHpAlloc] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_OFFSET_StgRegTable_rHpAlloc] :: PlatformConstants -> Int
- GHC.Platform: [pc_OFFSET_StgRegTable_rHpLim] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_OFFSET_StgRegTable_rHpLim] :: PlatformConstants -> Int
- GHC.Platform: [pc_OFFSET_StgRegTable_rHp] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_OFFSET_StgRegTable_rHp] :: PlatformConstants -> Int
- GHC.Platform: [pc_OFFSET_StgRegTable_rL1] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_OFFSET_StgRegTable_rL1] :: PlatformConstants -> Int
- GHC.Platform: [pc_OFFSET_StgRegTable_rR10] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_OFFSET_StgRegTable_rR10] :: PlatformConstants -> Int
- GHC.Platform: [pc_OFFSET_StgRegTable_rR1] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_OFFSET_StgRegTable_rR1] :: PlatformConstants -> Int
- GHC.Platform: [pc_OFFSET_StgRegTable_rR2] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_OFFSET_StgRegTable_rR2] :: PlatformConstants -> Int
- GHC.Platform: [pc_OFFSET_StgRegTable_rR3] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_OFFSET_StgRegTable_rR3] :: PlatformConstants -> Int
- GHC.Platform: [pc_OFFSET_StgRegTable_rR4] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_OFFSET_StgRegTable_rR4] :: PlatformConstants -> Int
- GHC.Platform: [pc_OFFSET_StgRegTable_rR5] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_OFFSET_StgRegTable_rR5] :: PlatformConstants -> Int
- GHC.Platform: [pc_OFFSET_StgRegTable_rR6] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_OFFSET_StgRegTable_rR6] :: PlatformConstants -> Int
- GHC.Platform: [pc_OFFSET_StgRegTable_rR7] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_OFFSET_StgRegTable_rR7] :: PlatformConstants -> Int
- GHC.Platform: [pc_OFFSET_StgRegTable_rR8] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_OFFSET_StgRegTable_rR8] :: PlatformConstants -> Int
- GHC.Platform: [pc_OFFSET_StgRegTable_rR9] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_OFFSET_StgRegTable_rR9] :: PlatformConstants -> Int
- GHC.Platform: [pc_OFFSET_StgRegTable_rSpLim] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_OFFSET_StgRegTable_rSpLim] :: PlatformConstants -> Int
- GHC.Platform: [pc_OFFSET_StgRegTable_rSp] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_OFFSET_StgRegTable_rSp] :: PlatformConstants -> Int
- GHC.Platform: [pc_OFFSET_StgRegTable_rXMM1] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_OFFSET_StgRegTable_rXMM1] :: PlatformConstants -> Int
- GHC.Platform: [pc_OFFSET_StgRegTable_rXMM2] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_OFFSET_StgRegTable_rXMM2] :: PlatformConstants -> Int
- GHC.Platform: [pc_OFFSET_StgRegTable_rXMM3] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_OFFSET_StgRegTable_rXMM3] :: PlatformConstants -> Int
- GHC.Platform: [pc_OFFSET_StgRegTable_rXMM4] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_OFFSET_StgRegTable_rXMM4] :: PlatformConstants -> Int
- GHC.Platform: [pc_OFFSET_StgRegTable_rXMM5] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_OFFSET_StgRegTable_rXMM5] :: PlatformConstants -> Int
- GHC.Platform: [pc_OFFSET_StgRegTable_rXMM6] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_OFFSET_StgRegTable_rXMM6] :: PlatformConstants -> Int
- GHC.Platform: [pc_OFFSET_StgRegTable_rYMM1] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_OFFSET_StgRegTable_rYMM1] :: PlatformConstants -> Int
- GHC.Platform: [pc_OFFSET_StgRegTable_rYMM2] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_OFFSET_StgRegTable_rYMM2] :: PlatformConstants -> Int
- GHC.Platform: [pc_OFFSET_StgRegTable_rYMM3] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_OFFSET_StgRegTable_rYMM3] :: PlatformConstants -> Int
- GHC.Platform: [pc_OFFSET_StgRegTable_rYMM4] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_OFFSET_StgRegTable_rYMM4] :: PlatformConstants -> Int
- GHC.Platform: [pc_OFFSET_StgRegTable_rYMM5] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_OFFSET_StgRegTable_rYMM5] :: PlatformConstants -> Int
- GHC.Platform: [pc_OFFSET_StgRegTable_rYMM6] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_OFFSET_StgRegTable_rYMM6] :: PlatformConstants -> Int
- GHC.Platform: [pc_OFFSET_StgRegTable_rZMM1] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_OFFSET_StgRegTable_rZMM1] :: PlatformConstants -> Int
- GHC.Platform: [pc_OFFSET_StgRegTable_rZMM2] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_OFFSET_StgRegTable_rZMM2] :: PlatformConstants -> Int
- GHC.Platform: [pc_OFFSET_StgRegTable_rZMM3] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_OFFSET_StgRegTable_rZMM3] :: PlatformConstants -> Int
- GHC.Platform: [pc_OFFSET_StgRegTable_rZMM4] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_OFFSET_StgRegTable_rZMM4] :: PlatformConstants -> Int
- GHC.Platform: [pc_OFFSET_StgRegTable_rZMM5] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_OFFSET_StgRegTable_rZMM5] :: PlatformConstants -> Int
- GHC.Platform: [pc_OFFSET_StgRegTable_rZMM6] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_OFFSET_StgRegTable_rZMM6] :: PlatformConstants -> Int
- GHC.Platform: [pc_OFFSET_StgSmallMutArrPtrs_ptrs] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_OFFSET_StgSmallMutArrPtrs_ptrs] :: PlatformConstants -> Int
- GHC.Platform: [pc_OFFSET_StgStack_sp] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_OFFSET_StgStack_sp] :: PlatformConstants -> Int
- GHC.Platform: [pc_OFFSET_StgStack_stack] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_OFFSET_StgStack_stack] :: PlatformConstants -> Int
- GHC.Platform: [pc_OFFSET_StgTSO_alloc_limit] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_OFFSET_StgTSO_alloc_limit] :: PlatformConstants -> Int
- GHC.Platform: [pc_OFFSET_StgTSO_cccs] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_OFFSET_StgTSO_cccs] :: PlatformConstants -> Int
- GHC.Platform: [pc_OFFSET_StgTSO_stackobj] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_OFFSET_StgTSO_stackobj] :: PlatformConstants -> Int
- GHC.Platform: [pc_OFFSET_StgUpdateFrame_updatee] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_OFFSET_StgUpdateFrame_updatee] :: PlatformConstants -> Int
- GHC.Platform: [pc_OFFSET_bdescr_blocks] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_OFFSET_bdescr_blocks] :: PlatformConstants -> Int
- GHC.Platform: [pc_OFFSET_bdescr_flags] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_OFFSET_bdescr_flags] :: PlatformConstants -> Int
- GHC.Platform: [pc_OFFSET_bdescr_free] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_OFFSET_bdescr_free] :: PlatformConstants -> Int
- GHC.Platform: [pc_OFFSET_bdescr_start] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_OFFSET_bdescr_start] :: PlatformConstants -> Int
- GHC.Platform: [pc_OFFSET_stgEagerBlackholeInfo] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_OFFSET_stgEagerBlackholeInfo] :: PlatformConstants -> Int
- GHC.Platform: [pc_OFFSET_stgGCEnter1] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_OFFSET_stgGCEnter1] :: PlatformConstants -> Int
- GHC.Platform: [pc_OFFSET_stgGCFun] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_OFFSET_stgGCFun] :: PlatformConstants -> Int
- GHC.Platform: [pc_PROF_HDR_SIZE] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_PROF_HDR_SIZE] :: PlatformConstants -> Int
- GHC.Platform: [pc_REP_CostCentreStack_mem_alloc] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_REP_CostCentreStack_mem_alloc] :: PlatformConstants -> Int
- GHC.Platform: [pc_REP_CostCentreStack_scc_count] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_REP_CostCentreStack_scc_count] :: PlatformConstants -> Int
- GHC.Platform: [pc_REP_StgEntCounter_allocd] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_REP_StgEntCounter_allocd] :: PlatformConstants -> Int
- GHC.Platform: [pc_REP_StgEntCounter_allocs] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_REP_StgEntCounter_allocs] :: PlatformConstants -> Int
- GHC.Platform: [pc_REP_StgFunInfoExtraFwd_arity] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_REP_StgFunInfoExtraFwd_arity] :: PlatformConstants -> Int
- GHC.Platform: [pc_REP_StgFunInfoExtraRev_arity] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_REP_StgFunInfoExtraRev_arity] :: PlatformConstants -> Int
- GHC.Platform: [pc_RESERVED_C_STACK_BYTES] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_RESERVED_C_STACK_BYTES] :: PlatformConstants -> Int
- GHC.Platform: [pc_RESERVED_STACK_WORDS] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_RESERVED_STACK_WORDS] :: PlatformConstants -> Int
- GHC.Platform: [pc_SIZEOF_CostCentreStack] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_SIZEOF_CostCentreStack] :: PlatformConstants -> Int
- GHC.Platform: [pc_SIZEOF_StgArrBytes_NoHdr] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_SIZEOF_StgArrBytes_NoHdr] :: PlatformConstants -> Int
- GHC.Platform: [pc_SIZEOF_StgFunInfoExtraRev] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_SIZEOF_StgFunInfoExtraRev] :: PlatformConstants -> Int
- GHC.Platform: [pc_SIZEOF_StgMutArrPtrs_NoHdr] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_SIZEOF_StgMutArrPtrs_NoHdr] :: PlatformConstants -> Int
- GHC.Platform: [pc_SIZEOF_StgOrigThunkInfoFrame_NoHdr] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_SIZEOF_StgOrigThunkInfoFrame_NoHdr] :: PlatformConstants -> Int
- GHC.Platform: [pc_SIZEOF_StgSMPThunkHeader] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_SIZEOF_StgSMPThunkHeader] :: PlatformConstants -> Int
- GHC.Platform: [pc_SIZEOF_StgSmallMutArrPtrs_NoHdr] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_SIZEOF_StgSmallMutArrPtrs_NoHdr] :: PlatformConstants -> Int
- GHC.Platform: [pc_SIZEOF_StgUpdateFrame_NoHdr] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_SIZEOF_StgUpdateFrame_NoHdr] :: PlatformConstants -> Int
- GHC.Platform: [pc_STD_HDR_SIZE] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_STD_HDR_SIZE] :: PlatformConstants -> Int
- GHC.Platform: [pc_TAG_BITS] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_TAG_BITS] :: PlatformConstants -> Int
- GHC.Platform: [pc_TICKY_BIN_COUNT] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_TICKY_BIN_COUNT] :: PlatformConstants -> Int
- GHC.Platform: [pc_USE_INLINE_SRT_FIELD] :: PlatformConstants -> !Bool
+ GHC.Platform: [pc_USE_INLINE_SRT_FIELD] :: PlatformConstants -> Bool
- GHC.Platform: [pc_WORD_SIZE] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform: [pc_WORD_SIZE] :: PlatformConstants -> Int
- GHC.Platform: [platformArchOS] :: Platform -> !ArchOS
+ GHC.Platform: [platformArchOS] :: Platform -> ArchOS
- GHC.Platform: [platformByteOrder] :: Platform -> !ByteOrder
+ GHC.Platform: [platformByteOrder] :: Platform -> ByteOrder
- GHC.Platform: [platformHasGnuNonexecStack] :: Platform -> !Bool
+ GHC.Platform: [platformHasGnuNonexecStack] :: Platform -> Bool
- GHC.Platform: [platformHasIdentDirective] :: Platform -> !Bool
+ GHC.Platform: [platformHasIdentDirective] :: Platform -> Bool
- GHC.Platform: [platformHasLibm] :: Platform -> !Bool
+ GHC.Platform: [platformHasLibm] :: Platform -> Bool
- GHC.Platform: [platformHasSubsectionsViaSymbols] :: Platform -> !Bool
+ GHC.Platform: [platformHasSubsectionsViaSymbols] :: Platform -> Bool
- GHC.Platform: [platformIsCrossCompiling] :: Platform -> !Bool
+ GHC.Platform: [platformIsCrossCompiling] :: Platform -> Bool
- GHC.Platform: [platformLeadingUnderscore] :: Platform -> !Bool
+ GHC.Platform: [platformLeadingUnderscore] :: Platform -> Bool
- GHC.Platform: [platformTablesNextToCode] :: Platform -> !Bool
+ GHC.Platform: [platformTablesNextToCode] :: Platform -> Bool
- GHC.Platform: [platformUnregisterised] :: Platform -> !Bool
+ GHC.Platform: [platformUnregisterised] :: Platform -> Bool
- GHC.Platform: [platformWordSize] :: Platform -> !PlatformWordSize
+ GHC.Platform: [platformWordSize] :: Platform -> PlatformWordSize
- GHC.Platform: [platform_constants] :: Platform -> !Maybe PlatformConstants
+ GHC.Platform: [platform_constants] :: Platform -> Maybe PlatformConstants
- GHC.Platform.Constants: PlatformConstants :: {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> !Integer -> !Integer -> !Integer -> !Bool -> PlatformConstants
+ GHC.Platform.Constants: PlatformConstants :: Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Integer -> Integer -> Integer -> Bool -> PlatformConstants
- GHC.Platform.Constants: [pc_AP_STACK_SPLIM] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_AP_STACK_SPLIM] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_BITMAP_BITS_SHIFT] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_BITMAP_BITS_SHIFT] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_BLOCKS_PER_MBLOCK] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_BLOCKS_PER_MBLOCK] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_BLOCK_SIZE] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_BLOCK_SIZE] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_CINT_SIZE] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_CINT_SIZE] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_CLONG_LONG_SIZE] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_CLONG_LONG_SIZE] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_CLONG_SIZE] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_CLONG_SIZE] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_CONTROL_GROUP_CONST_291] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_CONTROL_GROUP_CONST_291] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_ILDV_CREATE_MASK] :: PlatformConstants -> !Integer
+ GHC.Platform.Constants: [pc_ILDV_CREATE_MASK] :: PlatformConstants -> Integer
- GHC.Platform.Constants: [pc_ILDV_STATE_CREATE] :: PlatformConstants -> !Integer
+ GHC.Platform.Constants: [pc_ILDV_STATE_CREATE] :: PlatformConstants -> Integer
- GHC.Platform.Constants: [pc_ILDV_STATE_USE] :: PlatformConstants -> !Integer
+ GHC.Platform.Constants: [pc_ILDV_STATE_USE] :: PlatformConstants -> Integer
- GHC.Platform.Constants: [pc_LDV_SHIFT] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_LDV_SHIFT] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_MAX_CHARLIKE] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_MAX_CHARLIKE] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_MAX_Double_REG] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_MAX_Double_REG] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_MAX_Float_REG] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_MAX_Float_REG] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_MAX_INTLIKE] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_MAX_INTLIKE] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_MAX_Long_REG] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_MAX_Long_REG] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_MAX_Real_Double_REG] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_MAX_Real_Double_REG] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_MAX_Real_Float_REG] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_MAX_Real_Float_REG] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_MAX_Real_Long_REG] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_MAX_Real_Long_REG] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_MAX_Real_Vanilla_REG] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_MAX_Real_Vanilla_REG] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_MAX_Real_XMM_REG] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_MAX_Real_XMM_REG] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_MAX_SPEC_AP_SIZE] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_MAX_SPEC_AP_SIZE] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_MAX_SPEC_SELECTEE_SIZE] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_MAX_SPEC_SELECTEE_SIZE] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_MAX_Vanilla_REG] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_MAX_Vanilla_REG] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_MAX_XMM_REG] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_MAX_XMM_REG] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_MIN_CHARLIKE] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_MIN_CHARLIKE] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_MIN_INTLIKE] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_MIN_INTLIKE] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_MIN_PAYLOAD_SIZE] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_MIN_PAYLOAD_SIZE] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_MUT_ARR_PTRS_CARD_BITS] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_MUT_ARR_PTRS_CARD_BITS] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_OFFSET_Capability_r] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_OFFSET_Capability_r] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_OFFSET_CostCentreStack_mem_alloc] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_OFFSET_CostCentreStack_mem_alloc] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_OFFSET_CostCentreStack_scc_count] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_OFFSET_CostCentreStack_scc_count] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_OFFSET_StgArrBytes_bytes] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_OFFSET_StgArrBytes_bytes] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_OFFSET_StgEntCounter_allocd] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_OFFSET_StgEntCounter_allocd] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_OFFSET_StgEntCounter_allocs] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_OFFSET_StgEntCounter_allocs] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_OFFSET_StgEntCounter_entry_count] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_OFFSET_StgEntCounter_entry_count] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_OFFSET_StgEntCounter_link] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_OFFSET_StgEntCounter_link] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_OFFSET_StgEntCounter_registeredp] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_OFFSET_StgEntCounter_registeredp] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_OFFSET_StgFunInfoExtraFwd_arity] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_OFFSET_StgFunInfoExtraFwd_arity] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_OFFSET_StgFunInfoExtraRev_arity] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_OFFSET_StgFunInfoExtraRev_arity] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_OFFSET_StgHeader_ccs] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_OFFSET_StgHeader_ccs] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_OFFSET_StgHeader_ldvw] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_OFFSET_StgHeader_ldvw] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_OFFSET_StgMutArrPtrs_ptrs] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_OFFSET_StgMutArrPtrs_ptrs] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_OFFSET_StgMutArrPtrs_size] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_OFFSET_StgMutArrPtrs_size] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_OFFSET_StgOrigThunkInfoFrame_info_ptr] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_OFFSET_StgOrigThunkInfoFrame_info_ptr] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_OFFSET_StgRegTable_rCCCS] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_OFFSET_StgRegTable_rCCCS] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_OFFSET_StgRegTable_rCurrentNursery] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_OFFSET_StgRegTable_rCurrentNursery] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_OFFSET_StgRegTable_rCurrentTSO] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_OFFSET_StgRegTable_rCurrentTSO] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_OFFSET_StgRegTable_rD1] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_OFFSET_StgRegTable_rD1] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_OFFSET_StgRegTable_rD2] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_OFFSET_StgRegTable_rD2] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_OFFSET_StgRegTable_rD3] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_OFFSET_StgRegTable_rD3] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_OFFSET_StgRegTable_rD4] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_OFFSET_StgRegTable_rD4] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_OFFSET_StgRegTable_rD5] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_OFFSET_StgRegTable_rD5] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_OFFSET_StgRegTable_rD6] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_OFFSET_StgRegTable_rD6] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_OFFSET_StgRegTable_rF1] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_OFFSET_StgRegTable_rF1] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_OFFSET_StgRegTable_rF2] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_OFFSET_StgRegTable_rF2] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_OFFSET_StgRegTable_rF3] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_OFFSET_StgRegTable_rF3] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_OFFSET_StgRegTable_rF4] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_OFFSET_StgRegTable_rF4] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_OFFSET_StgRegTable_rF5] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_OFFSET_StgRegTable_rF5] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_OFFSET_StgRegTable_rF6] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_OFFSET_StgRegTable_rF6] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_OFFSET_StgRegTable_rHpAlloc] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_OFFSET_StgRegTable_rHpAlloc] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_OFFSET_StgRegTable_rHpLim] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_OFFSET_StgRegTable_rHpLim] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_OFFSET_StgRegTable_rHp] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_OFFSET_StgRegTable_rHp] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_OFFSET_StgRegTable_rL1] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_OFFSET_StgRegTable_rL1] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_OFFSET_StgRegTable_rR10] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_OFFSET_StgRegTable_rR10] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_OFFSET_StgRegTable_rR1] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_OFFSET_StgRegTable_rR1] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_OFFSET_StgRegTable_rR2] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_OFFSET_StgRegTable_rR2] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_OFFSET_StgRegTable_rR3] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_OFFSET_StgRegTable_rR3] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_OFFSET_StgRegTable_rR4] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_OFFSET_StgRegTable_rR4] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_OFFSET_StgRegTable_rR5] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_OFFSET_StgRegTable_rR5] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_OFFSET_StgRegTable_rR6] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_OFFSET_StgRegTable_rR6] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_OFFSET_StgRegTable_rR7] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_OFFSET_StgRegTable_rR7] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_OFFSET_StgRegTable_rR8] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_OFFSET_StgRegTable_rR8] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_OFFSET_StgRegTable_rR9] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_OFFSET_StgRegTable_rR9] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_OFFSET_StgRegTable_rSpLim] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_OFFSET_StgRegTable_rSpLim] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_OFFSET_StgRegTable_rSp] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_OFFSET_StgRegTable_rSp] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_OFFSET_StgRegTable_rXMM1] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_OFFSET_StgRegTable_rXMM1] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_OFFSET_StgRegTable_rXMM2] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_OFFSET_StgRegTable_rXMM2] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_OFFSET_StgRegTable_rXMM3] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_OFFSET_StgRegTable_rXMM3] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_OFFSET_StgRegTable_rXMM4] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_OFFSET_StgRegTable_rXMM4] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_OFFSET_StgRegTable_rXMM5] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_OFFSET_StgRegTable_rXMM5] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_OFFSET_StgRegTable_rXMM6] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_OFFSET_StgRegTable_rXMM6] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_OFFSET_StgRegTable_rYMM1] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_OFFSET_StgRegTable_rYMM1] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_OFFSET_StgRegTable_rYMM2] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_OFFSET_StgRegTable_rYMM2] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_OFFSET_StgRegTable_rYMM3] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_OFFSET_StgRegTable_rYMM3] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_OFFSET_StgRegTable_rYMM4] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_OFFSET_StgRegTable_rYMM4] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_OFFSET_StgRegTable_rYMM5] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_OFFSET_StgRegTable_rYMM5] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_OFFSET_StgRegTable_rYMM6] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_OFFSET_StgRegTable_rYMM6] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_OFFSET_StgRegTable_rZMM1] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_OFFSET_StgRegTable_rZMM1] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_OFFSET_StgRegTable_rZMM2] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_OFFSET_StgRegTable_rZMM2] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_OFFSET_StgRegTable_rZMM3] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_OFFSET_StgRegTable_rZMM3] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_OFFSET_StgRegTable_rZMM4] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_OFFSET_StgRegTable_rZMM4] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_OFFSET_StgRegTable_rZMM5] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_OFFSET_StgRegTable_rZMM5] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_OFFSET_StgRegTable_rZMM6] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_OFFSET_StgRegTable_rZMM6] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_OFFSET_StgSmallMutArrPtrs_ptrs] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_OFFSET_StgSmallMutArrPtrs_ptrs] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_OFFSET_StgStack_sp] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_OFFSET_StgStack_sp] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_OFFSET_StgStack_stack] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_OFFSET_StgStack_stack] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_OFFSET_StgTSO_alloc_limit] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_OFFSET_StgTSO_alloc_limit] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_OFFSET_StgTSO_cccs] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_OFFSET_StgTSO_cccs] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_OFFSET_StgTSO_stackobj] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_OFFSET_StgTSO_stackobj] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_OFFSET_StgUpdateFrame_updatee] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_OFFSET_StgUpdateFrame_updatee] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_OFFSET_bdescr_blocks] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_OFFSET_bdescr_blocks] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_OFFSET_bdescr_flags] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_OFFSET_bdescr_flags] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_OFFSET_bdescr_free] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_OFFSET_bdescr_free] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_OFFSET_bdescr_start] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_OFFSET_bdescr_start] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_OFFSET_stgEagerBlackholeInfo] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_OFFSET_stgEagerBlackholeInfo] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_OFFSET_stgGCEnter1] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_OFFSET_stgGCEnter1] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_OFFSET_stgGCFun] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_OFFSET_stgGCFun] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_PROF_HDR_SIZE] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_PROF_HDR_SIZE] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_REP_CostCentreStack_mem_alloc] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_REP_CostCentreStack_mem_alloc] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_REP_CostCentreStack_scc_count] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_REP_CostCentreStack_scc_count] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_REP_StgEntCounter_allocd] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_REP_StgEntCounter_allocd] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_REP_StgEntCounter_allocs] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_REP_StgEntCounter_allocs] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_REP_StgFunInfoExtraFwd_arity] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_REP_StgFunInfoExtraFwd_arity] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_REP_StgFunInfoExtraRev_arity] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_REP_StgFunInfoExtraRev_arity] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_RESERVED_C_STACK_BYTES] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_RESERVED_C_STACK_BYTES] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_RESERVED_STACK_WORDS] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_RESERVED_STACK_WORDS] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_SIZEOF_CostCentreStack] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_SIZEOF_CostCentreStack] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_SIZEOF_StgArrBytes_NoHdr] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_SIZEOF_StgArrBytes_NoHdr] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_SIZEOF_StgFunInfoExtraRev] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_SIZEOF_StgFunInfoExtraRev] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_SIZEOF_StgMutArrPtrs_NoHdr] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_SIZEOF_StgMutArrPtrs_NoHdr] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_SIZEOF_StgOrigThunkInfoFrame_NoHdr] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_SIZEOF_StgOrigThunkInfoFrame_NoHdr] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_SIZEOF_StgSMPThunkHeader] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_SIZEOF_StgSMPThunkHeader] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_SIZEOF_StgSmallMutArrPtrs_NoHdr] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_SIZEOF_StgSmallMutArrPtrs_NoHdr] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_SIZEOF_StgUpdateFrame_NoHdr] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_SIZEOF_StgUpdateFrame_NoHdr] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_STD_HDR_SIZE] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_STD_HDR_SIZE] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_TAG_BITS] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_TAG_BITS] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_TICKY_BIN_COUNT] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_TICKY_BIN_COUNT] :: PlatformConstants -> Int
- GHC.Platform.Constants: [pc_USE_INLINE_SRT_FIELD] :: PlatformConstants -> !Bool
+ GHC.Platform.Constants: [pc_USE_INLINE_SRT_FIELD] :: PlatformConstants -> Bool
- GHC.Platform.Constants: [pc_WORD_SIZE] :: PlatformConstants -> {-# UNPACK #-} !Int
+ GHC.Platform.Constants: [pc_WORD_SIZE] :: PlatformConstants -> Int
- GHC.Platform.Profile: Profile :: !Platform -> !Ways -> Profile
+ GHC.Platform.Profile: Profile :: Platform -> Ways -> Profile
- GHC.Platform.Profile: [profilePlatform] :: Profile -> !Platform
+ GHC.Platform.Profile: [profilePlatform] :: Profile -> Platform
- GHC.Platform.Profile: [profileWays] :: Profile -> !Ways
+ GHC.Platform.Profile: [profileWays] :: Profile -> Ways
- GHC.Platform.Reg: RegReal :: !RealReg -> Reg
+ GHC.Platform.Reg: RegReal :: RealReg -> Reg
- GHC.Platform.Reg: RegVirtual :: !VirtualReg -> Reg
+ GHC.Platform.Reg: RegVirtual :: VirtualReg -> Reg
- GHC.Platform.Reg: VirtualRegD :: {-# UNPACK #-} !Unique -> VirtualReg
+ GHC.Platform.Reg: VirtualRegD :: Unique -> VirtualReg
- GHC.Platform.Reg: VirtualRegHi :: {-# UNPACK #-} !Unique -> VirtualReg
+ GHC.Platform.Reg: VirtualRegHi :: Unique -> VirtualReg
- GHC.Platform.Reg: VirtualRegI :: {-# UNPACK #-} !Unique -> VirtualReg
+ GHC.Platform.Reg: VirtualRegI :: Unique -> VirtualReg
- GHC.Platform.Reg: VirtualRegV128 :: {-# UNPACK #-} !Unique -> VirtualReg
+ GHC.Platform.Reg: VirtualRegV128 :: Unique -> VirtualReg
- GHC.Platform.Reg: [virtualRegUnique] :: VirtualReg -> {-# UNPACK #-} !Unique
+ GHC.Platform.Reg: [virtualRegUnique] :: VirtualReg -> Unique
- GHC.Plugins: CoercionHole :: CoVar -> IORef (Maybe Coercion) -> Bool -> CoercionHole
+ GHC.Plugins: CoercionHole :: CoVar -> IORef (Maybe Coercion) -> CoercionHole
- GHC.Plugins: Invisible :: !Specificity -> ForAllTyFlag
+ GHC.Plugins: Invisible :: Specificity -> ForAllTyFlag
- GHC.Plugins: cloneBndrs :: MonadUnique m => Subst -> [Var] -> m (Subst, [Var])
+ GHC.Plugins: cloneBndrs :: Subst -> UniqSupply -> [Var] -> (Subst, [Var])
- GHC.Plugins: cloneRecIdBndrs :: MonadUnique m => Subst -> [Id] -> m (Subst, [Id])
+ GHC.Plugins: cloneRecIdBndrs :: Subst -> UniqSupply -> [Id] -> (Subst, [Id])
- GHC.Plugins: extendSubst :: Subst -> Var -> CoreArg -> Subst
+ GHC.Plugins: extendSubst :: HasDebugCallStack => Subst -> Var -> CoreArg -> Subst
- GHC.Plugins: idDetails :: Id -> IdDetails
+ GHC.Plugins: idDetails :: HasCallStack => Id -> IdDetails
- GHC.Plugins: idMult :: Id -> Mult
+ GHC.Plugins: idMult :: HasDebugCallStack => Id -> Mult
- GHC.Plugins: liftCoSubstWithEx :: Role -> [TyVar] -> [Coercion] -> [TyCoVar] -> [Type] -> (Type -> Coercion, [Type])
+ GHC.Plugins: liftCoSubstWithEx :: [TyVar] -> [Coercion] -> [TyCoVar] -> [Type] -> (Type -> CoercionR, [Type])
- GHC.Plugins: pprModulePrefix :: PprStyle -> Module -> OccName -> SDoc
+ GHC.Plugins: pprModulePrefix :: PprStyle -> Module -> Maybe ModuleName -> OccName -> SDoc
- GHC.Plugins: pprPrefixName :: NamedThing a => a -> SDoc
+ GHC.Plugins: pprPrefixName :: (Outputable a, NamedThing a) => a -> SDoc
- GHC.Prelude.Basic: fail :: MonadFail m => String -> m a
+ GHC.Prelude.Basic: fail :: (MonadFail m, HasCallStack) => String -> m a
- GHC.Prelude.Basic: foldl1 :: Foldable t => (a -> a -> a) -> t a -> a
+ GHC.Prelude.Basic: foldl1 :: Foldable1 t => (a -> a -> a) -> t a -> a
- GHC.Prelude.Basic: foldr1 :: Foldable t => (a -> a -> a) -> t a -> a
+ GHC.Prelude.Basic: foldr1 :: Foldable1 t => (a -> a -> a) -> t a -> a
- GHC.Prelude.Basic: maximum :: (Foldable t, Ord a) => t a -> a
+ GHC.Prelude.Basic: maximum :: (Foldable1 t, Ord a) => t a -> a
- GHC.Prelude.Basic: minimum :: (Foldable t, Ord a) => t a -> a
+ GHC.Prelude.Basic: minimum :: (Foldable1 t, Ord a) => t a -> a
- GHC.Prelude.Basic: unzip :: [(a, b)] -> ([a], [b])
+ GHC.Prelude.Basic: unzip :: Functor f => f (a, b) -> (f a, f b)
- GHC.Rename.Bind: InstDeclCtxt :: NameSet -> HsSigCtxt
+ GHC.Rename.Bind: InstDeclCtxt :: OccEnv Name -> HsSigCtxt
- GHC.Rename.Env: IncorrectParent :: Name -> GlobalRdrElt -> [Name] -> ChildLookupResult
+ GHC.Rename.Env: IncorrectParent :: ParentGRE -> GlobalRdrElt -> [Name] -> ChildLookupResult
- GHC.Rename.Env: InstDeclCtxt :: NameSet -> HsSigCtxt
+ GHC.Rename.Env: InstDeclCtxt :: OccEnv Name -> HsSigCtxt
- GHC.Rename.Env: irrefutableConLikeRn :: HasDebugCallStack => HscEnv -> GlobalRdrEnv -> CompleteMatches -> Name -> Bool
+ GHC.Rename.Env: irrefutableConLikeRn :: HasDebugCallStack => HscEnv -> GlobalRdrEnv -> CompleteMatches -> WithUserRdr Name -> Bool
- GHC.Rename.Env: lookupConstructorFields :: HasDebugCallStack => Name -> RnM [FieldLabel]
+ GHC.Rename.Env: lookupConstructorFields :: HasDebugCallStack => WithUserRdr Name -> RnM [FieldLabel]
- GHC.Rename.Env: lookupConstructorInfo :: HasDebugCallStack => Name -> RnM ConInfo
+ GHC.Rename.Env: lookupConstructorInfo :: HasDebugCallStack => WithUserRdr Name -> RnM ConInfo
- GHC.Rename.Env: lookupGreAvailRn :: RdrName -> RnM (Maybe GlobalRdrElt)
+ GHC.Rename.Env: lookupGreAvailRn :: WhatLooking -> RdrName -> RnM (Maybe GlobalRdrElt)
- GHC.Rename.Env: lookupInstDeclBndr :: Name -> SDoc -> RdrName -> RnM Name
+ GHC.Rename.Env: lookupInstDeclBndr :: Name -> Subordinate -> RdrName -> RnM Name
- GHC.Rename.Env: lookupLocalOccThLvl_maybe :: Name -> RnM (Maybe (TopLevelFlag, ThLevel))
+ GHC.Rename.Env: lookupLocalOccThLvl_maybe :: Name -> RnM (Maybe (TopLevelFlag, ThLevelIndex))
- GHC.Rename.Env: lookupLocalTcNames :: HsSigCtxt -> SDoc -> NamespaceSpecifier -> RdrName -> RnM [(RdrName, Name)]
+ GHC.Rename.Env: lookupLocalTcNames :: HsSigCtxt -> SigLike -> NamespaceSpecifier -> RdrName -> RnM [(RdrName, Name)]
- GHC.Rename.Env: lookupLocatedOccRn :: GenLocated (EpAnn ann) RdrName -> TcRn (GenLocated (EpAnn ann) Name)
+ GHC.Rename.Env: lookupLocatedOccRn :: WhatLooking -> GenLocated (EpAnn ann) RdrName -> TcRn (GenLocated (EpAnn ann) Name)
- GHC.Rename.Env: lookupLocatedTopBndrRnN :: LocatedN RdrName -> RnM (LocatedN Name)
+ GHC.Rename.Env: lookupLocatedTopBndrRnN :: WhatLooking -> LocatedN RdrName -> RnM (LocatedN Name)
- GHC.Rename.Env: lookupOccRn :: RdrName -> RnM Name
+ GHC.Rename.Env: lookupOccRn :: WhatLooking -> RdrName -> RnM Name
- GHC.Rename.Env: lookupRecFieldOcc :: Maybe Name -> RdrName -> RnM Name
+ GHC.Rename.Env: lookupRecFieldOcc :: Maybe (WithUserRdr Name) -> RdrName -> RnM Name
- GHC.Rename.Env: lookupSigCtxtOccRn :: HsSigCtxt -> SDoc -> GenLocated (EpAnn ann) RdrName -> RnM (GenLocated (EpAnn ann) Name)
+ GHC.Rename.Env: lookupSigCtxtOccRn :: HsSigCtxt -> SigLike -> GenLocated (EpAnn ann) RdrName -> RnM (GenLocated (EpAnn ann) Name)
- GHC.Rename.Env: lookupSigOccRn :: HsSigCtxt -> Sig GhcPs -> LocatedA RdrName -> RnM (LocatedA Name)
+ GHC.Rename.Env: lookupSigOccRn :: HsSigCtxt -> Sig GhcPs -> GenLocated (EpAnn ann) RdrName -> RnM (GenLocated (EpAnn ann) Name)
- GHC.Rename.Env: lookupSubBndrOcc_helper :: Bool -> DeprecationWarnings -> Name -> RdrName -> LookupChild -> RnM ChildLookupResult
+ GHC.Rename.Env: lookupSubBndrOcc_helper :: Bool -> DeprecationWarnings -> ParentGRE -> RdrName -> RnM ChildLookupResult
- GHC.Rename.Env: lookupTopBndrRn :: WhatLooking -> RdrName -> RnM Name
+ GHC.Rename.Env: lookupTopBndrRn :: WhatLooking -> RdrName -> RnM (WithUserRdr Name)
- GHC.Rename.HsType: mkConOpPatRn :: LocatedN Name -> Fixity -> LPat GhcRn -> LPat GhcRn -> RnM (Pat GhcRn)
+ GHC.Rename.HsType: mkConOpPatRn :: LocatedN (WithUserRdr Name) -> Fixity -> LPat GhcRn -> LPat GhcRn -> RnM (Pat GhcRn)
- GHC.Rename.HsType: mkHsOpTyRn :: PromotionFlag -> LocatedN Name -> Fixity -> LHsType GhcRn -> LHsType GhcRn -> RnM (HsType GhcRn)
+ GHC.Rename.HsType: mkHsOpTyRn :: PromotionFlag -> LocatedN (WithUserRdr Name) -> Fixity -> LHsType GhcRn -> LHsType GhcRn -> RnM (HsType GhcRn)
- GHC.Rename.Names: ImpUserSpec :: !ImpDeclSpec -> !ImpUserList -> ImportUserSpec
+ GHC.Rename.Names: ImpUserSpec :: ImpDeclSpec -> ImpUserList -> ImportUserSpec
- GHC.Rename.Names: [ius_decl] :: ImportUserSpec -> !ImpDeclSpec
+ GHC.Rename.Names: [ius_decl] :: ImportUserSpec -> ImpDeclSpec
- GHC.Rename.Names: [ius_imports] :: ImportUserSpec -> !ImpUserList
+ GHC.Rename.Names: [ius_imports] :: ImportUserSpec -> ImpUserList
- GHC.Rename.Names: rnImports :: [(LImportDecl GhcPs, SDoc)] -> RnM ([LImportDecl GhcRn], [ImportUserSpec], GlobalRdrEnv, ImportAvails, AnyHpcUsage)
+ GHC.Rename.Names: rnImports :: [(LImportDecl GhcPs, SDoc)] -> RnM ([LImportDecl GhcRn], [ImportUserSpec], GlobalRdrEnv, ImportAvails)
- GHC.Rename.Pat: HsRecFieldCon :: Name -> HsRecFieldContext
+ GHC.Rename.Pat: HsRecFieldCon :: WithUserRdr Name -> HsRecFieldContext
- GHC.Rename.Pat: HsRecFieldPat :: Name -> HsRecFieldContext
+ GHC.Rename.Pat: HsRecFieldPat :: WithUserRdr Name -> HsRecFieldContext
- GHC.Rename.Splice: checkThLocalName :: Name -> RnM ()
+ GHC.Rename.Splice: checkThLocalName :: Bool -> LIdOccP GhcRn -> RnM (HsExpr GhcRn)
- GHC.Rename.Splice: rnTypedSplice :: LHsExpr GhcPs -> RnM (HsExpr GhcRn, FreeVars)
+ GHC.Rename.Splice: rnTypedSplice :: HsTypedSplice GhcPs -> RnM (HsExpr GhcRn, FreeVars)
- GHC.Rename.Unbound: reportUnboundName :: RdrName -> RnM Name
+ GHC.Rename.Unbound: reportUnboundName :: WhatLooking -> RdrName -> RnM Name
- GHC.Runtime.Context: IIModule :: ModuleName -> InteractiveImport
+ GHC.Runtime.Context: IIModule :: Module -> InteractiveImport
- GHC.Runtime.Context: InteractiveContext :: DynFlags -> Int -> [InteractiveImport] -> [TyThing] -> IcGlobalRdrEnv -> (InstEnv, [FamInst]) -> FixityEnv -> DefaultEnv -> [Resume] -> Name -> Name -> Maybe FilePath -> !Plugins -> InteractiveContext
+ GHC.Runtime.Context: InteractiveContext :: DynFlags -> Int -> [InteractiveImport] -> [TyThing] -> IcGlobalRdrEnv -> (InstEnv, [FamInst]) -> FixityEnv -> DefaultEnv -> [Resume] -> Name -> Name -> Maybe FilePath -> Plugins -> InteractiveContext
- GHC.Runtime.Context: [ic_plugins] :: InteractiveContext -> !Plugins
+ GHC.Runtime.Context: [ic_plugins] :: InteractiveContext -> Plugins
- GHC.Runtime.Eval: Suspension :: ClosureType -> RttiType -> ForeignHValue -> Maybe Name -> Term
+ GHC.Runtime.Eval: Suspension :: ClosureType -> RttiType -> ForeignHValue -> Maybe Name -> Maybe InfoProv -> Term
- GHC.Runtime.Eval: back :: GhcMonad m => Int -> m ([Name], Int, SrcSpan, String)
+ GHC.Runtime.Eval: back :: GhcMonad m => Int -> m ([Name], Int, SrcSpan)
- GHC.Runtime.Eval: forward :: GhcMonad m => Int -> m ([Name], Int, SrcSpan, String)
+ GHC.Runtime.Eval: forward :: GhcMonad m => Int -> m ([Name], Int, SrcSpan)
- GHC.Runtime.Eval: getHistoryModule :: History -> Module
+ GHC.Runtime.Eval: getHistoryModule :: HomeUnitGraph -> History -> IO Module
- GHC.Runtime.Eval: getHistorySpan :: HscEnv -> History -> SrcSpan
+ GHC.Runtime.Eval: getHistorySpan :: HomeUnitGraph -> History -> IO SrcSpan
- GHC.Runtime.Eval: getModBreaks :: HomeModInfo -> ModBreaks
+ GHC.Runtime.Eval: getModBreaks :: HomeModInfo -> Maybe InternalModBreaks
- GHC.Runtime.Eval: mkTopLevEnv :: HscEnv -> ModuleName -> IO (Either String GlobalRdrEnv)
+ GHC.Runtime.Eval: mkTopLevEnv :: HscEnv -> Module -> IO (Either String GlobalRdrEnv)
- GHC.Runtime.Eval: moduleIsBootOrNotObjectLinkable :: GhcMonad m => ModSummary -> m Bool
+ GHC.Runtime.Eval: moduleIsBootOrNotObjectLinkable :: GhcMonad m => Module -> m Bool
- GHC.Runtime.Eval: resumeExec :: GhcMonad m => (SrcSpan -> Bool) -> SingleStep -> Maybe Int -> m ExecResult
+ GHC.Runtime.Eval: resumeExec :: GhcMonad m => SingleStep -> Maybe Int -> m ExecResult
- GHC.Runtime.Eval: setupBreakpoint :: GhcMonad m => HscEnv -> BreakpointId -> Int -> m ()
+ GHC.Runtime.Eval: setupBreakpoint :: GhcMonad m => Interp -> InternalBreakpointId -> Int -> m ()
- GHC.Runtime.Eval: showModule :: GhcMonad m => ModSummary -> m String
+ GHC.Runtime.Eval: showModule :: GhcMonad m => ModuleNodeInfo -> m String
- GHC.Runtime.Eval.Types: IcGlobalRdrEnv :: !GlobalRdrEnv -> !GlobalRdrEnv -> IcGlobalRdrEnv
+ GHC.Runtime.Eval.Types: IcGlobalRdrEnv :: GlobalRdrEnv -> GlobalRdrEnv -> IcGlobalRdrEnv
- GHC.Runtime.Eval.Types: [igre_env] :: IcGlobalRdrEnv -> !GlobalRdrEnv
+ GHC.Runtime.Eval.Types: [igre_env] :: IcGlobalRdrEnv -> GlobalRdrEnv
- GHC.Runtime.Eval.Types: [igre_prompt_env] :: IcGlobalRdrEnv -> !GlobalRdrEnv
+ GHC.Runtime.Eval.Types: [igre_prompt_env] :: IcGlobalRdrEnv -> GlobalRdrEnv
- GHC.Runtime.Heap.Inspect: Suspension :: ClosureType -> RttiType -> ForeignHValue -> Maybe Name -> Term
+ GHC.Runtime.Heap.Inspect: Suspension :: ClosureType -> RttiType -> ForeignHValue -> Maybe Name -> Maybe InfoProv -> Term
- GHC.Runtime.Heap.Inspect: TermFold :: TermProcessor a a -> (RttiType -> [Word] -> a) -> (ClosureType -> RttiType -> ForeignHValue -> Maybe Name -> a) -> (RttiType -> Either String DataCon -> a -> a) -> (RttiType -> a -> a) -> TermFold a
+ GHC.Runtime.Heap.Inspect: TermFold :: TermProcessor a a -> (RttiType -> [Word] -> a) -> (ClosureType -> RttiType -> ForeignHValue -> Maybe Name -> Maybe InfoProv -> a) -> (RttiType -> Either String DataCon -> a -> a) -> (RttiType -> a -> a) -> TermFold a
- GHC.Runtime.Heap.Inspect: [fSuspension] :: TermFold a -> ClosureType -> RttiType -> ForeignHValue -> Maybe Name -> a
+ GHC.Runtime.Heap.Inspect: [fSuspension] :: TermFold a -> ClosureType -> RttiType -> ForeignHValue -> Maybe Name -> Maybe InfoProv -> a
- GHC.Runtime.Heap.Layout: ArgSpec :: !Int -> ArgDescr
+ GHC.Runtime.Heap.Layout: ArgSpec :: Int -> ArgDescr
- GHC.Runtime.Heap.Layout: ArrayPtrsRep :: !WordOff -> !WordOff -> SMRep
+ GHC.Runtime.Heap.Layout: ArrayPtrsRep :: WordOff -> WordOff -> SMRep
- GHC.Runtime.Heap.Layout: ArrayWordsRep :: !WordOff -> SMRep
+ GHC.Runtime.Heap.Layout: ArrayWordsRep :: WordOff -> SMRep
- GHC.Runtime.Heap.Layout: HeapRep :: IsStatic -> !WordOff -> !WordOff -> ClosureTypeInfo -> SMRep
+ GHC.Runtime.Heap.Layout: HeapRep :: IsStatic -> WordOff -> WordOff -> ClosureTypeInfo -> SMRep
- GHC.Runtime.Heap.Layout: SmallArrayPtrsRep :: !WordOff -> SMRep
+ GHC.Runtime.Heap.Layout: SmallArrayPtrsRep :: WordOff -> SMRep
- GHC.Runtime.Interpreter: [MkConInfoTable] :: Bool -> Int -> Int -> Int -> Int -> ByteString -> Message (RemotePtr StgInfoTable)
+ GHC.Runtime.Interpreter: [MkConInfoTable] :: ConInfoTable -> Message (RemotePtr StgInfoTable)
- GHC.Runtime.Interpreter: evalBreakpointToId :: HomePackageTable -> EvalBreakpoint -> InternalBreakpointId
+ GHC.Runtime.Interpreter: evalBreakpointToId :: EvalBreakpoint -> InternalBreakpointId
- GHC.Runtime.Interpreter: getModBreaks :: HomeModInfo -> ModBreaks
+ GHC.Runtime.Interpreter: getModBreaks :: HomeModInfo -> Maybe InternalModBreaks
- GHC.Runtime.Interpreter: lookupClosure :: Interp -> String -> IO (Maybe HValueRef)
+ GHC.Runtime.Interpreter: lookupClosure :: forall (s :: SuffixOrInterpreted). Interp -> InterpSymbol s -> IO (Maybe HValueRef)
- GHC.Runtime.Interpreter: lookupSymbol :: Interp -> FastString -> IO (Maybe (Ptr ()))
+ GHC.Runtime.Interpreter: lookupSymbol :: forall (s :: SuffixOrInterpreted). Interp -> InterpSymbol s -> IO (Maybe (Ptr ()))
- GHC.Runtime.Interpreter: lookupSymbolInDLL :: Interp -> RemotePtr LoadedDLL -> FastString -> IO (Maybe (Ptr ()))
+ GHC.Runtime.Interpreter: lookupSymbolInDLL :: forall (s :: SuffixOrInterpreted). Interp -> RemotePtr LoadedDLL -> InterpSymbol s -> IO (Maybe (Ptr ()))
- GHC.Runtime.Interpreter.Process: [MkConInfoTable] :: Bool -> Int -> Int -> Int -> Int -> ByteString -> Message (RemotePtr StgInfoTable)
+ GHC.Runtime.Interpreter.Process: [MkConInfoTable] :: ConInfoTable -> Message (RemotePtr StgInfoTable)
- GHC.Runtime.Interpreter.Types: ExtIServ :: !IServ -> ExtInterp
+ GHC.Runtime.Interpreter.Types: ExtIServ :: IServ -> ExtInterp
- GHC.Runtime.Interpreter.Types: ExtInterpInstance :: {-# UNPACK #-} !InterpProcess -> !MVar [HValueRef] -> !c -> ExtInterpInstance c
+ GHC.Runtime.Interpreter.Types: ExtInterpInstance :: InterpProcess -> MVar [HValueRef] -> c -> ExtInterpInstance c
- GHC.Runtime.Interpreter.Types: ExtInterpState :: !cfg -> !ExtInterpStatusVar details -> ExtInterpState cfg details
+ GHC.Runtime.Interpreter.Types: ExtInterpState :: cfg -> ExtInterpStatusVar details -> ExtInterpState cfg details
- GHC.Runtime.Interpreter.Types: ExtJS :: !JSInterp -> ExtInterp
+ GHC.Runtime.Interpreter.Types: ExtJS :: JSInterp -> ExtInterp
- GHC.Runtime.Interpreter.Types: ExtWasm :: !WasmInterp -> ExtInterp
+ GHC.Runtime.Interpreter.Types: ExtWasm :: WasmInterp -> ExtInterp
- GHC.Runtime.Interpreter.Types: ExternalInterp :: !ExtInterp -> InterpInstance
+ GHC.Runtime.Interpreter.Types: ExternalInterp :: ExtInterp -> InterpInstance
- GHC.Runtime.Interpreter.Types: IServConfig :: !String -> ![String] -> !Bool -> !Bool -> !Maybe (CreateProcess -> IO ProcessHandle) -> IO () -> IServConfig
+ GHC.Runtime.Interpreter.Types: IServConfig :: String -> [String] -> Bool -> Bool -> Maybe (CreateProcess -> IO ProcessHandle) -> IO () -> IServConfig
- GHC.Runtime.Interpreter.Types: Interp :: !InterpInstance -> !Loader -> !MVar (UniqFM FastString (Ptr ())) -> Interp
+ GHC.Runtime.Interpreter.Types: Interp :: InterpInstance -> Loader -> InterpSymbolCache -> Interp
- GHC.Runtime.Interpreter.Types: InterpProcess :: !Pipe -> !ProcessHandle -> !MVar () -> InterpProcess
+ GHC.Runtime.Interpreter.Types: InterpProcess :: Pipe -> ProcessHandle -> MVar () -> InterpProcess
- GHC.Runtime.Interpreter.Types: InterpRunning :: !inst -> InterpStatus inst
+ GHC.Runtime.Interpreter.Types: InterpRunning :: inst -> InterpStatus inst
- GHC.Runtime.Interpreter.Types: JSInterpConfig :: !NodeJsSettings -> !FilePath -> !TmpFs -> !TempDir -> !Logger -> !StgToJSConfig -> !UnitEnv -> !FinderOpts -> !FinderCache -> JSInterpConfig
+ GHC.Runtime.Interpreter.Types: JSInterpConfig :: NodeJsSettings -> FilePath -> TmpFs -> TempDir -> Logger -> StgToJSConfig -> UnitEnv -> FinderOpts -> FinderCache -> JSInterpConfig
- GHC.Runtime.Interpreter.Types: JSInterpExtra :: !Handle -> !FinderCache -> !FinderOpts -> !MVar JSState -> !UnitId -> JSInterpExtra
+ GHC.Runtime.Interpreter.Types: JSInterpExtra :: Handle -> FinderCache -> FinderOpts -> MVar JSState -> UnitId -> JSInterpExtra
- GHC.Runtime.Interpreter.Types: JSState :: !LinkPlan -> !Bool -> JSState
+ GHC.Runtime.Interpreter.Types: JSState :: LinkPlan -> Bool -> JSState
- GHC.Runtime.Interpreter.Types: WasmInterpConfig :: !FilePath -> FilePath -> ![String] -> !Platform -> !Bool -> !String -> !UnitState -> WasmInterpConfig
+ GHC.Runtime.Interpreter.Types: WasmInterpConfig :: FilePath -> FilePath -> [String] -> Bool -> String -> Int -> Bool -> Maybe String -> Maybe String -> Maybe String -> Platform -> Bool -> String -> UnitState -> WasmInterpConfig
- GHC.Runtime.Interpreter.Types: [instExtra] :: ExtInterpInstance c -> !c
+ GHC.Runtime.Interpreter.Types: [instExtra] :: ExtInterpInstance c -> c
- GHC.Runtime.Interpreter.Types: [instFinderCache] :: JSInterpExtra -> !FinderCache
+ GHC.Runtime.Interpreter.Types: [instFinderCache] :: JSInterpExtra -> FinderCache
- GHC.Runtime.Interpreter.Types: [instFinderOpts] :: JSInterpExtra -> !FinderOpts
+ GHC.Runtime.Interpreter.Types: [instFinderOpts] :: JSInterpExtra -> FinderOpts
- GHC.Runtime.Interpreter.Types: [instGhciUnitId] :: JSInterpExtra -> !UnitId
+ GHC.Runtime.Interpreter.Types: [instGhciUnitId] :: JSInterpExtra -> UnitId
- GHC.Runtime.Interpreter.Types: [instJSState] :: JSInterpExtra -> !MVar JSState
+ GHC.Runtime.Interpreter.Types: [instJSState] :: JSInterpExtra -> MVar JSState
- GHC.Runtime.Interpreter.Types: [instPendingFrees] :: ExtInterpInstance c -> !MVar [HValueRef]
+ GHC.Runtime.Interpreter.Types: [instPendingFrees] :: ExtInterpInstance c -> MVar [HValueRef]
- GHC.Runtime.Interpreter.Types: [instProcess] :: ExtInterpInstance c -> {-# UNPACK #-} !InterpProcess
+ GHC.Runtime.Interpreter.Types: [instProcess] :: ExtInterpInstance c -> InterpProcess
- GHC.Runtime.Interpreter.Types: [instStdIn] :: JSInterpExtra -> !Handle
+ GHC.Runtime.Interpreter.Types: [instStdIn] :: JSInterpExtra -> Handle
- GHC.Runtime.Interpreter.Types: [interpConfig] :: ExtInterpState cfg details -> !cfg
+ GHC.Runtime.Interpreter.Types: [interpConfig] :: ExtInterpState cfg details -> cfg
- GHC.Runtime.Interpreter.Types: [interpHandle] :: InterpProcess -> !ProcessHandle
+ GHC.Runtime.Interpreter.Types: [interpHandle] :: InterpProcess -> ProcessHandle
- GHC.Runtime.Interpreter.Types: [interpInstance] :: Interp -> !InterpInstance
+ GHC.Runtime.Interpreter.Types: [interpInstance] :: Interp -> InterpInstance
- GHC.Runtime.Interpreter.Types: [interpLoader] :: Interp -> !Loader
+ GHC.Runtime.Interpreter.Types: [interpLoader] :: Interp -> Loader
- GHC.Runtime.Interpreter.Types: [interpLock] :: InterpProcess -> !MVar ()
+ GHC.Runtime.Interpreter.Types: [interpLock] :: InterpProcess -> MVar ()
- GHC.Runtime.Interpreter.Types: [interpPipe] :: InterpProcess -> !Pipe
+ GHC.Runtime.Interpreter.Types: [interpPipe] :: InterpProcess -> Pipe
- GHC.Runtime.Interpreter.Types: [interpStatus] :: ExtInterpState cfg details -> !ExtInterpStatusVar details
+ GHC.Runtime.Interpreter.Types: [interpStatus] :: ExtInterpState cfg details -> ExtInterpStatusVar details
- GHC.Runtime.Interpreter.Types: [iservConfDynamic] :: IServConfig -> !Bool
+ GHC.Runtime.Interpreter.Types: [iservConfDynamic] :: IServConfig -> Bool
- GHC.Runtime.Interpreter.Types: [iservConfHook] :: IServConfig -> !Maybe (CreateProcess -> IO ProcessHandle)
+ GHC.Runtime.Interpreter.Types: [iservConfHook] :: IServConfig -> Maybe (CreateProcess -> IO ProcessHandle)
- GHC.Runtime.Interpreter.Types: [iservConfOpts] :: IServConfig -> ![String]
+ GHC.Runtime.Interpreter.Types: [iservConfOpts] :: IServConfig -> [String]
- GHC.Runtime.Interpreter.Types: [iservConfProfiled] :: IServConfig -> !Bool
+ GHC.Runtime.Interpreter.Types: [iservConfProfiled] :: IServConfig -> Bool
- GHC.Runtime.Interpreter.Types: [iservConfProgram] :: IServConfig -> !String
+ GHC.Runtime.Interpreter.Types: [iservConfProgram] :: IServConfig -> String
- GHC.Runtime.Interpreter.Types: [jsInterpCodegenCfg] :: JSInterpConfig -> !StgToJSConfig
+ GHC.Runtime.Interpreter.Types: [jsInterpCodegenCfg] :: JSInterpConfig -> StgToJSConfig
- GHC.Runtime.Interpreter.Types: [jsInterpFinderCache] :: JSInterpConfig -> !FinderCache
+ GHC.Runtime.Interpreter.Types: [jsInterpFinderCache] :: JSInterpConfig -> FinderCache
- GHC.Runtime.Interpreter.Types: [jsInterpFinderOpts] :: JSInterpConfig -> !FinderOpts
+ GHC.Runtime.Interpreter.Types: [jsInterpFinderOpts] :: JSInterpConfig -> FinderOpts
- GHC.Runtime.Interpreter.Types: [jsInterpLogger] :: JSInterpConfig -> !Logger
+ GHC.Runtime.Interpreter.Types: [jsInterpLogger] :: JSInterpConfig -> Logger
- GHC.Runtime.Interpreter.Types: [jsInterpNodeConfig] :: JSInterpConfig -> !NodeJsSettings
+ GHC.Runtime.Interpreter.Types: [jsInterpNodeConfig] :: JSInterpConfig -> NodeJsSettings
- GHC.Runtime.Interpreter.Types: [jsInterpScript] :: JSInterpConfig -> !FilePath
+ GHC.Runtime.Interpreter.Types: [jsInterpScript] :: JSInterpConfig -> FilePath
- GHC.Runtime.Interpreter.Types: [jsInterpTmpDir] :: JSInterpConfig -> !TempDir
+ GHC.Runtime.Interpreter.Types: [jsInterpTmpDir] :: JSInterpConfig -> TempDir
- GHC.Runtime.Interpreter.Types: [jsInterpTmpFs] :: JSInterpConfig -> !TmpFs
+ GHC.Runtime.Interpreter.Types: [jsInterpTmpFs] :: JSInterpConfig -> TmpFs
- GHC.Runtime.Interpreter.Types: [jsInterpUnitEnv] :: JSInterpConfig -> !UnitEnv
+ GHC.Runtime.Interpreter.Types: [jsInterpUnitEnv] :: JSInterpConfig -> UnitEnv
- GHC.Runtime.Interpreter.Types: [jsLinkState] :: JSState -> !LinkPlan
+ GHC.Runtime.Interpreter.Types: [jsLinkState] :: JSState -> LinkPlan
- GHC.Runtime.Interpreter.Types: [jsServerStarted] :: JSState -> !Bool
+ GHC.Runtime.Interpreter.Types: [jsServerStarted] :: JSState -> Bool
- GHC.Runtime.Interpreter.Types: [wasmInterpDyLD] :: WasmInterpConfig -> !FilePath
+ GHC.Runtime.Interpreter.Types: [wasmInterpDyLD] :: WasmInterpConfig -> FilePath
- GHC.Runtime.Interpreter.Types: [wasmInterpHsSoSuffix] :: WasmInterpConfig -> !String
+ GHC.Runtime.Interpreter.Types: [wasmInterpHsSoSuffix] :: WasmInterpConfig -> String
- GHC.Runtime.Interpreter.Types: [wasmInterpOpts] :: WasmInterpConfig -> ![String]
+ GHC.Runtime.Interpreter.Types: [wasmInterpOpts] :: WasmInterpConfig -> [String]
- GHC.Runtime.Interpreter.Types: [wasmInterpProfiled] :: WasmInterpConfig -> !Bool
+ GHC.Runtime.Interpreter.Types: [wasmInterpProfiled] :: WasmInterpConfig -> Bool
- GHC.Runtime.Interpreter.Types: [wasmInterpTargetPlatform] :: WasmInterpConfig -> !Platform
+ GHC.Runtime.Interpreter.Types: [wasmInterpTargetPlatform] :: WasmInterpConfig -> Platform
- GHC.Runtime.Interpreter.Types: [wasmInterpUnitState] :: WasmInterpConfig -> !UnitState
+ GHC.Runtime.Interpreter.Types: [wasmInterpUnitState] :: WasmInterpConfig -> UnitState
- GHC.Settings: Platform :: !ArchOS -> !PlatformWordSize -> !ByteOrder -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Maybe PlatformConstants -> Platform
+ GHC.Settings: Platform :: ArchOS -> PlatformWordSize -> ByteOrder -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Maybe PlatformConstants -> Platform
- GHC.Settings: Settings :: {-# UNPACK #-} !GhcNameVersion -> {-# UNPACK #-} !FileSettings -> Platform -> {-# UNPACK #-} !ToolSettings -> {-# UNPACK #-} !PlatformMisc -> [(String, String)] -> Settings
+ GHC.Settings: Settings :: GhcNameVersion -> FileSettings -> Platform -> ToolSettings -> PlatformMisc -> UnitSettings -> [(String, String)] -> Settings
- GHC.Settings: [platformArchOS] :: Platform -> !ArchOS
+ GHC.Settings: [platformArchOS] :: Platform -> ArchOS
- GHC.Settings: [platformByteOrder] :: Platform -> !ByteOrder
+ GHC.Settings: [platformByteOrder] :: Platform -> ByteOrder
- GHC.Settings: [platformHasGnuNonexecStack] :: Platform -> !Bool
+ GHC.Settings: [platformHasGnuNonexecStack] :: Platform -> Bool
- GHC.Settings: [platformHasIdentDirective] :: Platform -> !Bool
+ GHC.Settings: [platformHasIdentDirective] :: Platform -> Bool
- GHC.Settings: [platformHasLibm] :: Platform -> !Bool
+ GHC.Settings: [platformHasLibm] :: Platform -> Bool
- GHC.Settings: [platformHasSubsectionsViaSymbols] :: Platform -> !Bool
+ GHC.Settings: [platformHasSubsectionsViaSymbols] :: Platform -> Bool
- GHC.Settings: [platformIsCrossCompiling] :: Platform -> !Bool
+ GHC.Settings: [platformIsCrossCompiling] :: Platform -> Bool
- GHC.Settings: [platformLeadingUnderscore] :: Platform -> !Bool
+ GHC.Settings: [platformLeadingUnderscore] :: Platform -> Bool
- GHC.Settings: [platformTablesNextToCode] :: Platform -> !Bool
+ GHC.Settings: [platformTablesNextToCode] :: Platform -> Bool
- GHC.Settings: [platformUnregisterised] :: Platform -> !Bool
+ GHC.Settings: [platformUnregisterised] :: Platform -> Bool
- GHC.Settings: [platformWordSize] :: Platform -> !PlatformWordSize
+ GHC.Settings: [platformWordSize] :: Platform -> PlatformWordSize
- GHC.Settings: [platform_constants] :: Platform -> !Maybe PlatformConstants
+ GHC.Settings: [platform_constants] :: Platform -> Maybe PlatformConstants
- GHC.Settings: [sFileSettings] :: Settings -> {-# UNPACK #-} !FileSettings
+ GHC.Settings: [sFileSettings] :: Settings -> FileSettings
- GHC.Settings: [sGhcNameVersion] :: Settings -> {-# UNPACK #-} !GhcNameVersion
+ GHC.Settings: [sGhcNameVersion] :: Settings -> GhcNameVersion
- GHC.Settings: [sPlatformMisc] :: Settings -> {-# UNPACK #-} !PlatformMisc
+ GHC.Settings: [sPlatformMisc] :: Settings -> PlatformMisc
- GHC.Settings: [sToolSettings] :: Settings -> {-# UNPACK #-} !ToolSettings
+ GHC.Settings: [sToolSettings] :: Settings -> ToolSettings
- GHC.Stg.Debug: StgDebugOpts :: !Bool -> !Bool -> StgDebugOpts
+ GHC.Stg.Debug: StgDebugOpts :: Bool -> Bool -> StgDebugOpts
- GHC.Stg.Debug: [stgDebug_distinctConstructorTables] :: StgDebugOpts -> !Bool
+ GHC.Stg.Debug: [stgDebug_distinctConstructorTables] :: StgDebugOpts -> Bool
- GHC.Stg.Debug: [stgDebug_infoTableMap] :: StgDebugOpts -> !Bool
+ GHC.Stg.Debug: [stgDebug_infoTableMap] :: StgDebugOpts -> Bool
- GHC.Stg.Lift: StgLiftConfig :: !Profile -> !Maybe Int -> !Maybe Int -> !Bool -> StgLiftConfig
+ GHC.Stg.Lift: StgLiftConfig :: Profile -> Maybe Int -> Maybe Int -> Bool -> StgLiftConfig
- GHC.Stg.Lift: [c_liftLamsKnown] :: StgLiftConfig -> !Bool
+ GHC.Stg.Lift: [c_liftLamsKnown] :: StgLiftConfig -> Bool
- GHC.Stg.Lift: [c_liftLamsNonRecArgs] :: StgLiftConfig -> !Maybe Int
+ GHC.Stg.Lift: [c_liftLamsNonRecArgs] :: StgLiftConfig -> Maybe Int
- GHC.Stg.Lift: [c_liftLamsRecArgs] :: StgLiftConfig -> !Maybe Int
+ GHC.Stg.Lift: [c_liftLamsRecArgs] :: StgLiftConfig -> Maybe Int
- GHC.Stg.Lift: [c_targetProfile] :: StgLiftConfig -> !Profile
+ GHC.Stg.Lift: [c_targetProfile] :: StgLiftConfig -> Profile
- GHC.Stg.Lift.Analysis: AltSk :: !Skeleton -> !Skeleton -> Skeleton
+ GHC.Stg.Lift.Analysis: AltSk :: Skeleton -> Skeleton -> Skeleton
- GHC.Stg.Lift.Analysis: BindsClosure :: !Id -> !Bool -> BinderInfo
+ GHC.Stg.Lift.Analysis: BindsClosure :: Id -> Bool -> BinderInfo
- GHC.Stg.Lift.Analysis: BoringBinder :: !Id -> BinderInfo
+ GHC.Stg.Lift.Analysis: BoringBinder :: Id -> BinderInfo
- GHC.Stg.Lift.Analysis: BothSk :: !Skeleton -> !Skeleton -> Skeleton
+ GHC.Stg.Lift.Analysis: BothSk :: Skeleton -> Skeleton -> Skeleton
- GHC.Stg.Lift.Analysis: ClosureSk :: !Id -> !DIdSet -> !Skeleton -> Skeleton
+ GHC.Stg.Lift.Analysis: ClosureSk :: Id -> DIdSet -> Skeleton -> Skeleton
- GHC.Stg.Lift.Analysis: RhsSk :: !Card -> !Skeleton -> Skeleton
+ GHC.Stg.Lift.Analysis: RhsSk :: Card -> Skeleton -> Skeleton
- GHC.Stg.Lift.Config: StgLiftConfig :: !Profile -> !Maybe Int -> !Maybe Int -> !Bool -> StgLiftConfig
+ GHC.Stg.Lift.Config: StgLiftConfig :: Profile -> Maybe Int -> Maybe Int -> Bool -> StgLiftConfig
- GHC.Stg.Lift.Config: [c_liftLamsKnown] :: StgLiftConfig -> !Bool
+ GHC.Stg.Lift.Config: [c_liftLamsKnown] :: StgLiftConfig -> Bool
- GHC.Stg.Lift.Config: [c_liftLamsNonRecArgs] :: StgLiftConfig -> !Maybe Int
+ GHC.Stg.Lift.Config: [c_liftLamsNonRecArgs] :: StgLiftConfig -> Maybe Int
- GHC.Stg.Lift.Config: [c_liftLamsRecArgs] :: StgLiftConfig -> !Maybe Int
+ GHC.Stg.Lift.Config: [c_liftLamsRecArgs] :: StgLiftConfig -> Maybe Int
- GHC.Stg.Lift.Config: [c_targetProfile] :: StgLiftConfig -> !Profile
+ GHC.Stg.Lift.Config: [c_targetProfile] :: StgLiftConfig -> Profile
- GHC.Stg.Lift.Monad: Env :: StgLiftConfig -> !Subst -> !IdEnv DIdSet -> Env
+ GHC.Stg.Lift.Monad: Env :: StgLiftConfig -> Subst -> IdEnv DIdSet -> Env
- GHC.Stg.Lift.Monad: [e_expansions] :: Env -> !IdEnv DIdSet
+ GHC.Stg.Lift.Monad: [e_expansions] :: Env -> IdEnv DIdSet
- GHC.Stg.Lift.Monad: [e_subst] :: Env -> !Subst
+ GHC.Stg.Lift.Monad: [e_subst] :: Env -> Subst
- GHC.Stg.Lift.Types: AltSk :: !Skeleton -> !Skeleton -> Skeleton
+ GHC.Stg.Lift.Types: AltSk :: Skeleton -> Skeleton -> Skeleton
- GHC.Stg.Lift.Types: BindsClosure :: !Id -> !Bool -> BinderInfo
+ GHC.Stg.Lift.Types: BindsClosure :: Id -> Bool -> BinderInfo
- GHC.Stg.Lift.Types: BoringBinder :: !Id -> BinderInfo
+ GHC.Stg.Lift.Types: BoringBinder :: Id -> BinderInfo
- GHC.Stg.Lift.Types: BothSk :: !Skeleton -> !Skeleton -> Skeleton
+ GHC.Stg.Lift.Types: BothSk :: Skeleton -> Skeleton -> Skeleton
- GHC.Stg.Lift.Types: ClosureSk :: !Id -> !DIdSet -> !Skeleton -> Skeleton
+ GHC.Stg.Lift.Types: ClosureSk :: Id -> DIdSet -> Skeleton -> Skeleton
- GHC.Stg.Lift.Types: RhsSk :: !Card -> !Skeleton -> Skeleton
+ GHC.Stg.Lift.Types: RhsSk :: Card -> Skeleton -> Skeleton
- GHC.Stg.Make: MkStgRhs :: [Id] -> StgExpr -> Type -> !Bool -> MkStgRhs
+ GHC.Stg.Make: MkStgRhs :: [Id] -> StgExpr -> Type -> Bool -> MkStgRhs
- GHC.Stg.Make: [rhs_is_join] :: MkStgRhs -> !Bool
+ GHC.Stg.Make: [rhs_is_join] :: MkStgRhs -> Bool
- GHC.Stg.Pipeline: StgPipelineOpts :: ![StgToDo] -> !Maybe DiagOpts -> !StgPprOpts -> !Platform -> !Bool -> (Module -> DataCon -> [StgArg] -> Bool) -> StgPipelineOpts
+ GHC.Stg.Pipeline: StgPipelineOpts :: [StgToDo] -> Maybe DiagOpts -> StgPprOpts -> Platform -> Bool -> (Module -> DataCon -> [StgArg] -> Bool) -> StgPipelineOpts
- GHC.Stg.Pipeline: [stgPipeline_forBytecode] :: StgPipelineOpts -> !Bool
+ GHC.Stg.Pipeline: [stgPipeline_forBytecode] :: StgPipelineOpts -> Bool
- GHC.Stg.Pipeline: [stgPipeline_lint] :: StgPipelineOpts -> !Maybe DiagOpts
+ GHC.Stg.Pipeline: [stgPipeline_lint] :: StgPipelineOpts -> Maybe DiagOpts
- GHC.Stg.Pipeline: [stgPipeline_phases] :: StgPipelineOpts -> ![StgToDo]
+ GHC.Stg.Pipeline: [stgPipeline_phases] :: StgPipelineOpts -> [StgToDo]
- GHC.Stg.Pipeline: [stgPipeline_pprOpts] :: StgPipelineOpts -> !StgPprOpts
+ GHC.Stg.Pipeline: [stgPipeline_pprOpts] :: StgPipelineOpts -> StgPprOpts
- GHC.Stg.Pipeline: [stgPlatform] :: StgPipelineOpts -> !Platform
+ GHC.Stg.Pipeline: [stgPlatform] :: StgPipelineOpts -> Platform
- GHC.Stg.Syntax: GenStgAlt :: !AltCon -> ![BinderP pass] -> !GenStgExpr pass -> GenStgAlt (pass :: StgPass)
+ GHC.Stg.Syntax: GenStgAlt :: AltCon -> [BinderP pass] -> GenStgExpr pass -> GenStgAlt (pass :: StgPass)
- GHC.Stg.Syntax: StgPprOpts :: !Bool -> StgPprOpts
+ GHC.Stg.Syntax: StgPprOpts :: Bool -> StgPprOpts
- GHC.Stg.Syntax: StgRhsClosure :: XRhsClosure pass -> CostCentreStack -> !UpdateFlag -> [BinderP pass] -> GenStgExpr pass -> Type -> GenStgRhs (pass :: StgPass)
+ GHC.Stg.Syntax: StgRhsClosure :: XRhsClosure pass -> CostCentreStack -> UpdateFlag -> [BinderP pass] -> GenStgExpr pass -> Type -> GenStgRhs (pass :: StgPass)
- GHC.Stg.Syntax: [alt_bndrs] :: GenStgAlt (pass :: StgPass) -> ![BinderP pass]
+ GHC.Stg.Syntax: [alt_bndrs] :: GenStgAlt (pass :: StgPass) -> [BinderP pass]
- GHC.Stg.Syntax: [alt_con] :: GenStgAlt (pass :: StgPass) -> !AltCon
+ GHC.Stg.Syntax: [alt_con] :: GenStgAlt (pass :: StgPass) -> AltCon
- GHC.Stg.Syntax: [alt_rhs] :: GenStgAlt (pass :: StgPass) -> !GenStgExpr pass
+ GHC.Stg.Syntax: [alt_rhs] :: GenStgAlt (pass :: StgPass) -> GenStgExpr pass
- GHC.Stg.Syntax: [stgSccEnabled] :: StgPprOpts -> !Bool
+ GHC.Stg.Syntax: [stgSccEnabled] :: StgPprOpts -> Bool
- GHC.StgToCmm.CgUtils: fixStgRegisters :: Platform -> RawCmmDecl -> RawCmmDecl
+ GHC.StgToCmm.CgUtils: fixStgRegisters :: Platform -> GenCmmDecl d h (GenCmmGraph CmmNode) -> GenCmmDecl d h (GenCmmGraph CmmNode)
- GHC.StgToCmm.Config: StgToCmmConfig :: !Profile -> Module -> !TempDir -> !SDocContext -> !Bool -> !Maybe Word -> !Int -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> (FMASign -> Bool) -> !Bool -> !Bool -> Maybe String -> !Bool -> !Bool -> !Bool -> StgToCmmConfig
+ GHC.StgToCmm.Config: StgToCmmConfig :: Profile -> Module -> TempDir -> SDocContext -> Bool -> Maybe Word -> Int -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> (FMASign -> Bool) -> Bool -> Bool -> Bool -> Maybe String -> Bool -> Bool -> Bool -> StgToCmmConfig
- GHC.StgToCmm.Config: [stgToCmmAlignCheck] :: StgToCmmConfig -> !Bool
+ GHC.StgToCmm.Config: [stgToCmmAlignCheck] :: StgToCmmConfig -> Bool
- GHC.StgToCmm.Config: [stgToCmmAllowArith64] :: StgToCmmConfig -> !Bool
+ GHC.StgToCmm.Config: [stgToCmmAllowArith64] :: StgToCmmConfig -> Bool
- GHC.StgToCmm.Config: [stgToCmmAllowExtendedAddSubInstrs] :: StgToCmmConfig -> !Bool
+ GHC.StgToCmm.Config: [stgToCmmAllowExtendedAddSubInstrs] :: StgToCmmConfig -> Bool
- GHC.StgToCmm.Config: [stgToCmmAllowIntMul2Instr] :: StgToCmmConfig -> !Bool
+ GHC.StgToCmm.Config: [stgToCmmAllowIntMul2Instr] :: StgToCmmConfig -> Bool
- GHC.StgToCmm.Config: [stgToCmmAllowQuot64] :: StgToCmmConfig -> !Bool
+ GHC.StgToCmm.Config: [stgToCmmAllowQuot64] :: StgToCmmConfig -> Bool
- GHC.StgToCmm.Config: [stgToCmmAllowQuotRem2] :: StgToCmmConfig -> !Bool
+ GHC.StgToCmm.Config: [stgToCmmAllowQuotRem2] :: StgToCmmConfig -> Bool
- GHC.StgToCmm.Config: [stgToCmmAllowQuotRemInstr] :: StgToCmmConfig -> !Bool
+ GHC.StgToCmm.Config: [stgToCmmAllowQuotRemInstr] :: StgToCmmConfig -> Bool
- GHC.StgToCmm.Config: [stgToCmmAllowWordMul2Instr] :: StgToCmmConfig -> !Bool
+ GHC.StgToCmm.Config: [stgToCmmAllowWordMul2Instr] :: StgToCmmConfig -> Bool
- GHC.StgToCmm.Config: [stgToCmmAvx2] :: StgToCmmConfig -> !Bool
+ GHC.StgToCmm.Config: [stgToCmmAvx2] :: StgToCmmConfig -> Bool
- GHC.StgToCmm.Config: [stgToCmmAvx512f] :: StgToCmmConfig -> !Bool
+ GHC.StgToCmm.Config: [stgToCmmAvx512f] :: StgToCmmConfig -> Bool
- GHC.StgToCmm.Config: [stgToCmmAvx] :: StgToCmmConfig -> !Bool
+ GHC.StgToCmm.Config: [stgToCmmAvx] :: StgToCmmConfig -> Bool
- GHC.StgToCmm.Config: [stgToCmmBinBlobThresh] :: StgToCmmConfig -> !Maybe Word
+ GHC.StgToCmm.Config: [stgToCmmBinBlobThresh] :: StgToCmmConfig -> Maybe Word
- GHC.StgToCmm.Config: [stgToCmmContext] :: StgToCmmConfig -> !SDocContext
+ GHC.StgToCmm.Config: [stgToCmmContext] :: StgToCmmConfig -> SDocContext
- GHC.StgToCmm.Config: [stgToCmmDoBoundsCheck] :: StgToCmmConfig -> !Bool
+ GHC.StgToCmm.Config: [stgToCmmDoBoundsCheck] :: StgToCmmConfig -> Bool
- GHC.StgToCmm.Config: [stgToCmmDoTagCheck] :: StgToCmmConfig -> !Bool
+ GHC.StgToCmm.Config: [stgToCmmDoTagCheck] :: StgToCmmConfig -> Bool
- GHC.StgToCmm.Config: [stgToCmmDoTicky] :: StgToCmmConfig -> !Bool
+ GHC.StgToCmm.Config: [stgToCmmDoTicky] :: StgToCmmConfig -> Bool
- GHC.StgToCmm.Config: [stgToCmmEagerBlackHole] :: StgToCmmConfig -> !Bool
+ GHC.StgToCmm.Config: [stgToCmmEagerBlackHole] :: StgToCmmConfig -> Bool
- GHC.StgToCmm.Config: [stgToCmmEmitDebugInfo] :: StgToCmmConfig -> !Bool
+ GHC.StgToCmm.Config: [stgToCmmEmitDebugInfo] :: StgToCmmConfig -> Bool
- GHC.StgToCmm.Config: [stgToCmmExtDynRefs] :: StgToCmmConfig -> !Bool
+ GHC.StgToCmm.Config: [stgToCmmExtDynRefs] :: StgToCmmConfig -> Bool
- GHC.StgToCmm.Config: [stgToCmmFastPAPCalls] :: StgToCmmConfig -> !Bool
+ GHC.StgToCmm.Config: [stgToCmmFastPAPCalls] :: StgToCmmConfig -> Bool
- GHC.StgToCmm.Config: [stgToCmmInfoTableMapWithFallback] :: StgToCmmConfig -> !Bool
+ GHC.StgToCmm.Config: [stgToCmmInfoTableMapWithFallback] :: StgToCmmConfig -> Bool
- GHC.StgToCmm.Config: [stgToCmmInfoTableMapWithStack] :: StgToCmmConfig -> !Bool
+ GHC.StgToCmm.Config: [stgToCmmInfoTableMapWithStack] :: StgToCmmConfig -> Bool
- GHC.StgToCmm.Config: [stgToCmmInfoTableMap] :: StgToCmmConfig -> !Bool
+ GHC.StgToCmm.Config: [stgToCmmInfoTableMap] :: StgToCmmConfig -> Bool
- GHC.StgToCmm.Config: [stgToCmmLoopification] :: StgToCmmConfig -> !Bool
+ GHC.StgToCmm.Config: [stgToCmmLoopification] :: StgToCmmConfig -> Bool
- GHC.StgToCmm.Config: [stgToCmmMaxInlAllocSize] :: StgToCmmConfig -> !Int
+ GHC.StgToCmm.Config: [stgToCmmMaxInlAllocSize] :: StgToCmmConfig -> Int
- GHC.StgToCmm.Config: [stgToCmmObjectDeterminism] :: StgToCmmConfig -> !Bool
+ GHC.StgToCmm.Config: [stgToCmmObjectDeterminism] :: StgToCmmConfig -> Bool
- GHC.StgToCmm.Config: [stgToCmmOmitIfPragmas] :: StgToCmmConfig -> !Bool
+ GHC.StgToCmm.Config: [stgToCmmOmitIfPragmas] :: StgToCmmConfig -> Bool
- GHC.StgToCmm.Config: [stgToCmmOmitYields] :: StgToCmmConfig -> !Bool
+ GHC.StgToCmm.Config: [stgToCmmOmitYields] :: StgToCmmConfig -> Bool
- GHC.StgToCmm.Config: [stgToCmmOrigThunkInfo] :: StgToCmmConfig -> !Bool
+ GHC.StgToCmm.Config: [stgToCmmOrigThunkInfo] :: StgToCmmConfig -> Bool
- GHC.StgToCmm.Config: [stgToCmmPIC] :: StgToCmmConfig -> !Bool
+ GHC.StgToCmm.Config: [stgToCmmPIC] :: StgToCmmConfig -> Bool
- GHC.StgToCmm.Config: [stgToCmmPIE] :: StgToCmmConfig -> !Bool
+ GHC.StgToCmm.Config: [stgToCmmPIE] :: StgToCmmConfig -> Bool
- GHC.StgToCmm.Config: [stgToCmmProfile] :: StgToCmmConfig -> !Profile
+ GHC.StgToCmm.Config: [stgToCmmProfile] :: StgToCmmConfig -> Profile
- GHC.StgToCmm.Config: [stgToCmmSCCProfiling] :: StgToCmmConfig -> !Bool
+ GHC.StgToCmm.Config: [stgToCmmSCCProfiling] :: StgToCmmConfig -> Bool
- GHC.StgToCmm.Config: [stgToCmmSaveFCallTargetToLocal] :: StgToCmmConfig -> !Bool
+ GHC.StgToCmm.Config: [stgToCmmSaveFCallTargetToLocal] :: StgToCmmConfig -> Bool
- GHC.StgToCmm.Config: [stgToCmmTickyAP] :: StgToCmmConfig -> !Bool
+ GHC.StgToCmm.Config: [stgToCmmTickyAP] :: StgToCmmConfig -> Bool
- GHC.StgToCmm.Config: [stgToCmmTickyAllocd] :: StgToCmmConfig -> !Bool
+ GHC.StgToCmm.Config: [stgToCmmTickyAllocd] :: StgToCmmConfig -> Bool
- GHC.StgToCmm.Config: [stgToCmmTickyDynThunk] :: StgToCmmConfig -> !Bool
+ GHC.StgToCmm.Config: [stgToCmmTickyDynThunk] :: StgToCmmConfig -> Bool
- GHC.StgToCmm.Config: [stgToCmmTickyLNE] :: StgToCmmConfig -> !Bool
+ GHC.StgToCmm.Config: [stgToCmmTickyLNE] :: StgToCmmConfig -> Bool
- GHC.StgToCmm.Config: [stgToCmmTickyTag] :: StgToCmmConfig -> !Bool
+ GHC.StgToCmm.Config: [stgToCmmTickyTag] :: StgToCmmConfig -> Bool
- GHC.StgToCmm.Config: [stgToCmmTmpDir] :: StgToCmmConfig -> !TempDir
+ GHC.StgToCmm.Config: [stgToCmmTmpDir] :: StgToCmmConfig -> TempDir
- GHC.StgToCmm.Monad: MkSelfLoopInfo :: !Id -> !RepArity -> ![LocalReg] -> !BlockId -> SelfLoopInfo
+ GHC.StgToCmm.Monad: MkSelfLoopInfo :: Id -> RepArity -> [LocalReg] -> BlockId -> SelfLoopInfo
- GHC.StgToCmm.Monad: StgToCmmConfig :: !Profile -> Module -> !TempDir -> !SDocContext -> !Bool -> !Maybe Word -> !Int -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> (FMASign -> Bool) -> !Bool -> !Bool -> Maybe String -> !Bool -> !Bool -> !Bool -> StgToCmmConfig
+ GHC.StgToCmm.Monad: StgToCmmConfig :: Profile -> Module -> TempDir -> SDocContext -> Bool -> Maybe Word -> Int -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> (FMASign -> Bool) -> Bool -> Bool -> Bool -> Maybe String -> Bool -> Bool -> Bool -> StgToCmmConfig
- GHC.StgToCmm.Monad: [sli_arity] :: SelfLoopInfo -> !RepArity
+ GHC.StgToCmm.Monad: [sli_arity] :: SelfLoopInfo -> RepArity
- GHC.StgToCmm.Monad: [sli_header_block] :: SelfLoopInfo -> !BlockId
+ GHC.StgToCmm.Monad: [sli_header_block] :: SelfLoopInfo -> BlockId
- GHC.StgToCmm.Monad: [sli_id] :: SelfLoopInfo -> !Id
+ GHC.StgToCmm.Monad: [sli_id] :: SelfLoopInfo -> Id
- GHC.StgToCmm.Monad: [sli_registers] :: SelfLoopInfo -> ![LocalReg]
+ GHC.StgToCmm.Monad: [sli_registers] :: SelfLoopInfo -> [LocalReg]
- GHC.StgToCmm.Monad: [stgToCmmAlignCheck] :: StgToCmmConfig -> !Bool
+ GHC.StgToCmm.Monad: [stgToCmmAlignCheck] :: StgToCmmConfig -> Bool
- GHC.StgToCmm.Monad: [stgToCmmAllowArith64] :: StgToCmmConfig -> !Bool
+ GHC.StgToCmm.Monad: [stgToCmmAllowArith64] :: StgToCmmConfig -> Bool
- GHC.StgToCmm.Monad: [stgToCmmAllowExtendedAddSubInstrs] :: StgToCmmConfig -> !Bool
+ GHC.StgToCmm.Monad: [stgToCmmAllowExtendedAddSubInstrs] :: StgToCmmConfig -> Bool
- GHC.StgToCmm.Monad: [stgToCmmAllowIntMul2Instr] :: StgToCmmConfig -> !Bool
+ GHC.StgToCmm.Monad: [stgToCmmAllowIntMul2Instr] :: StgToCmmConfig -> Bool
- GHC.StgToCmm.Monad: [stgToCmmAllowQuot64] :: StgToCmmConfig -> !Bool
+ GHC.StgToCmm.Monad: [stgToCmmAllowQuot64] :: StgToCmmConfig -> Bool
- GHC.StgToCmm.Monad: [stgToCmmAllowQuotRem2] :: StgToCmmConfig -> !Bool
+ GHC.StgToCmm.Monad: [stgToCmmAllowQuotRem2] :: StgToCmmConfig -> Bool
- GHC.StgToCmm.Monad: [stgToCmmAllowQuotRemInstr] :: StgToCmmConfig -> !Bool
+ GHC.StgToCmm.Monad: [stgToCmmAllowQuotRemInstr] :: StgToCmmConfig -> Bool
- GHC.StgToCmm.Monad: [stgToCmmAllowWordMul2Instr] :: StgToCmmConfig -> !Bool
+ GHC.StgToCmm.Monad: [stgToCmmAllowWordMul2Instr] :: StgToCmmConfig -> Bool
- GHC.StgToCmm.Monad: [stgToCmmAvx2] :: StgToCmmConfig -> !Bool
+ GHC.StgToCmm.Monad: [stgToCmmAvx2] :: StgToCmmConfig -> Bool
- GHC.StgToCmm.Monad: [stgToCmmAvx512f] :: StgToCmmConfig -> !Bool
+ GHC.StgToCmm.Monad: [stgToCmmAvx512f] :: StgToCmmConfig -> Bool
- GHC.StgToCmm.Monad: [stgToCmmAvx] :: StgToCmmConfig -> !Bool
+ GHC.StgToCmm.Monad: [stgToCmmAvx] :: StgToCmmConfig -> Bool
- GHC.StgToCmm.Monad: [stgToCmmBinBlobThresh] :: StgToCmmConfig -> !Maybe Word
+ GHC.StgToCmm.Monad: [stgToCmmBinBlobThresh] :: StgToCmmConfig -> Maybe Word
- GHC.StgToCmm.Monad: [stgToCmmContext] :: StgToCmmConfig -> !SDocContext
+ GHC.StgToCmm.Monad: [stgToCmmContext] :: StgToCmmConfig -> SDocContext
- GHC.StgToCmm.Monad: [stgToCmmDoBoundsCheck] :: StgToCmmConfig -> !Bool
+ GHC.StgToCmm.Monad: [stgToCmmDoBoundsCheck] :: StgToCmmConfig -> Bool
- GHC.StgToCmm.Monad: [stgToCmmDoTagCheck] :: StgToCmmConfig -> !Bool
+ GHC.StgToCmm.Monad: [stgToCmmDoTagCheck] :: StgToCmmConfig -> Bool
- GHC.StgToCmm.Monad: [stgToCmmDoTicky] :: StgToCmmConfig -> !Bool
+ GHC.StgToCmm.Monad: [stgToCmmDoTicky] :: StgToCmmConfig -> Bool
- GHC.StgToCmm.Monad: [stgToCmmEagerBlackHole] :: StgToCmmConfig -> !Bool
+ GHC.StgToCmm.Monad: [stgToCmmEagerBlackHole] :: StgToCmmConfig -> Bool
- GHC.StgToCmm.Monad: [stgToCmmEmitDebugInfo] :: StgToCmmConfig -> !Bool
+ GHC.StgToCmm.Monad: [stgToCmmEmitDebugInfo] :: StgToCmmConfig -> Bool
- GHC.StgToCmm.Monad: [stgToCmmExtDynRefs] :: StgToCmmConfig -> !Bool
+ GHC.StgToCmm.Monad: [stgToCmmExtDynRefs] :: StgToCmmConfig -> Bool
- GHC.StgToCmm.Monad: [stgToCmmFastPAPCalls] :: StgToCmmConfig -> !Bool
+ GHC.StgToCmm.Monad: [stgToCmmFastPAPCalls] :: StgToCmmConfig -> Bool
- GHC.StgToCmm.Monad: [stgToCmmInfoTableMapWithFallback] :: StgToCmmConfig -> !Bool
+ GHC.StgToCmm.Monad: [stgToCmmInfoTableMapWithFallback] :: StgToCmmConfig -> Bool
- GHC.StgToCmm.Monad: [stgToCmmInfoTableMapWithStack] :: StgToCmmConfig -> !Bool
+ GHC.StgToCmm.Monad: [stgToCmmInfoTableMapWithStack] :: StgToCmmConfig -> Bool
- GHC.StgToCmm.Monad: [stgToCmmInfoTableMap] :: StgToCmmConfig -> !Bool
+ GHC.StgToCmm.Monad: [stgToCmmInfoTableMap] :: StgToCmmConfig -> Bool
- GHC.StgToCmm.Monad: [stgToCmmLoopification] :: StgToCmmConfig -> !Bool
+ GHC.StgToCmm.Monad: [stgToCmmLoopification] :: StgToCmmConfig -> Bool
- GHC.StgToCmm.Monad: [stgToCmmMaxInlAllocSize] :: StgToCmmConfig -> !Int
+ GHC.StgToCmm.Monad: [stgToCmmMaxInlAllocSize] :: StgToCmmConfig -> Int
- GHC.StgToCmm.Monad: [stgToCmmObjectDeterminism] :: StgToCmmConfig -> !Bool
+ GHC.StgToCmm.Monad: [stgToCmmObjectDeterminism] :: StgToCmmConfig -> Bool
- GHC.StgToCmm.Monad: [stgToCmmOmitIfPragmas] :: StgToCmmConfig -> !Bool
+ GHC.StgToCmm.Monad: [stgToCmmOmitIfPragmas] :: StgToCmmConfig -> Bool
- GHC.StgToCmm.Monad: [stgToCmmOmitYields] :: StgToCmmConfig -> !Bool
+ GHC.StgToCmm.Monad: [stgToCmmOmitYields] :: StgToCmmConfig -> Bool
- GHC.StgToCmm.Monad: [stgToCmmOrigThunkInfo] :: StgToCmmConfig -> !Bool
+ GHC.StgToCmm.Monad: [stgToCmmOrigThunkInfo] :: StgToCmmConfig -> Bool
- GHC.StgToCmm.Monad: [stgToCmmPIC] :: StgToCmmConfig -> !Bool
+ GHC.StgToCmm.Monad: [stgToCmmPIC] :: StgToCmmConfig -> Bool
- GHC.StgToCmm.Monad: [stgToCmmPIE] :: StgToCmmConfig -> !Bool
+ GHC.StgToCmm.Monad: [stgToCmmPIE] :: StgToCmmConfig -> Bool
- GHC.StgToCmm.Monad: [stgToCmmProfile] :: StgToCmmConfig -> !Profile
+ GHC.StgToCmm.Monad: [stgToCmmProfile] :: StgToCmmConfig -> Profile
- GHC.StgToCmm.Monad: [stgToCmmSCCProfiling] :: StgToCmmConfig -> !Bool
+ GHC.StgToCmm.Monad: [stgToCmmSCCProfiling] :: StgToCmmConfig -> Bool
- GHC.StgToCmm.Monad: [stgToCmmSaveFCallTargetToLocal] :: StgToCmmConfig -> !Bool
+ GHC.StgToCmm.Monad: [stgToCmmSaveFCallTargetToLocal] :: StgToCmmConfig -> Bool
- GHC.StgToCmm.Monad: [stgToCmmTickyAP] :: StgToCmmConfig -> !Bool
+ GHC.StgToCmm.Monad: [stgToCmmTickyAP] :: StgToCmmConfig -> Bool
- GHC.StgToCmm.Monad: [stgToCmmTickyAllocd] :: StgToCmmConfig -> !Bool
+ GHC.StgToCmm.Monad: [stgToCmmTickyAllocd] :: StgToCmmConfig -> Bool
- GHC.StgToCmm.Monad: [stgToCmmTickyDynThunk] :: StgToCmmConfig -> !Bool
+ GHC.StgToCmm.Monad: [stgToCmmTickyDynThunk] :: StgToCmmConfig -> Bool
- GHC.StgToCmm.Monad: [stgToCmmTickyLNE] :: StgToCmmConfig -> !Bool
+ GHC.StgToCmm.Monad: [stgToCmmTickyLNE] :: StgToCmmConfig -> Bool
- GHC.StgToCmm.Monad: [stgToCmmTickyTag] :: StgToCmmConfig -> !Bool
+ GHC.StgToCmm.Monad: [stgToCmmTickyTag] :: StgToCmmConfig -> Bool
- GHC.StgToCmm.Monad: [stgToCmmTmpDir] :: StgToCmmConfig -> !TempDir
+ GHC.StgToCmm.Monad: [stgToCmmTmpDir] :: StgToCmmConfig -> TempDir
- GHC.StgToCmm.Sequel: MkSelfLoopInfo :: !Id -> !RepArity -> ![LocalReg] -> !BlockId -> SelfLoopInfo
+ GHC.StgToCmm.Sequel: MkSelfLoopInfo :: Id -> RepArity -> [LocalReg] -> BlockId -> SelfLoopInfo
- GHC.StgToCmm.Sequel: [sli_arity] :: SelfLoopInfo -> !RepArity
+ GHC.StgToCmm.Sequel: [sli_arity] :: SelfLoopInfo -> RepArity
- GHC.StgToCmm.Sequel: [sli_header_block] :: SelfLoopInfo -> !BlockId
+ GHC.StgToCmm.Sequel: [sli_header_block] :: SelfLoopInfo -> BlockId
- GHC.StgToCmm.Sequel: [sli_id] :: SelfLoopInfo -> !Id
+ GHC.StgToCmm.Sequel: [sli_id] :: SelfLoopInfo -> Id
- GHC.StgToCmm.Sequel: [sli_registers] :: SelfLoopInfo -> ![LocalReg]
+ GHC.StgToCmm.Sequel: [sli_registers] :: SelfLoopInfo -> [LocalReg]
- GHC.StgToCmm.Types: ApThunk :: !RepArity -> StandardFormInfo
+ GHC.StgToCmm.Types: ApThunk :: RepArity -> StandardFormInfo
- GHC.StgToCmm.Types: CmmCgInfos :: !NonCaffySet -> !ModuleLFInfos -> !CStub -> CmmCgInfos
+ GHC.StgToCmm.Types: CmmCgInfos :: NonCaffySet -> ModuleLFInfos -> CStub -> CmmCgInfos
- GHC.StgToCmm.Types: LFCon :: !DataCon -> LambdaFormInfo
+ GHC.StgToCmm.Types: LFCon :: DataCon -> LambdaFormInfo
- GHC.StgToCmm.Types: LFReEntrant :: !TopLevelFlag -> !RepArity -> !Bool -> !ArgDescr -> LambdaFormInfo
+ GHC.StgToCmm.Types: LFReEntrant :: TopLevelFlag -> RepArity -> Bool -> ArgDescr -> LambdaFormInfo
- GHC.StgToCmm.Types: LFThunk :: !TopLevelFlag -> !Bool -> !Bool -> !StandardFormInfo -> !Bool -> LambdaFormInfo
+ GHC.StgToCmm.Types: LFThunk :: TopLevelFlag -> Bool -> Bool -> StandardFormInfo -> Bool -> LambdaFormInfo
- GHC.StgToCmm.Types: LFUnknown :: !Bool -> LambdaFormInfo
+ GHC.StgToCmm.Types: LFUnknown :: Bool -> LambdaFormInfo
- GHC.StgToCmm.Types: SelectorThunk :: !WordOff -> StandardFormInfo
+ GHC.StgToCmm.Types: SelectorThunk :: WordOff -> StandardFormInfo
- GHC.StgToCmm.Types: [cgIPEStub] :: CmmCgInfos -> !CStub
+ GHC.StgToCmm.Types: [cgIPEStub] :: CmmCgInfos -> CStub
- GHC.StgToCmm.Types: [cgLFInfos] :: CmmCgInfos -> !ModuleLFInfos
+ GHC.StgToCmm.Types: [cgLFInfos] :: CmmCgInfos -> ModuleLFInfos
- GHC.StgToCmm.Types: [cgNonCafs] :: CmmCgInfos -> !NonCaffySet
+ GHC.StgToCmm.Types: [cgNonCafs] :: CmmCgInfos -> NonCaffySet
- GHC.StgToCmm.Utils: IPEStats :: !Int -> !IntMap Int -> !Int -> !Int -> IPEStats
+ GHC.StgToCmm.Utils: IPEStats :: Int -> IntMap Int -> Int -> Int -> IPEStats
- GHC.StgToCmm.Utils: [ipe_closure_types] :: IPEStats -> !IntMap Int
+ GHC.StgToCmm.Utils: [ipe_closure_types] :: IPEStats -> IntMap Int
- GHC.StgToCmm.Utils: [ipe_fallback] :: IPEStats -> !Int
+ GHC.StgToCmm.Utils: [ipe_fallback] :: IPEStats -> Int
- GHC.StgToCmm.Utils: [ipe_skipped] :: IPEStats -> !Int
+ GHC.StgToCmm.Utils: [ipe_skipped] :: IPEStats -> Int
- GHC.StgToCmm.Utils: [ipe_total] :: IPEStats -> !Int
+ GHC.StgToCmm.Utils: [ipe_total] :: IPEStats -> Int
- GHC.StgToJS.Linker.Linker: LinkPlan :: Map Module LocatedBlockInfo -> Set BlockRef -> !Set FilePath -> !Set FilePath -> !Set FilePath -> LinkPlan
+ GHC.StgToJS.Linker.Linker: LinkPlan :: Map Module LocatedBlockInfo -> Set BlockRef -> Set FilePath -> Set FilePath -> Set FilePath -> LinkPlan
- GHC.StgToJS.Linker.Linker: [lkp_archives] :: LinkPlan -> !Set FilePath
+ GHC.StgToJS.Linker.Linker: [lkp_archives] :: LinkPlan -> Set FilePath
- GHC.StgToJS.Linker.Linker: [lkp_objs_cc] :: LinkPlan -> !Set FilePath
+ GHC.StgToJS.Linker.Linker: [lkp_objs_cc] :: LinkPlan -> Set FilePath
- GHC.StgToJS.Linker.Linker: [lkp_objs_js] :: LinkPlan -> !Set FilePath
+ GHC.StgToJS.Linker.Linker: [lkp_objs_js] :: LinkPlan -> Set FilePath
- GHC.StgToJS.Linker.Types: JSLinkConfig :: !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> JSLinkConfig
+ GHC.StgToJS.Linker.Types: JSLinkConfig :: Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> JSLinkConfig
- GHC.StgToJS.Linker.Types: LinkPlan :: Map Module LocatedBlockInfo -> Set BlockRef -> !Set FilePath -> !Set FilePath -> !Set FilePath -> LinkPlan
+ GHC.StgToJS.Linker.Types: LinkPlan :: Map Module LocatedBlockInfo -> Set BlockRef -> Set FilePath -> Set FilePath -> Set FilePath -> LinkPlan
- GHC.StgToJS.Linker.Types: [lcCombineAll] :: JSLinkConfig -> !Bool
+ GHC.StgToJS.Linker.Types: [lcCombineAll] :: JSLinkConfig -> Bool
- GHC.StgToJS.Linker.Types: [lcForceEmccRts] :: JSLinkConfig -> !Bool
+ GHC.StgToJS.Linker.Types: [lcForceEmccRts] :: JSLinkConfig -> Bool
- GHC.StgToJS.Linker.Types: [lcForeignRefs] :: JSLinkConfig -> !Bool
+ GHC.StgToJS.Linker.Types: [lcForeignRefs] :: JSLinkConfig -> Bool
- GHC.StgToJS.Linker.Types: [lcLinkCsources] :: JSLinkConfig -> !Bool
+ GHC.StgToJS.Linker.Types: [lcLinkCsources] :: JSLinkConfig -> Bool
- GHC.StgToJS.Linker.Types: [lcNoHsMain] :: JSLinkConfig -> !Bool
+ GHC.StgToJS.Linker.Types: [lcNoHsMain] :: JSLinkConfig -> Bool
- GHC.StgToJS.Linker.Types: [lcNoJSExecutables] :: JSLinkConfig -> !Bool
+ GHC.StgToJS.Linker.Types: [lcNoJSExecutables] :: JSLinkConfig -> Bool
- GHC.StgToJS.Linker.Types: [lcNoRts] :: JSLinkConfig -> !Bool
+ GHC.StgToJS.Linker.Types: [lcNoRts] :: JSLinkConfig -> Bool
- GHC.StgToJS.Linker.Types: [lcNoStats] :: JSLinkConfig -> !Bool
+ GHC.StgToJS.Linker.Types: [lcNoStats] :: JSLinkConfig -> Bool
- GHC.StgToJS.Linker.Types: [lkp_archives] :: LinkPlan -> !Set FilePath
+ GHC.StgToJS.Linker.Types: [lkp_archives] :: LinkPlan -> Set FilePath
- GHC.StgToJS.Linker.Types: [lkp_objs_cc] :: LinkPlan -> !Set FilePath
+ GHC.StgToJS.Linker.Types: [lkp_objs_cc] :: LinkPlan -> Set FilePath
- GHC.StgToJS.Linker.Types: [lkp_objs_js] :: LinkPlan -> !Set FilePath
+ GHC.StgToJS.Linker.Types: [lkp_objs_js] :: LinkPlan -> Set FilePath
- GHC.StgToJS.Monad: GlobalOcc :: !Ident -> !Id -> !Word -> GlobalOcc
+ GHC.StgToJS.Monad: GlobalOcc :: Id -> Word -> GlobalOcc
- GHC.StgToJS.Monad: [global_count] :: GlobalOcc -> !Word
+ GHC.StgToJS.Monad: [global_count] :: GlobalOcc -> Word
- GHC.StgToJS.Monad: [global_id] :: GlobalOcc -> !Id
+ GHC.StgToJS.Monad: [global_id] :: GlobalOcc -> Id
- GHC.StgToJS.Monad: globalOccs :: JStgStat -> G [GlobalOcc]
+ GHC.StgToJS.Monad: globalOccs :: JStgStat -> G (UniqFM Id GlobalOcc)
- GHC.StgToJS.Object: BlockInfo :: !Module -> !BlockIds -> !Map ExportedFun BlockId -> !Array BlockId BlockDeps -> BlockInfo
+ GHC.StgToJS.Object: BlockInfo :: Module -> BlockIds -> Map ExportedFun BlockId -> Array BlockId BlockDeps -> BlockInfo
- GHC.StgToJS.Object: BlockRef :: !Module -> !BlockId -> BlockRef
+ GHC.StgToJS.Object: BlockRef :: Module -> BlockId -> BlockRef
- GHC.StgToJS.Object: ExportedFun :: !Module -> !LexicalFastString -> ExportedFun
+ GHC.StgToJS.Object: ExportedFun :: Module -> LexicalFastString -> ExportedFun
- GHC.StgToJS.Object: IndexEntry :: ![FastString] -> !Bin ObjBlock -> IndexEntry
+ GHC.StgToJS.Object: IndexEntry :: [FastString] -> Bin ObjBlock -> IndexEntry
- GHC.StgToJS.Object: JSOptions :: !Bool -> ![String] -> ![String] -> ![String] -> JSOptions
+ GHC.StgToJS.Object: JSOptions :: Bool -> [String] -> [String] -> [String] -> JSOptions
- GHC.StgToJS.Object: LocatedBlockInfo :: !BlockLocation -> !BlockInfo -> LocatedBlockInfo
+ GHC.StgToJS.Object: LocatedBlockInfo :: BlockLocation -> BlockInfo -> LocatedBlockInfo
- GHC.StgToJS.Object: Object :: !ModuleName -> !ReadBinHandle -> !Bin ObjBlock -> !BlockInfo -> !Index -> Object
+ GHC.StgToJS.Object: Object :: ModuleName -> ReadBinHandle -> Bin ObjBlock -> BlockInfo -> Index -> Object
- GHC.StgToJS.Object: [bi_block_deps] :: BlockInfo -> !Array BlockId BlockDeps
+ GHC.StgToJS.Object: [bi_block_deps] :: BlockInfo -> Array BlockId BlockDeps
- GHC.StgToJS.Object: [bi_exports] :: BlockInfo -> !Map ExportedFun BlockId
+ GHC.StgToJS.Object: [bi_exports] :: BlockInfo -> Map ExportedFun BlockId
- GHC.StgToJS.Object: [bi_module] :: BlockInfo -> !Module
+ GHC.StgToJS.Object: [bi_module] :: BlockInfo -> Module
- GHC.StgToJS.Object: [bi_must_link] :: BlockInfo -> !BlockIds
+ GHC.StgToJS.Object: [bi_must_link] :: BlockInfo -> BlockIds
- GHC.StgToJS.Object: [block_ref_idx] :: BlockRef -> !BlockId
+ GHC.StgToJS.Object: [block_ref_idx] :: BlockRef -> BlockId
- GHC.StgToJS.Object: [block_ref_mod] :: BlockRef -> !Module
+ GHC.StgToJS.Object: [block_ref_mod] :: BlockRef -> Module
- GHC.StgToJS.Object: [emccExportedFunctions] :: JSOptions -> ![String]
+ GHC.StgToJS.Object: [emccExportedFunctions] :: JSOptions -> [String]
- GHC.StgToJS.Object: [emccExportedRuntimeMethods] :: JSOptions -> ![String]
+ GHC.StgToJS.Object: [emccExportedRuntimeMethods] :: JSOptions -> [String]
- GHC.StgToJS.Object: [emccExtraOptions] :: JSOptions -> ![String]
+ GHC.StgToJS.Object: [emccExtraOptions] :: JSOptions -> [String]
- GHC.StgToJS.Object: [enableCPP] :: JSOptions -> !Bool
+ GHC.StgToJS.Object: [enableCPP] :: JSOptions -> Bool
- GHC.StgToJS.Object: [funModule] :: ExportedFun -> !Module
+ GHC.StgToJS.Object: [funModule] :: ExportedFun -> Module
- GHC.StgToJS.Object: [funSymbol] :: ExportedFun -> !LexicalFastString
+ GHC.StgToJS.Object: [funSymbol] :: ExportedFun -> LexicalFastString
- GHC.StgToJS.Object: [idxOffset] :: IndexEntry -> !Bin ObjBlock
+ GHC.StgToJS.Object: [idxOffset] :: IndexEntry -> Bin ObjBlock
- GHC.StgToJS.Object: [idxSymbols] :: IndexEntry -> ![FastString]
+ GHC.StgToJS.Object: [idxSymbols] :: IndexEntry -> [FastString]
- GHC.StgToJS.Object: [lbi_info] :: LocatedBlockInfo -> !BlockInfo
+ GHC.StgToJS.Object: [lbi_info] :: LocatedBlockInfo -> BlockInfo
- GHC.StgToJS.Object: [lbi_loc] :: LocatedBlockInfo -> !BlockLocation
+ GHC.StgToJS.Object: [lbi_loc] :: LocatedBlockInfo -> BlockLocation
- GHC.StgToJS.Object: [objBlockInfo] :: Object -> !BlockInfo
+ GHC.StgToJS.Object: [objBlockInfo] :: Object -> BlockInfo
- GHC.StgToJS.Object: [objHandle] :: Object -> !ReadBinHandle
+ GHC.StgToJS.Object: [objHandle] :: Object -> ReadBinHandle
- GHC.StgToJS.Object: [objIndex] :: Object -> !Index
+ GHC.StgToJS.Object: [objIndex] :: Object -> Index
- GHC.StgToJS.Object: [objModuleName] :: Object -> !ModuleName
+ GHC.StgToJS.Object: [objModuleName] :: Object -> ModuleName
- GHC.StgToJS.Object: [objPayloadOffset] :: Object -> !Bin ObjBlock
+ GHC.StgToJS.Object: [objPayloadOffset] :: Object -> Bin ObjBlock
- GHC.StgToJS.Types: BinLit :: !ByteString -> StaticLit
+ GHC.StgToJS.Types: BinLit :: ByteString -> StaticLit
- GHC.StgToJS.Types: BoolLit :: !Bool -> StaticLit
+ GHC.StgToJS.Types: BoolLit :: Bool -> StaticLit
- GHC.StgToJS.Types: CICon :: !Int -> CIType
+ GHC.StgToJS.Types: CICon :: Int -> CIType
- GHC.StgToJS.Types: CIFun :: !Int -> !Int -> CIType
+ GHC.StgToJS.Types: CIFun :: Int -> Int -> CIType
- GHC.StgToJS.Types: CILayoutFixed :: !Int -> [JSRep] -> CILayout
+ GHC.StgToJS.Types: CILayoutFixed :: Int -> [JSRep] -> CILayout
- GHC.StgToJS.Types: CILayoutUnknown :: !Int -> CILayout
+ GHC.StgToJS.Types: CILayoutUnknown :: Int -> CILayout
- GHC.StgToJS.Types: DoubleLit :: !SaneDouble -> StaticLit
+ GHC.StgToJS.Types: DoubleLit :: SaneDouble -> StaticLit
- GHC.StgToJS.Types: ExpFun :: !Bool -> [JSFFIType] -> !JSFFIType -> ExpFun
+ GHC.StgToJS.Types: ExpFun :: Bool -> [JSFFIType] -> JSFFIType -> ExpFun
- GHC.StgToJS.Types: ForeignJSRef :: !FastString -> !FastString -> !Safety -> !CCallConv -> ![FastString] -> !FastString -> ForeignJSRef
+ GHC.StgToJS.Types: ForeignJSRef :: FastString -> FastString -> Safety -> CCallConv -> [FastString] -> FastString -> ForeignJSRef
- GHC.StgToJS.Types: GenState :: !StgToJSConfig -> !Module -> {-# UNPACK #-} !FastMutInt -> !IdCache -> !UniqFM Id CgStgExpr -> GenGroupState -> [JStgStat] -> GenState
+ GHC.StgToJS.Types: GenState :: StgToJSConfig -> Module -> FastMutInt -> IdCache -> UniqFM Id CgStgExpr -> GenGroupState -> [JStgStat] -> GenState
- GHC.StgToJS.Types: IdKey :: !Word64 -> !Int -> !IdType -> IdKey
+ GHC.StgToJS.Types: IdKey :: Word64 -> Int -> IdType -> IdKey
- GHC.StgToJS.Types: IntLit :: !Integer -> StaticLit
+ GHC.StgToJS.Types: IntLit :: Integer -> StaticLit
- GHC.StgToJS.Types: LabelLit :: !Bool -> !FastString -> StaticLit
+ GHC.StgToJS.Types: LabelLit :: Bool -> FastString -> StaticLit
- GHC.StgToJS.Types: ObjBlock :: ![FastString] -> ![ClosureInfo] -> ![StaticInfo] -> JStat -> !ByteString -> ![ExpFun] -> ![ForeignJSRef] -> ObjBlock
+ GHC.StgToJS.Types: ObjBlock :: [FastString] -> [ClosureInfo] -> [StaticInfo] -> JStat -> ByteString -> [ExpFun] -> [ForeignJSRef] -> ObjBlock
- GHC.StgToJS.Types: OtherSymb :: !Module -> !FastString -> OtherSymb
+ GHC.StgToJS.Types: OtherSymb :: Module -> FastString -> OtherSymb
- GHC.StgToJS.Types: SlotId :: !Id -> !Int -> StackSlot
+ GHC.StgToJS.Types: SlotId :: Id -> Int -> StackSlot
- GHC.StgToJS.Types: StaticConArg :: !FastString -> [StaticArg] -> StaticArg
+ GHC.StgToJS.Types: StaticConArg :: FastString -> [StaticArg] -> StaticArg
- GHC.StgToJS.Types: StaticInfo :: !FastString -> !StaticVal -> !Maybe Ident -> StaticInfo
+ GHC.StgToJS.Types: StaticInfo :: FastString -> StaticVal -> Maybe Ident -> StaticInfo
- GHC.StgToJS.Types: StaticLitArg :: !StaticLit -> StaticArg
+ GHC.StgToJS.Types: StaticLitArg :: StaticLit -> StaticArg
- GHC.StgToJS.Types: StaticObjArg :: !FastString -> StaticArg
+ GHC.StgToJS.Types: StaticObjArg :: FastString -> StaticArg
- GHC.StgToJS.Types: StaticUnboxed :: !StaticUnboxed -> StaticVal
+ GHC.StgToJS.Types: StaticUnboxed :: StaticUnboxed -> StaticVal
- GHC.StgToJS.Types: StaticUnboxedBool :: !Bool -> StaticUnboxed
+ GHC.StgToJS.Types: StaticUnboxedBool :: Bool -> StaticUnboxed
- GHC.StgToJS.Types: StaticUnboxedDouble :: !SaneDouble -> StaticUnboxed
+ GHC.StgToJS.Types: StaticUnboxedDouble :: SaneDouble -> StaticUnboxed
- GHC.StgToJS.Types: StaticUnboxedInt :: !Integer -> StaticUnboxed
+ GHC.StgToJS.Types: StaticUnboxedInt :: Integer -> StaticUnboxed
- GHC.StgToJS.Types: StaticUnboxedString :: !ByteString -> StaticUnboxed
+ GHC.StgToJS.Types: StaticUnboxedString :: ByteString -> StaticUnboxed
- GHC.StgToJS.Types: StaticUnboxedStringOffset :: !ByteString -> StaticUnboxed
+ GHC.StgToJS.Types: StaticUnboxedStringOffset :: ByteString -> StaticUnboxed
- GHC.StgToJS.Types: StgToJSConfig :: !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !SDocContext -> !LinkerConfig -> StgToJSConfig
+ GHC.StgToJS.Types: StgToJSConfig :: Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> SDocContext -> LinkerConfig -> StgToJSConfig
- GHC.StgToJS.Types: StringLit :: !FastString -> StaticLit
+ GHC.StgToJS.Types: StringLit :: FastString -> StaticLit
- GHC.StgToJS.Types: TypedExpr :: !PrimRep -> [JStgExpr] -> TypedExpr
+ GHC.StgToJS.Types: TypedExpr :: PrimRep -> [JStgExpr] -> TypedExpr
- GHC.StgToJS.Types: [citArity] :: CIType -> !Int
+ GHC.StgToJS.Types: [citArity] :: CIType -> Int
- GHC.StgToJS.Types: [citConstructor] :: CIType -> !Int
+ GHC.StgToJS.Types: [citConstructor] :: CIType -> Int
- GHC.StgToJS.Types: [citRegs] :: CIType -> !Int
+ GHC.StgToJS.Types: [citRegs] :: CIType -> Int
- GHC.StgToJS.Types: [csAssertRts] :: StgToJSConfig -> !Bool
+ GHC.StgToJS.Types: [csAssertRts] :: StgToJSConfig -> Bool
- GHC.StgToJS.Types: [csBoundsCheck] :: StgToJSConfig -> !Bool
+ GHC.StgToJS.Types: [csBoundsCheck] :: StgToJSConfig -> Bool
- GHC.StgToJS.Types: [csContext] :: StgToJSConfig -> !SDocContext
+ GHC.StgToJS.Types: [csContext] :: StgToJSConfig -> SDocContext
- GHC.StgToJS.Types: [csDebugAlloc] :: StgToJSConfig -> !Bool
+ GHC.StgToJS.Types: [csDebugAlloc] :: StgToJSConfig -> Bool
- GHC.StgToJS.Types: [csInlineAlloc] :: StgToJSConfig -> !Bool
+ GHC.StgToJS.Types: [csInlineAlloc] :: StgToJSConfig -> Bool
- GHC.StgToJS.Types: [csInlineBlackhole] :: StgToJSConfig -> !Bool
+ GHC.StgToJS.Types: [csInlineBlackhole] :: StgToJSConfig -> Bool
- GHC.StgToJS.Types: [csInlineEnter] :: StgToJSConfig -> !Bool
+ GHC.StgToJS.Types: [csInlineEnter] :: StgToJSConfig -> Bool
- GHC.StgToJS.Types: [csInlineLoadRegs] :: StgToJSConfig -> !Bool
+ GHC.StgToJS.Types: [csInlineLoadRegs] :: StgToJSConfig -> Bool
- GHC.StgToJS.Types: [csInlinePush] :: StgToJSConfig -> !Bool
+ GHC.StgToJS.Types: [csInlinePush] :: StgToJSConfig -> Bool
- GHC.StgToJS.Types: [csLinkerConfig] :: StgToJSConfig -> !LinkerConfig
+ GHC.StgToJS.Types: [csLinkerConfig] :: StgToJSConfig -> LinkerConfig
- GHC.StgToJS.Types: [csPrettyRender] :: StgToJSConfig -> !Bool
+ GHC.StgToJS.Types: [csPrettyRender] :: StgToJSConfig -> Bool
- GHC.StgToJS.Types: [csProf] :: StgToJSConfig -> !Bool
+ GHC.StgToJS.Types: [csProf] :: StgToJSConfig -> Bool
- GHC.StgToJS.Types: [csRuntimeAssert] :: StgToJSConfig -> !Bool
+ GHC.StgToJS.Types: [csRuntimeAssert] :: StgToJSConfig -> Bool
- GHC.StgToJS.Types: [csTraceForeign] :: StgToJSConfig -> !Bool
+ GHC.StgToJS.Types: [csTraceForeign] :: StgToJSConfig -> Bool
- GHC.StgToJS.Types: [csTraceRts] :: StgToJSConfig -> !Bool
+ GHC.StgToJS.Types: [csTraceRts] :: StgToJSConfig -> Bool
- GHC.StgToJS.Types: [foreignRefArgs] :: ForeignJSRef -> ![FastString]
+ GHC.StgToJS.Types: [foreignRefArgs] :: ForeignJSRef -> [FastString]
- GHC.StgToJS.Types: [foreignRefCConv] :: ForeignJSRef -> !CCallConv
+ GHC.StgToJS.Types: [foreignRefCConv] :: ForeignJSRef -> CCallConv
- GHC.StgToJS.Types: [foreignRefPattern] :: ForeignJSRef -> !FastString
+ GHC.StgToJS.Types: [foreignRefPattern] :: ForeignJSRef -> FastString
- GHC.StgToJS.Types: [foreignRefResult] :: ForeignJSRef -> !FastString
+ GHC.StgToJS.Types: [foreignRefResult] :: ForeignJSRef -> FastString
- GHC.StgToJS.Types: [foreignRefSafety] :: ForeignJSRef -> !Safety
+ GHC.StgToJS.Types: [foreignRefSafety] :: ForeignJSRef -> Safety
- GHC.StgToJS.Types: [foreignRefSrcSpan] :: ForeignJSRef -> !FastString
+ GHC.StgToJS.Types: [foreignRefSrcSpan] :: ForeignJSRef -> FastString
- GHC.StgToJS.Types: [gsId] :: GenState -> {-# UNPACK #-} !FastMutInt
+ GHC.StgToJS.Types: [gsId] :: GenState -> FastMutInt
- GHC.StgToJS.Types: [gsIdents] :: GenState -> !IdCache
+ GHC.StgToJS.Types: [gsIdents] :: GenState -> IdCache
- GHC.StgToJS.Types: [gsModule] :: GenState -> !Module
+ GHC.StgToJS.Types: [gsModule] :: GenState -> Module
- GHC.StgToJS.Types: [gsSettings] :: GenState -> !StgToJSConfig
+ GHC.StgToJS.Types: [gsSettings] :: GenState -> StgToJSConfig
- GHC.StgToJS.Types: [gsUnfloated] :: GenState -> !UniqFM Id CgStgExpr
+ GHC.StgToJS.Types: [gsUnfloated] :: GenState -> UniqFM Id CgStgExpr
- GHC.StgToJS.Types: [isIO] :: ExpFun -> !Bool
+ GHC.StgToJS.Types: [isIO] :: ExpFun -> Bool
- GHC.StgToJS.Types: [layoutSize] :: CILayout -> !Int
+ GHC.StgToJS.Types: [layoutSize] :: CILayout -> Int
- GHC.StgToJS.Types: [oiClInfo] :: ObjBlock -> ![ClosureInfo]
+ GHC.StgToJS.Types: [oiClInfo] :: ObjBlock -> [ClosureInfo]
- GHC.StgToJS.Types: [oiFExports] :: ObjBlock -> ![ExpFun]
+ GHC.StgToJS.Types: [oiFExports] :: ObjBlock -> [ExpFun]
- GHC.StgToJS.Types: [oiFImports] :: ObjBlock -> ![ForeignJSRef]
+ GHC.StgToJS.Types: [oiFImports] :: ObjBlock -> [ForeignJSRef]
- GHC.StgToJS.Types: [oiRaw] :: ObjBlock -> !ByteString
+ GHC.StgToJS.Types: [oiRaw] :: ObjBlock -> ByteString
- GHC.StgToJS.Types: [oiStatic] :: ObjBlock -> ![StaticInfo]
+ GHC.StgToJS.Types: [oiStatic] :: ObjBlock -> [StaticInfo]
- GHC.StgToJS.Types: [oiSymbols] :: ObjBlock -> ![FastString]
+ GHC.StgToJS.Types: [oiSymbols] :: ObjBlock -> [FastString]
- GHC.StgToJS.Types: [result] :: ExpFun -> !JSFFIType
+ GHC.StgToJS.Types: [result] :: ExpFun -> JSFFIType
- GHC.StgToJS.Types: [siCC] :: StaticInfo -> !Maybe Ident
+ GHC.StgToJS.Types: [siCC] :: StaticInfo -> Maybe Ident
- GHC.StgToJS.Types: [siVal] :: StaticInfo -> !StaticVal
+ GHC.StgToJS.Types: [siVal] :: StaticInfo -> StaticVal
- GHC.StgToJS.Types: [siVar] :: StaticInfo -> !FastString
+ GHC.StgToJS.Types: [siVar] :: StaticInfo -> FastString
- GHC.StgToJS.Types: [typex_typ] :: TypedExpr -> !PrimRep
+ GHC.StgToJS.Types: [typex_typ] :: TypedExpr -> PrimRep
- GHC.SysTools.Cpp: CppOpts :: !SourceCodePreprocessor -> !Bool -> CppOpts
+ GHC.SysTools.Cpp: CppOpts :: SourceCodePreprocessor -> Bool -> CppOpts
- GHC.SysTools.Cpp: [cppLinePragmas] :: CppOpts -> !Bool
+ GHC.SysTools.Cpp: [cppLinePragmas] :: CppOpts -> Bool
- GHC.SysTools.Cpp: [sourceCodePreprocessor] :: CppOpts -> !SourceCodePreprocessor
+ GHC.SysTools.Cpp: [sourceCodePreprocessor] :: CppOpts -> SourceCodePreprocessor
- GHC.SysTools.Cpp: getGhcVersionPathName :: DynFlags -> UnitEnv -> IO FilePath
+ GHC.SysTools.Cpp: getGhcVersionPathName :: DynFlags -> UnitEnv -> IO (Maybe FilePath)
- GHC.SysTools.Process: runSomethingFiltered :: Logger -> (String -> String) -> String -> String -> [Option] -> Maybe FilePath -> Maybe [(String, String)] -> IO ()
+ GHC.SysTools.Process: runSomethingFiltered :: Logger -> ([String] -> [String]) -> String -> String -> [Option] -> Maybe FilePath -> Maybe [(String, String)] -> IO ()
- GHC.SysTools.Process: runSomethingResponseFile :: Logger -> TmpFs -> TempDir -> (String -> String) -> String -> String -> [Option] -> Maybe [(String, String)] -> IO ()
+ GHC.SysTools.Process: runSomethingResponseFile :: Logger -> TmpFs -> TempDir -> ([String] -> [String]) -> String -> String -> [Option] -> Maybe [(String, String)] -> IO ()
- GHC.Tc.Deriv: DerivInfo :: TyCon -> ![(Name, TyVar)] -> [LHsDerivingClause GhcRn] -> SDoc -> DerivInfo
+ GHC.Tc.Deriv: DerivInfo :: TyCon -> [(Name, TyVar)] -> [LHsDerivingClause GhcRn] -> ErrCtxtMsg -> DerivInfo
- GHC.Tc.Deriv: [di_ctxt] :: DerivInfo -> SDoc
+ GHC.Tc.Deriv: [di_ctxt] :: DerivInfo -> ErrCtxtMsg
- GHC.Tc.Deriv: [di_scoped_tvs] :: DerivInfo -> ![(Name, TyVar)]
+ GHC.Tc.Deriv: [di_scoped_tvs] :: DerivInfo -> [(Name, TyVar)]
- GHC.Tc.Deriv.Infer: inferConstraints :: DerivSpecMechanism -> DerivM (ThetaSpec, [TyVar], [TcType], DerivSpecMechanism)
+ GHC.Tc.Deriv.Infer: inferConstraints :: DerivSpecMechanism -> DerivEnv -> DerivM (ThetaSpec, [TyVar], [TcType], DerivSpecMechanism)
- GHC.Tc.Deriv.Utils: StockClassError :: !DeriveInstanceErrReason -> OriginativeDerivStatus
+ GHC.Tc.Deriv.Utils: StockClassError :: DeriveInstanceErrReason -> OriginativeDerivStatus
- GHC.Tc.Deriv.Utils: isStandaloneWildcardDeriv :: DerivM Bool
+ GHC.Tc.Deriv.Utils: isStandaloneWildcardDeriv :: DerivContext -> Bool
- GHC.Tc.Errors.Hole: sortHoleFitsByGraph :: [HoleFit] -> TcM [HoleFit]
+ GHC.Tc.Errors.Hole: sortHoleFitsByGraph :: [TcHoleFit] -> TcM [TcHoleFit]
- GHC.Tc.Errors.Hole: sortHoleFitsBySize :: [HoleFit] -> TcM [HoleFit]
+ GHC.Tc.Errors.Hole: sortHoleFitsBySize :: [TcHoleFit] -> TcM [TcHoleFit]
- GHC.Tc.Errors.Hole: tcFilterHoleFits :: Maybe Int -> TypedHole -> (TcType, [TcTyVar]) -> [HoleFitCandidate] -> TcM (Bool, [HoleFit])
+ GHC.Tc.Errors.Hole: tcFilterHoleFits :: Maybe Int -> TypedHole -> (TcType, [TcTyVar]) -> [HoleFitCandidate] -> TcM (Bool, [TcHoleFit])
- GHC.Tc.Errors.Hole: zonkSubs :: TidyEnv -> [HoleFit] -> ZonkM (TidyEnv, [HoleFit])
+ GHC.Tc.Errors.Hole: zonkSubs :: TidyEnv -> [TcHoleFit] -> ZonkM (TidyEnv, [TcHoleFit])
- GHC.Tc.Errors.Hole.FitTypes: HoleFit :: Id -> HoleFitCandidate -> TcType -> Int -> [TcType] -> [TcType] -> Maybe [HsDocString] -> HoleFit
+ GHC.Tc.Errors.Hole.FitTypes: HoleFit :: Id -> HoleFitCandidate -> TcType -> Int -> [TcType] -> [TcType] -> Maybe [HsDocString] -> TcHoleFit
- GHC.Tc.Errors.Hole.FitTypes: [hfCand] :: HoleFit -> HoleFitCandidate
+ GHC.Tc.Errors.Hole.FitTypes: [hfCand] :: TcHoleFit -> HoleFitCandidate
- GHC.Tc.Errors.Hole.FitTypes: [hfDoc] :: HoleFit -> Maybe [HsDocString]
+ GHC.Tc.Errors.Hole.FitTypes: [hfDoc] :: TcHoleFit -> Maybe [HsDocString]
- GHC.Tc.Errors.Hole.FitTypes: [hfId] :: HoleFit -> Id
+ GHC.Tc.Errors.Hole.FitTypes: [hfId] :: TcHoleFit -> Id
- GHC.Tc.Errors.Hole.FitTypes: [hfMatches] :: HoleFit -> [TcType]
+ GHC.Tc.Errors.Hole.FitTypes: [hfMatches] :: TcHoleFit -> [TcType]
- GHC.Tc.Errors.Hole.FitTypes: [hfRefLvl] :: HoleFit -> Int
+ GHC.Tc.Errors.Hole.FitTypes: [hfRefLvl] :: TcHoleFit -> Int
- GHC.Tc.Errors.Hole.FitTypes: [hfType] :: HoleFit -> TcType
+ GHC.Tc.Errors.Hole.FitTypes: [hfType] :: TcHoleFit -> TcType
- GHC.Tc.Errors.Hole.FitTypes: [hfWrap] :: HoleFit -> [TcType]
+ GHC.Tc.Errors.Hole.FitTypes: [hfWrap] :: TcHoleFit -> [TcType]
- GHC.Tc.Errors.Hole.FitTypes: hfIsLcl :: HoleFit -> Bool
+ GHC.Tc.Errors.Hole.FitTypes: hfIsLcl :: TcHoleFit -> Bool
- GHC.Tc.Errors.Ppr: TcRnMessageOpts :: !Bool -> !IfaceMessageOpts -> TcRnMessageOpts
+ GHC.Tc.Errors.Ppr: TcRnMessageOpts :: Bool -> IfaceMessageOpts -> TcRnMessageOpts
- GHC.Tc.Errors.Ppr: [tcOptsIfaceOpts] :: TcRnMessageOpts -> !IfaceMessageOpts
+ GHC.Tc.Errors.Ppr: [tcOptsIfaceOpts] :: TcRnMessageOpts -> IfaceMessageOpts
- GHC.Tc.Errors.Ppr: [tcOptsShowContext] :: TcRnMessageOpts -> !Bool
+ GHC.Tc.Errors.Ppr: [tcOptsShowContext] :: TcRnMessageOpts -> Bool
- GHC.Tc.Errors.Types: AddDocToNonLocalDefn :: !DocLoc -> THError
+ GHC.Tc.Errors.Types: AddDocToNonLocalDefn :: DocLoc -> THError
- GHC.Tc.Errors.Types: AddInvalidCorePlugin :: !String -> THError
+ GHC.Tc.Errors.Types: AddInvalidCorePlugin :: String -> THError
- GHC.Tc.Errors.Types: AddTopDeclsError :: !AddTopDeclsError -> THError
+ GHC.Tc.Errors.Types: AddTopDeclsError :: AddTopDeclsError -> THError
- GHC.Tc.Errors.Types: AddTopDeclsRunSpliceFailure :: !RunSpliceFailReason -> AddTopDeclsError
+ GHC.Tc.Errors.Types: AddTopDeclsRunSpliceFailure :: RunSpliceFailReason -> AddTopDeclsError
- GHC.Tc.Errors.Types: AssocDefaultBadArgs :: !TyCon -> ![Type] -> AssocDefaultBadArgs -> InvalidAssocDefault
+ GHC.Tc.Errors.Types: AssocDefaultBadArgs :: TyCon -> [Type] -> AssocDefaultBadArgs -> InvalidAssocDefault
- GHC.Tc.Errors.Types: AssocDefaultDuplicateTyVars :: !NonEmpty (TyCoVar, ForAllTyFlag) -> AssocDefaultBadArgs
+ GHC.Tc.Errors.Types: AssocDefaultDuplicateTyVars :: NonEmpty (TyCoVar, ForAllTyFlag) -> AssocDefaultBadArgs
- GHC.Tc.Errors.Types: AssocDefaultNonTyVarArg :: !(Type, ForAllTyFlag) -> AssocDefaultBadArgs
+ GHC.Tc.Errors.Types: AssocDefaultNonTyVarArg :: (Type, ForAllTyFlag) -> AssocDefaultBadArgs
- GHC.Tc.Errors.Types: AssocDefaultNotAssoc :: !Name -> !Name -> InvalidAssocDefault
+ GHC.Tc.Errors.Types: AssocDefaultNotAssoc :: Name -> Name -> InvalidAssocDefault
- GHC.Tc.Errors.Types: AssocInstanceMissing :: !Name -> InvalidAssocInstance
+ GHC.Tc.Errors.Types: AssocInstanceMissing :: Name -> InvalidAssocInstance
- GHC.Tc.Errors.Types: AssocInstanceNotInAClass :: !TyCon -> InvalidAssocInstance
+ GHC.Tc.Errors.Types: AssocInstanceNotInAClass :: TyCon -> InvalidAssocInstance
- GHC.Tc.Errors.Types: AssocMultipleDefaults :: !Name -> InvalidAssocDefault
+ GHC.Tc.Errors.Types: AssocMultipleDefaults :: Name -> InvalidAssocDefault
- GHC.Tc.Errors.Types: AssocNoClassTyVar :: !Class -> !TyCon -> InvalidAssocInstance
+ GHC.Tc.Errors.Types: AssocNoClassTyVar :: Class -> TyCon -> InvalidAssocInstance
- GHC.Tc.Errors.Types: AssocNotInThisClass :: !Class -> !TyCon -> InvalidAssocInstance
+ GHC.Tc.Errors.Types: AssocNotInThisClass :: Class -> TyCon -> InvalidAssocInstance
- GHC.Tc.Errors.Types: AssocTyVarsDontMatch :: !ForAllTyFlag -> !TyCon -> ![Type] -> ![Type] -> InvalidAssocInstance
+ GHC.Tc.Errors.Types: AssocTyVarsDontMatch :: ForAllTyFlag -> TyCon -> [Type] -> [Type] -> InvalidAssocInstance
- GHC.Tc.Errors.Types: BadCoercionRole :: !Coercion -> RoleValidationFailedReason
+ GHC.Tc.Errors.Types: BadCoercionRole :: Coercion -> RoleValidationFailedReason
- GHC.Tc.Errors.Types: BadImportAvailTyCon :: Bool -> BadImportKind
+ GHC.Tc.Errors.Types: BadImportAvailTyCon :: BadImportKind
- GHC.Tc.Errors.Types: BadImportNotExportedSubordinates :: [OccName] -> BadImportKind
+ GHC.Tc.Errors.Types: BadImportNotExportedSubordinates :: GlobalRdrElt -> NonEmpty FastString -> BadImportKind
- GHC.Tc.Errors.Types: BadReexportedBootThing :: !Name -> !Name -> BootMismatch
+ GHC.Tc.Errors.Types: BadReexportedBootThing :: Name -> Name -> BootMismatch
- GHC.Tc.Errors.Types: BootBindsPs :: !NonEmpty (LHsBindLR GhcRn GhcPs) -> BadBootDecls
+ GHC.Tc.Errors.Types: BootBindsPs :: NonEmpty (LHsBindLR GhcRn GhcPs) -> BadBootDecls
- GHC.Tc.Errors.Types: BootBindsRn :: !NonEmpty (LHsBindLR GhcRn GhcRn) -> BadBootDecls
+ GHC.Tc.Errors.Types: BootBindsRn :: NonEmpty (LHsBindLR GhcRn GhcRn) -> BadBootDecls
- GHC.Tc.Errors.Types: BootDefaultDecls :: !NonEmpty (LDefaultDecl GhcRn) -> BadBootDecls
+ GHC.Tc.Errors.Types: BootDefaultDecls :: NonEmpty (LDefaultDecl GhcRn) -> BadBootDecls
- GHC.Tc.Errors.Types: BootFamInst :: !TyCon -> BadBootDecls
+ GHC.Tc.Errors.Types: BootFamInst :: TyCon -> BadBootDecls
- GHC.Tc.Errors.Types: BootForeignDecls :: !NonEmpty (LForeignDecl GhcRn) -> BadBootDecls
+ GHC.Tc.Errors.Types: BootForeignDecls :: NonEmpty (LForeignDecl GhcRn) -> BadBootDecls
- GHC.Tc.Errors.Types: BootInstanceSigs :: !NonEmpty (LSig GhcRn) -> BadBootDecls
+ GHC.Tc.Errors.Types: BootInstanceSigs :: NonEmpty (LSig GhcRn) -> BadBootDecls
- GHC.Tc.Errors.Types: BootMismatch :: !TyThing -> !TyThing -> !BootMismatchWhat -> BootMismatch
+ GHC.Tc.Errors.Types: BootMismatch :: TyThing -> TyThing -> BootMismatchWhat -> BootMismatch
- GHC.Tc.Errors.Types: BootMismatchedIdTypes :: !Id -> !Id -> BootMismatchWhat
+ GHC.Tc.Errors.Types: BootMismatchedIdTypes :: Id -> Id -> BootMismatchWhat
- GHC.Tc.Errors.Types: BootMismatchedTyCons :: !TyCon -> !TyCon -> !NonEmpty BootTyConMismatch -> BootMismatchWhat
+ GHC.Tc.Errors.Types: BootMismatchedTyCons :: TyCon -> TyCon -> NonEmpty BootTyConMismatch -> BootMismatchWhat
- GHC.Tc.Errors.Types: BootRuleDecls :: !NonEmpty (LRuleDecls GhcRn) -> BadBootDecls
+ GHC.Tc.Errors.Types: BootRuleDecls :: NonEmpty (LRuleDecls GhcRn) -> BadBootDecls
- GHC.Tc.Errors.Types: BootSpliceDecls :: !NonEmpty (LocatedA (HsUntypedSplice GhcPs)) -> BadBootDecls
+ GHC.Tc.Errors.Types: BootSpliceDecls :: NonEmpty (LocatedA (HsUntypedSplice GhcPs)) -> BadBootDecls
- GHC.Tc.Errors.Types: CannotReifyInstance :: !Type -> THReifyError
+ GHC.Tc.Errors.Types: CannotReifyInstance :: Type -> THReifyError
- GHC.Tc.Errors.Types: CannotReifyOutOfScopeThing :: !Name -> THReifyError
+ GHC.Tc.Errors.Types: CannotReifyOutOfScopeThing :: Name -> THReifyError
- GHC.Tc.Errors.Types: CannotReifyThingNotInTypeEnv :: !Name -> THReifyError
+ GHC.Tc.Errors.Types: CannotReifyThingNotInTypeEnv :: Name -> THReifyError
- GHC.Tc.Errors.Types: CannotRepresentType :: !UnrepresentableTypeDescr -> !Type -> THReifyError
+ GHC.Tc.Errors.Types: CannotRepresentType :: UnrepresentableTypeDescr -> Type -> THReifyError
- GHC.Tc.Errors.Types: CannotResolveInstance :: ErrorItem -> [ClsInst] -> [ClsInst] -> [ImportError] -> [GhcHint] -> RelevantBindings -> TcSolverReportMsg
+ GHC.Tc.Errors.Types: CannotResolveInstance :: ErrorItem -> [ClsInst] -> [ClsInst] -> RelevantBindings -> TcSolverReportMsg
- GHC.Tc.Errors.Types: ClassInstanceCtx :: HsDocContext
+ GHC.Tc.Errors.Types: ClassInstanceCtx :: LHsType GhcRn -> HsDocContext
- GHC.Tc.Errors.Types: ConvDec :: !Dec -> ThingBeingConverted
+ GHC.Tc.Errors.Types: ConvDec :: Dec -> ThingBeingConverted
- GHC.Tc.Errors.Types: ConvExp :: !Exp -> ThingBeingConverted
+ GHC.Tc.Errors.Types: ConvExp :: Exp -> ThingBeingConverted
- GHC.Tc.Errors.Types: ConvPat :: !Pat -> ThingBeingConverted
+ GHC.Tc.Errors.Types: ConvPat :: Pat -> ThingBeingConverted
- GHC.Tc.Errors.Types: ConvType :: !Type -> ThingBeingConverted
+ GHC.Tc.Errors.Types: ConvType :: Type -> ThingBeingConverted
- GHC.Tc.Errors.Types: ConversionFail :: !ThingBeingConverted -> !ConversionFailReason -> RunSpliceFailReason
+ GHC.Tc.Errors.Types: ConversionFail :: ThingBeingConverted -> ConversionFailReason -> RunSpliceFailReason
- GHC.Tc.Errors.Types: DefaultDataInstDecl :: ![LDataFamInstDecl GhcPs] -> ConversionFailReason
+ GHC.Tc.Errors.Types: DefaultDataInstDecl :: [LDataFamInstDecl GhcPs] -> ConversionFailReason
- GHC.Tc.Errors.Types: DerivErrBadConCovariant :: !DataCon -> DeriveInstanceBadConstructor
+ GHC.Tc.Errors.Types: DerivErrBadConCovariant :: DataCon -> DeriveInstanceBadConstructor
- GHC.Tc.Errors.Types: DerivErrBadConExistential :: !DataCon -> DeriveInstanceBadConstructor
+ GHC.Tc.Errors.Types: DerivErrBadConExistential :: DataCon -> DeriveInstanceBadConstructor
- GHC.Tc.Errors.Types: DerivErrBadConFunTypes :: !DataCon -> DeriveInstanceBadConstructor
+ GHC.Tc.Errors.Types: DerivErrBadConFunTypes :: DataCon -> DeriveInstanceBadConstructor
- GHC.Tc.Errors.Types: DerivErrBadConHasConstraints :: !DataCon -> DeriveInstanceBadConstructor
+ GHC.Tc.Errors.Types: DerivErrBadConHasConstraints :: DataCon -> DeriveInstanceBadConstructor
- GHC.Tc.Errors.Types: DerivErrBadConHasExistentials :: !DataCon -> DeriveInstanceBadConstructor
+ GHC.Tc.Errors.Types: DerivErrBadConHasExistentials :: DataCon -> DeriveInstanceBadConstructor
- GHC.Tc.Errors.Types: DerivErrBadConHasHigherRankType :: !DataCon -> DeriveInstanceBadConstructor
+ GHC.Tc.Errors.Types: DerivErrBadConHasHigherRankType :: DataCon -> DeriveInstanceBadConstructor
- GHC.Tc.Errors.Types: DerivErrBadConIsGADT :: !DataCon -> DeriveInstanceBadConstructor
+ GHC.Tc.Errors.Types: DerivErrBadConIsGADT :: DataCon -> DeriveInstanceBadConstructor
- GHC.Tc.Errors.Types: DerivErrBadConWrongArg :: !DataCon -> DeriveInstanceBadConstructor
+ GHC.Tc.Errors.Types: DerivErrBadConWrongArg :: DataCon -> DeriveInstanceBadConstructor
- GHC.Tc.Errors.Types: DerivErrBadConstructor :: !Maybe HasWildcard -> [DeriveInstanceBadConstructor] -> DeriveInstanceErrReason
+ GHC.Tc.Errors.Types: DerivErrBadConstructor :: Maybe HasWildcard -> [DeriveInstanceBadConstructor] -> DeriveInstanceErrReason
- GHC.Tc.Errors.Types: DerivErrCannotEtaReduceEnough :: !Bool -> DeriveInstanceErrReason
+ GHC.Tc.Errors.Types: DerivErrCannotEtaReduceEnough :: Bool -> DeriveInstanceErrReason
- GHC.Tc.Errors.Types: DerivErrDataConsNotAllInScope :: !TyCon -> DeriveInstanceErrReason
+ GHC.Tc.Errors.Types: DerivErrDataConsNotAllInScope :: TyCon -> DeriveInstanceErrReason
- GHC.Tc.Errors.Types: DerivErrDerivingViaWrongKind :: !Kind -> !Type -> !Kind -> DeriveInstanceErrReason
+ GHC.Tc.Errors.Types: DerivErrDerivingViaWrongKind :: Kind -> Type -> Kind -> DeriveInstanceErrReason
- GHC.Tc.Errors.Types: DerivErrDunnoHowToDeriveForType :: !Type -> DeriveInstanceErrReason
+ GHC.Tc.Errors.Types: DerivErrDunnoHowToDeriveForType :: Type -> DeriveInstanceErrReason
- GHC.Tc.Errors.Types: DerivErrEnumOrProduct :: !DeriveInstanceErrReason -> !DeriveInstanceErrReason -> DeriveInstanceErrReason
+ GHC.Tc.Errors.Types: DerivErrEnumOrProduct :: DeriveInstanceErrReason -> DeriveInstanceErrReason -> DeriveInstanceErrReason
- GHC.Tc.Errors.Types: DerivErrGenericsMustBeVanillaDataCon :: !DataCon -> DeriveGenericsErrReason
+ GHC.Tc.Errors.Types: DerivErrGenericsMustBeVanillaDataCon :: DataCon -> DeriveGenericsErrReason
- GHC.Tc.Errors.Types: DerivErrGenericsMustHaveSomeTypeParams :: !TyCon -> DeriveGenericsErrReason
+ GHC.Tc.Errors.Types: DerivErrGenericsMustHaveSomeTypeParams :: TyCon -> DeriveGenericsErrReason
- GHC.Tc.Errors.Types: DerivErrGenericsMustNotHaveDatatypeContext :: !TyCon -> DeriveGenericsErrReason
+ GHC.Tc.Errors.Types: DerivErrGenericsMustNotHaveDatatypeContext :: TyCon -> DeriveGenericsErrReason
- GHC.Tc.Errors.Types: DerivErrGenericsMustNotHaveExistentials :: !DataCon -> DeriveGenericsErrReason
+ GHC.Tc.Errors.Types: DerivErrGenericsMustNotHaveExistentials :: DataCon -> DeriveGenericsErrReason
- GHC.Tc.Errors.Types: DerivErrGenericsMustNotHaveExoticArgs :: !DataCon -> DeriveGenericsErrReason
+ GHC.Tc.Errors.Types: DerivErrGenericsMustNotHaveExoticArgs :: DataCon -> DeriveGenericsErrReason
- GHC.Tc.Errors.Types: DerivErrGenericsWrongArgKind :: !DataCon -> DeriveGenericsErrReason
+ GHC.Tc.Errors.Types: DerivErrGenericsWrongArgKind :: DataCon -> DeriveGenericsErrReason
- GHC.Tc.Errors.Types: DerivErrHasAssociatedDatatypes :: !HasAssociatedDataFamInsts -> !AssociatedTyLastVarInKind -> !AssociatedTyNotParamOverLastTyVar -> DeriveInstanceErrReason
+ GHC.Tc.Errors.Types: DerivErrHasAssociatedDatatypes :: HasAssociatedDataFamInsts -> AssociatedTyLastVarInKind -> AssociatedTyNotParamOverLastTyVar -> DeriveInstanceErrReason
- GHC.Tc.Errors.Types: DerivErrLangExtRequired :: !Extension -> DeriveInstanceErrReason
+ GHC.Tc.Errors.Types: DerivErrLangExtRequired :: Extension -> DeriveInstanceErrReason
- GHC.Tc.Errors.Types: DerivErrMustBeEnumType :: !TyCon -> DeriveInstanceErrReason
+ GHC.Tc.Errors.Types: DerivErrMustBeEnumType :: TyCon -> DeriveInstanceErrReason
- GHC.Tc.Errors.Types: DerivErrMustHaveExactlyOneConstructor :: !TyCon -> DeriveInstanceErrReason
+ GHC.Tc.Errors.Types: DerivErrMustHaveExactlyOneConstructor :: TyCon -> DeriveInstanceErrReason
- GHC.Tc.Errors.Types: DerivErrMustHaveSomeParameters :: !TyCon -> DeriveInstanceErrReason
+ GHC.Tc.Errors.Types: DerivErrMustHaveSomeParameters :: TyCon -> DeriveInstanceErrReason
- GHC.Tc.Errors.Types: DerivErrMustNotHaveClassContext :: !TyCon -> !ThetaType -> DeriveInstanceErrReason
+ GHC.Tc.Errors.Types: DerivErrMustNotHaveClassContext :: TyCon -> ThetaType -> DeriveInstanceErrReason
- GHC.Tc.Errors.Types: DerivErrNoConstructors :: !TyCon -> DeriveInstanceErrReason
+ GHC.Tc.Errors.Types: DerivErrNoConstructors :: TyCon -> DeriveInstanceErrReason
- GHC.Tc.Errors.Types: DerivErrNoEtaReduce :: !Type -> DeriveInstanceErrReason
+ GHC.Tc.Errors.Types: DerivErrNoEtaReduce :: Type -> DeriveInstanceErrReason
- GHC.Tc.Errors.Types: DerivErrNoFamilyInstance :: !TyCon -> [Type] -> DeriveInstanceErrReason
+ GHC.Tc.Errors.Types: DerivErrNoFamilyInstance :: TyCon -> [Type] -> DeriveInstanceErrReason
- GHC.Tc.Errors.Types: DerivErrNotAClass :: !PredType -> DeriveInstanceErrReason
+ GHC.Tc.Errors.Types: DerivErrNotAClass :: PredType -> DeriveInstanceErrReason
- GHC.Tc.Errors.Types: DerivErrNotDeriveable :: !DeriveAnyClassEnabled -> DeriveInstanceErrReason
+ GHC.Tc.Errors.Types: DerivErrNotDeriveable :: DeriveAnyClassEnabled -> DeriveInstanceErrReason
- GHC.Tc.Errors.Types: DerivErrNotStockDeriveable :: !DeriveAnyClassEnabled -> DeriveInstanceErrReason
+ GHC.Tc.Errors.Types: DerivErrNotStockDeriveable :: DeriveAnyClassEnabled -> DeriveInstanceErrReason
- GHC.Tc.Errors.Types: DerivErrNotWellKinded :: !TyCon -> !Kind -> !Int -> DeriveInstanceErrReason
+ GHC.Tc.Errors.Types: DerivErrNotWellKinded :: TyCon -> Kind -> Int -> DeriveInstanceErrReason
- GHC.Tc.Errors.Types: DerivErrOnlyAnyClassDeriveable :: !TyCon -> !DeriveAnyClassEnabled -> DeriveInstanceErrReason
+ GHC.Tc.Errors.Types: DerivErrOnlyAnyClassDeriveable :: TyCon -> DeriveAnyClassEnabled -> DeriveInstanceErrReason
- GHC.Tc.Errors.Types: DodgyImportsEmptyParent :: !GlobalRdrElt -> DodgyImportsReason
+ GHC.Tc.Errors.Types: DodgyImportsEmptyParent :: GlobalRdrElt -> DodgyImportsReason
- GHC.Tc.Errors.Types: DodgyImportsHiding :: !ImportLookupReason -> DodgyImportsReason
+ GHC.Tc.Errors.Types: DodgyImportsHiding :: ImportLookupReason -> DodgyImportsReason
- GHC.Tc.Errors.Types: DoesNotHaveSingleField :: !Int -> IllegalNewtypeReason
+ GHC.Tc.Errors.Types: DoesNotHaveSingleField :: Int -> IllegalNewtypeReason
- GHC.Tc.Errors.Types: EquationArgs :: !Name -> MatchArgsContext
+ GHC.Tc.Errors.Types: EquationArgs :: Name -> MatchArgsContext
- GHC.Tc.Errors.Types: ErrInfo :: !SDoc -> !SDoc -> ErrInfo
+ GHC.Tc.Errors.Types: ErrInfo :: [ErrCtxtMsg] -> Maybe (HoleFitDispConfig, [SupplementaryInfo]) -> [GhcHint] -> ErrInfo
- GHC.Tc.Errors.Types: FRR_Info :: FixedRuntimeRepOrigin -> Maybe (TcTyVar, TcType) -> FixedRuntimeRepErrorInfo
+ GHC.Tc.Errors.Types: FRR_Info :: FixedRuntimeRepOrigin -> Maybe (TcTyVar, TcType) -> Maybe CtOrigin -> FixedRuntimeRepErrorInfo
- GHC.Tc.Errors.Types: FailedICC :: !Bool -> FailedCoverageCondition
+ GHC.Tc.Errors.Types: FailedICC :: Bool -> FailedCoverageCondition
- GHC.Tc.Errors.Types: FailedToLookupThInstName :: !Type -> !LookupTHInstNameErrReason -> THError
+ GHC.Tc.Errors.Types: FailedToLookupThInstName :: Type -> LookupTHInstNameErrReason -> THError
- GHC.Tc.Errors.Types: FamInstLHSUnusedBoundTyVars :: !NonEmpty InvalidFamInstQTv -> IllegalFamilyInstanceReason
+ GHC.Tc.Errors.Types: FamInstLHSUnusedBoundTyVars :: NonEmpty InvalidFamInstQTv -> IllegalFamilyInstanceReason
- GHC.Tc.Errors.Types: FamInstRHSOutOfScopeTyVars :: !Maybe (TyCon, [Type], TyVarSet) -> !NonEmpty Name -> IllegalFamilyInstanceReason
+ GHC.Tc.Errors.Types: FamInstRHSOutOfScopeTyVars :: Maybe (TyCon, [Type], TyVarSet) -> NonEmpty Name -> IllegalFamilyInstanceReason
- GHC.Tc.Errors.Types: FamilyArityMismatch :: !TyCon -> !Arity -> IllegalFamilyInstanceReason
+ GHC.Tc.Errors.Types: FamilyArityMismatch :: TyCon -> Arity -> IllegalFamilyInstanceReason
- GHC.Tc.Errors.Types: FamilyCategoryMismatch :: !TyCon -> IllegalFamilyInstanceReason
+ GHC.Tc.Errors.Types: FamilyCategoryMismatch :: TyCon -> IllegalFamilyInstanceReason
- GHC.Tc.Errors.Types: ForeignDynNotPtr :: !Type -> !Type -> IllegalForeignTypeReason
+ GHC.Tc.Errors.Types: ForeignDynNotPtr :: Type -> Type -> IllegalForeignTypeReason
- GHC.Tc.Errors.Types: FunBindLacksEquations :: !Name -> ConversionFailReason
+ GHC.Tc.Errors.Types: FunBindLacksEquations :: Name -> ConversionFailReason
- GHC.Tc.Errors.Types: HsigShapeNotUnifiable :: !Name -> !Name -> !Bool -> HsigShapeMismatchReason
+ GHC.Tc.Errors.Types: HsigShapeNotUnifiable :: Name -> Name -> Bool -> HsigShapeMismatchReason
- GHC.Tc.Errors.Types: HsigShapeSortMismatch :: !AvailInfo -> !AvailInfo -> HsigShapeMismatchReason
+ GHC.Tc.Errors.Types: HsigShapeSortMismatch :: AvailInfo -> AvailInfo -> HsigShapeMismatchReason
- GHC.Tc.Errors.Types: IllegalClassInstance :: !TypedThing -> !IllegalClassInstanceReason -> IllegalInstanceReason
+ GHC.Tc.Errors.Types: IllegalClassInstance :: TypedThing -> IllegalClassInstanceReason -> IllegalInstanceReason
- GHC.Tc.Errors.Types: IllegalDeclaration :: !THDeclDescriptor -> !IllegalDecls -> ConversionFailReason
+ GHC.Tc.Errors.Types: IllegalDeclaration :: THDeclDescriptor -> IllegalDecls -> ConversionFailReason
- GHC.Tc.Errors.Types: IllegalDecls :: !NonEmpty (LHsDecl GhcPs) -> IllegalDecls
+ GHC.Tc.Errors.Types: IllegalDecls :: NonEmpty (LHsDecl GhcPs) -> IllegalDecls
- GHC.Tc.Errors.Types: IllegalFamDecls :: !NonEmpty (LFamilyDecl GhcPs) -> IllegalDecls
+ GHC.Tc.Errors.Types: IllegalFamDecls :: NonEmpty (LFamilyDecl GhcPs) -> IllegalDecls
- GHC.Tc.Errors.Types: IllegalFamilyApplicationInInstance :: !Type -> !Bool -> !TyCon -> ![Type] -> IllegalInstanceReason
+ GHC.Tc.Errors.Types: IllegalFamilyApplicationInInstance :: Type -> Bool -> TyCon -> [Type] -> IllegalInstanceReason
- GHC.Tc.Errors.Types: IllegalFamilyInstance :: !IllegalFamilyInstanceReason -> IllegalInstanceReason
+ GHC.Tc.Errors.Types: IllegalFamilyInstance :: IllegalFamilyInstanceReason -> IllegalInstanceReason
- GHC.Tc.Errors.Types: IllegalHasFieldInstance :: !IllegalHasFieldInstance -> IllegalClassInstanceReason
+ GHC.Tc.Errors.Types: IllegalHasFieldInstance :: IllegalHasFieldInstance -> IllegalClassInstanceReason
- GHC.Tc.Errors.Types: IllegalHasFieldInstanceTyConHasField :: !TyCon -> !FieldLabelString -> IllegalHasFieldInstance
+ GHC.Tc.Errors.Types: IllegalHasFieldInstanceTyConHasField :: TyCon -> FieldLabelString -> IllegalHasFieldInstance
- GHC.Tc.Errors.Types: IllegalHasFieldInstanceTyConHasFields :: !TyCon -> !Type -> IllegalHasFieldInstance
+ GHC.Tc.Errors.Types: IllegalHasFieldInstanceTyConHasFields :: TyCon -> Type -> IllegalHasFieldInstance
- GHC.Tc.Errors.Types: IllegalInstanceFailsCoverageCondition :: !Class -> !CoverageProblem -> IllegalClassInstanceReason
+ GHC.Tc.Errors.Types: IllegalInstanceFailsCoverageCondition :: Class -> CoverageProblem -> IllegalClassInstanceReason
- GHC.Tc.Errors.Types: IllegalInstanceHead :: !IllegalInstanceHeadReason -> IllegalClassInstanceReason
+ GHC.Tc.Errors.Types: IllegalInstanceHead :: IllegalInstanceHeadReason -> IllegalClassInstanceReason
- GHC.Tc.Errors.Types: IllegalLastStatement :: !HsDoFlavour -> !LStmt GhcPs (LHsExpr GhcPs) -> ConversionFailReason
+ GHC.Tc.Errors.Types: IllegalLastStatement :: HsDoFlavour -> LStmt GhcPs (LHsExpr GhcPs) -> ConversionFailReason
- GHC.Tc.Errors.Types: IllegalOccName :: !NameSpace -> !String -> ConversionFailReason
+ GHC.Tc.Errors.Types: IllegalOccName :: NameSpace -> String -> ConversionFailReason
- GHC.Tc.Errors.Types: IllegalSpecialClassInstance :: !Class -> !Bool -> IllegalClassInstanceReason
+ GHC.Tc.Errors.Types: IllegalSpecialClassInstance :: Class -> Bool -> IllegalClassInstanceReason
- GHC.Tc.Errors.Types: IllegalStaticFormInSplice :: !HsExpr GhcPs -> THError
+ GHC.Tc.Errors.Types: IllegalStaticFormInSplice :: HsExpr GhcPs -> THError
- GHC.Tc.Errors.Types: IllegalSumAlt :: !SumAlt -> ConversionFailReason
+ GHC.Tc.Errors.Types: IllegalSumAlt :: SumAlt -> ConversionFailReason
- GHC.Tc.Errors.Types: IllegalSumArity :: !SumArity -> ConversionFailReason
+ GHC.Tc.Errors.Types: IllegalSumArity :: SumArity -> ConversionFailReason
- GHC.Tc.Errors.Types: IllegalTHQuotes :: !HsExpr GhcPs -> THSyntaxError
+ GHC.Tc.Errors.Types: IllegalTHQuotes :: HsExpr GhcPs -> THSyntaxError
- GHC.Tc.Errors.Types: InjErrCannotInferFromRhs :: !TyVarSet -> !HasKinds -> !SuggestUndecidableInstances -> InjectivityErrReason
+ GHC.Tc.Errors.Types: InjErrCannotInferFromRhs :: TyVarSet -> HasKinds -> SuggestUndecidableInstances -> InjectivityErrReason
- GHC.Tc.Errors.Types: InstHeadAbstractClass :: !Class -> IllegalInstanceHeadReason
+ GHC.Tc.Errors.Types: InstHeadAbstractClass :: WithUserRdr Name -> IllegalInstanceHeadReason
- GHC.Tc.Errors.Types: InvalidAssoc :: !InvalidAssoc -> IllegalFamilyInstanceReason
+ GHC.Tc.Errors.Types: InvalidAssoc :: InvalidAssoc -> IllegalFamilyInstanceReason
- GHC.Tc.Errors.Types: InvalidAssocDefault :: !InvalidAssocDefault -> InvalidAssoc
+ GHC.Tc.Errors.Types: InvalidAssocDefault :: InvalidAssocDefault -> InvalidAssoc
- GHC.Tc.Errors.Types: InvalidAssocInstance :: !InvalidAssocInstance -> InvalidAssoc
+ GHC.Tc.Errors.Types: InvalidAssocInstance :: InvalidAssocInstance -> InvalidAssoc
- GHC.Tc.Errors.Types: InvalidCCallImpent :: !String -> ConversionFailReason
+ GHC.Tc.Errors.Types: InvalidCCallImpent :: String -> ConversionFailReason
- GHC.Tc.Errors.Types: InvalidTopDecl :: !HsDecl GhcPs -> AddTopDeclsError
+ GHC.Tc.Errors.Types: InvalidTopDecl :: HsDecl GhcPs -> AddTopDeclsError
- GHC.Tc.Errors.Types: InvalidTyFamInstLHS :: !Type -> ConversionFailReason
+ GHC.Tc.Errors.Types: InvalidTyFamInstLHS :: Type -> ConversionFailReason
- GHC.Tc.Errors.Types: InvalidTypeInstanceHeader :: !Type -> ConversionFailReason
+ GHC.Tc.Errors.Types: InvalidTypeInstanceHeader :: Type -> ConversionFailReason
- GHC.Tc.Errors.Types: MalformedType :: !TypeOrKind -> !Type -> ConversionFailReason
+ GHC.Tc.Errors.Types: MalformedType :: TypeOrKind -> Type -> ConversionFailReason
- GHC.Tc.Errors.Types: MismatchedATs :: !BootListMismatches ClassATItem BootATMismatch -> BootClassMismatch
+ GHC.Tc.Errors.Types: MismatchedATs :: BootListMismatches ClassATItem BootATMismatch -> BootClassMismatch
- GHC.Tc.Errors.Types: MismatchedConstructors :: !BootListMismatches DataCon BootDataConMismatch -> BootDataMismatch
+ GHC.Tc.Errors.Types: MismatchedConstructors :: BootListMismatches DataCon BootDataConMismatch -> BootDataMismatch
- GHC.Tc.Errors.Types: MismatchedDefaultMethods :: !Bool -> BootMethodMismatch
+ GHC.Tc.Errors.Types: MismatchedDefaultMethods :: Bool -> BootMethodMismatch
- GHC.Tc.Errors.Types: MismatchedMethodTypes :: !Type -> !Type -> BootMethodMismatch
+ GHC.Tc.Errors.Types: MismatchedMethodTypes :: Type -> Type -> BootMethodMismatch
- GHC.Tc.Errors.Types: MismatchedMethods :: !BootListMismatches ClassOpItem BootMethodMismatch -> BootClassMismatch
+ GHC.Tc.Errors.Types: MismatchedMethods :: BootListMismatches ClassOpItem BootMethodMismatch -> BootClassMismatch
- GHC.Tc.Errors.Types: MismatchedThing :: !Int -> !item -> !item -> !err -> BootListMismatch item err
+ GHC.Tc.Errors.Types: MismatchedThing :: Int -> item -> item -> err -> BootListMismatch item err
- GHC.Tc.Errors.Types: MismatchedTyConAT :: !BootTyConMismatch -> BootATMismatch
+ GHC.Tc.Errors.Types: MismatchedTyConAT :: BootTyConMismatch -> BootATMismatch
- GHC.Tc.Errors.Types: MissingBinding :: SDoc -> [GhcHint] -> NotInScopeError
+ GHC.Tc.Errors.Types: MissingBinding :: SigLike -> [GhcHint] -> NotInScopeError
- GHC.Tc.Errors.Types: MissingBootInstance :: !DFunId -> BootMismatch
+ GHC.Tc.Errors.Types: MissingBootInstance :: DFunId -> BootMismatch
- GHC.Tc.Errors.Types: MissingBootThing :: !Name -> !MissingBootThing -> BootMismatch
+ GHC.Tc.Errors.Types: MissingBootThing :: Name -> MissingBootThing -> BootMismatch
- GHC.Tc.Errors.Types: ModulesDoNotExport :: NonEmpty Module -> OccName -> ImportError
+ GHC.Tc.Errors.Types: ModulesDoNotExport :: NonEmpty Module -> WhatLooking -> OccName -> ImportError
- GHC.Tc.Errors.Types: NewtypeDataConNotInScope :: !TyCon -> ![Type] -> TypeCannotBeMarshaledReason
+ GHC.Tc.Errors.Types: NewtypeDataConNotInScope :: TyCon -> [Type] -> TypeCannotBeMarshaledReason
- GHC.Tc.Errors.Types: NoRolesAssociatedWithThing :: !TcTyThing -> THReifyError
+ GHC.Tc.Errors.Types: NoRolesAssociatedWithThing :: TcTyThing -> THReifyError
- GHC.Tc.Errors.Types: NonExactName :: !RdrName -> THNameError
+ GHC.Tc.Errors.Types: NonExactName :: RdrName -> THNameError
- GHC.Tc.Errors.Types: NotAFamilyTyCon :: !TypeOrData -> !TyCon -> IllegalFamilyInstanceReason
+ GHC.Tc.Errors.Types: NotAFamilyTyCon :: TypeOrData -> TyCon -> IllegalFamilyInstanceReason
- GHC.Tc.Errors.Types: NotAnOpenFamilyTyCon :: !TyCon -> IllegalFamilyInstanceReason
+ GHC.Tc.Errors.Types: NotAnOpenFamilyTyCon :: TyCon -> IllegalFamilyInstanceReason
- GHC.Tc.Errors.Types: OutOfScopeHole :: [ImportError] -> [GhcHint] -> HoleError
+ GHC.Tc.Errors.Types: OutOfScopeHole :: HoleError
- GHC.Tc.Errors.Types: PatSynNotInvertible :: !Pat GhcRn -> PatSynInvalidRhsReason
+ GHC.Tc.Errors.Types: PatSynNotInvertible :: Pat GhcRn -> PatSynInvalidRhsReason
- GHC.Tc.Errors.Types: PatSynUnboundVar :: !Name -> PatSynInvalidRhsReason
+ GHC.Tc.Errors.Types: PatSynUnboundVar :: Name -> PatSynInvalidRhsReason
- GHC.Tc.Errors.Types: PatternArgs :: !HsMatchContextRn -> MatchArgsContext
+ GHC.Tc.Errors.Types: PatternArgs :: HsMatchContextRn -> MatchArgsContext
- GHC.Tc.Errors.Types: RecordFieldConstructor :: !Name -> RecordFieldPart
+ GHC.Tc.Errors.Types: RecordFieldConstructor :: Name -> RecordFieldPart
- GHC.Tc.Errors.Types: RecordFieldDecl :: !Name -> RecordFieldPart
+ GHC.Tc.Errors.Types: RecordFieldDecl :: Name -> RecordFieldPart
- GHC.Tc.Errors.Types: RecordFieldPattern :: !Name -> RecordFieldPart
+ GHC.Tc.Errors.Types: RecordFieldPattern :: Name -> RecordFieldPart
- GHC.Tc.Errors.Types: ReportCustomQuasiError :: !Bool -> !String -> THError
+ GHC.Tc.Errors.Types: ReportCustomQuasiError :: Bool -> String -> THError
- GHC.Tc.Errors.Types: RunSpliceFailure :: !RunSpliceFailReason -> SpliceFailReason
+ GHC.Tc.Errors.Types: RunSpliceFailure :: RunSpliceFailReason -> SpliceFailReason
- GHC.Tc.Errors.Types: SCD_HeadTyFam :: !PredType -> SuperclassCycleDetail
+ GHC.Tc.Errors.Types: SCD_HeadTyFam :: PredType -> SuperclassCycleDetail
- GHC.Tc.Errors.Types: SCD_HeadTyVar :: !PredType -> SuperclassCycleDetail
+ GHC.Tc.Errors.Types: SCD_HeadTyVar :: PredType -> SuperclassCycleDetail
- GHC.Tc.Errors.Types: SCD_Superclass :: !Class -> SuperclassCycleDetail
+ GHC.Tc.Errors.Types: SCD_Superclass :: Class -> SuperclassCycleDetail
- GHC.Tc.Errors.Types: ShadowedNameProvenanceLocal :: !SrcLoc -> ShadowedNameProvenance
+ GHC.Tc.Errors.Types: ShadowedNameProvenanceLocal :: SrcLoc -> ShadowedNameProvenance
- GHC.Tc.Errors.Types: SolverReport :: SolverReportWithCtxt -> [SolverReportSupplementary] -> SolverReport
+ GHC.Tc.Errors.Types: SolverReport :: SolverReportWithCtxt -> [SupplementaryInfo] -> [GhcHint] -> SolverReport
- GHC.Tc.Errors.Types: SplicePolymorphicLocalVar :: !Id -> TypedTHError
+ GHC.Tc.Errors.Types: SplicePolymorphicLocalVar :: Id -> TypedTHError
- GHC.Tc.Errors.Types: SpliceThrewException :: !SplicePhase -> !SomeException -> !String -> !LHsExpr GhcTc -> !Bool -> SpliceFailReason
+ GHC.Tc.Errors.Types: SpliceThrewException :: SplicePhase -> SomeException -> String -> LHsExpr GhcTc -> Bool -> SpliceFailReason
- GHC.Tc.Errors.Types: StandaloneKindSigCtx :: SDoc -> HsDocContext
+ GHC.Tc.Errors.Types: StandaloneKindSigCtx :: LocatedN RdrName -> HsDocContext
- GHC.Tc.Errors.Types: SumAltArityExceeded :: !SumAlt -> !SumArity -> ConversionFailReason
+ GHC.Tc.Errors.Types: SumAltArityExceeded :: SumAlt -> SumArity -> ConversionFailReason
- GHC.Tc.Errors.Types: SupplementaryBindings :: RelevantBindings -> SolverReportSupplementary
+ GHC.Tc.Errors.Types: SupplementaryBindings :: RelevantBindings -> SupplementaryInfo
- GHC.Tc.Errors.Types: SupplementaryCts :: [(PredType, RealSrcSpan)] -> SolverReportSupplementary
+ GHC.Tc.Errors.Types: SupplementaryCts :: NonEmpty (PredType, RealSrcSpan) -> SupplementaryInfo
- GHC.Tc.Errors.Types: SupplementaryHoleFits :: ValidHoleFits -> SolverReportSupplementary
+ GHC.Tc.Errors.Types: SupplementaryHoleFits :: ValidHoleFits -> SupplementaryInfo
- GHC.Tc.Errors.Types: SynAbstractData :: !SynAbstractDataError -> BootTyConMismatch
+ GHC.Tc.Errors.Types: SynAbstractData :: SynAbstractDataError -> BootTyConMismatch
- GHC.Tc.Errors.Types: SynAbstractDataInvalidRHS :: !NonEmpty Type -> SynAbstractDataError
+ GHC.Tc.Errors.Types: SynAbstractDataInvalidRHS :: NonEmpty Type -> SynAbstractDataError
- GHC.Tc.Errors.Types: THNameError :: !THNameError -> THError
+ GHC.Tc.Errors.Types: THNameError :: THNameError -> THError
- GHC.Tc.Errors.Types: THReifyError :: !THReifyError -> THError
+ GHC.Tc.Errors.Types: THReifyError :: THReifyError -> THError
- GHC.Tc.Errors.Types: THSpliceFailed :: !SpliceFailReason -> THError
+ GHC.Tc.Errors.Types: THSpliceFailed :: SpliceFailReason -> THError
- GHC.Tc.Errors.Types: THSyntaxError :: !THSyntaxError -> THError
+ GHC.Tc.Errors.Types: THSyntaxError :: THSyntaxError -> THError
- GHC.Tc.Errors.Types: TcRnMessageDetailed :: !ErrInfo -> !TcRnMessage -> TcRnMessageDetailed
+ GHC.Tc.Errors.Types: TcRnMessageDetailed :: ErrInfo -> TcRnMessage -> TcRnMessageDetailed
- GHC.Tc.Errors.Types: TcRnMessageOpts :: !Bool -> !IfaceMessageOpts -> TcRnMessageOpts
+ GHC.Tc.Errors.Types: TcRnMessageOpts :: Bool -> IfaceMessageOpts -> TcRnMessageOpts
- GHC.Tc.Errors.Types: TyConAxiomMismatch :: !BootListMismatches CoAxBranch BootAxiomBranchMismatch -> BootTyConMismatch
+ GHC.Tc.Errors.Types: TyConAxiomMismatch :: BootListMismatches CoAxBranch BootAxiomBranchMismatch -> BootTyConMismatch
- GHC.Tc.Errors.Types: TyConFlavourMismatch :: !FamTyConFlav -> !FamTyConFlav -> BootTyConMismatch
+ GHC.Tc.Errors.Types: TyConFlavourMismatch :: FamTyConFlav -> FamTyConFlav -> BootTyConMismatch
- GHC.Tc.Errors.Types: TyConMismatchedClasses :: !Class -> !Class -> !BootClassMismatch -> BootTyConMismatch
+ GHC.Tc.Errors.Types: TyConMismatchedClasses :: Class -> Class -> BootClassMismatch -> BootTyConMismatch
- GHC.Tc.Errors.Types: TyConMismatchedData :: !AlgTyConRhs -> !AlgTyConRhs -> !BootDataMismatch -> BootTyConMismatch
+ GHC.Tc.Errors.Types: TyConMismatchedData :: AlgTyConRhs -> AlgTyConRhs -> BootDataMismatch -> BootTyConMismatch
- GHC.Tc.Errors.Types: TyConRoleMismatch :: !Bool -> BootTyConMismatch
+ GHC.Tc.Errors.Types: TyConRoleMismatch :: Bool -> BootTyConMismatch
- GHC.Tc.Errors.Types: TyConSynonymMismatch :: !Kind -> !Kind -> BootTyConMismatch
+ GHC.Tc.Errors.Types: TyConSynonymMismatch :: Kind -> Kind -> BootTyConMismatch
- GHC.Tc.Errors.Types: TyFamNameMismatch :: !Name -> !Name -> IllegalFamilyInstanceReason
+ GHC.Tc.Errors.Types: TyFamNameMismatch :: Name -> Name -> IllegalFamilyInstanceReason
- GHC.Tc.Errors.Types: TyFamsDisabledFamily :: !Name -> TyFamsDisabledReason
+ GHC.Tc.Errors.Types: TyFamsDisabledFamily :: Name -> TyFamsDisabledReason
- GHC.Tc.Errors.Types: TyFamsDisabledInstance :: !TyCon -> TyFamsDisabledReason
+ GHC.Tc.Errors.Types: TyFamsDisabledInstance :: TyCon -> TyFamsDisabledReason
- GHC.Tc.Errors.Types: TyVarMissingInEnv :: !TyVar -> RoleValidationFailedReason
+ GHC.Tc.Errors.Types: TyVarMissingInEnv :: TyVar -> RoleValidationFailedReason
- GHC.Tc.Errors.Types: TyVarRoleMismatch :: !TyVar -> !Role -> RoleValidationFailedReason
+ GHC.Tc.Errors.Types: TyVarRoleMismatch :: TyVar -> Role -> RoleValidationFailedReason
- GHC.Tc.Errors.Types: TypeCannotBeMarshaled :: !Type -> TypeCannotBeMarshaledReason -> IllegalForeignTypeReason
+ GHC.Tc.Errors.Types: TypeCannotBeMarshaled :: Type -> TypeCannotBeMarshaledReason -> IllegalForeignTypeReason
- GHC.Tc.Errors.Types: TypeSigCtx :: SDoc -> HsDocContext
+ GHC.Tc.Errors.Types: TypeSigCtx :: [LocatedN RdrName] -> HsDocContext
- GHC.Tc.Errors.Types: TypedTHError :: !TypedTHError -> THError
+ GHC.Tc.Errors.Types: TypedTHError :: TypedTHError -> THError
- GHC.Tc.Errors.Types: TypedTHWithPolyType :: !TcType -> TypedTHError
+ GHC.Tc.Errors.Types: TypedTHWithPolyType :: TcType -> TypedTHError
- GHC.Tc.Errors.Types: UnknownSubordinate :: SDoc -> NotInScopeError
+ GHC.Tc.Errors.Types: UnknownSubordinate :: Name -> Subordinate -> NotInScopeError
- GHC.Tc.Errors.Types: UnusedNameImported :: !ModuleName -> UnusedNameProv
+ GHC.Tc.Errors.Types: UnusedNameImported :: ModuleName -> UnusedNameProv
- GHC.Tc.Errors.Types: YesAssocTyLastVarInKind :: !TyCon -> AssociatedTyLastVarInKind
+ GHC.Tc.Errors.Types: YesAssocTyLastVarInKind :: TyCon -> AssociatedTyLastVarInKind
- GHC.Tc.Errors.Types: YesAssociatedTyNotParamOverLastTyVar :: !TyCon -> AssociatedTyNotParamOverLastTyVar
+ GHC.Tc.Errors.Types: YesAssociatedTyNotParamOverLastTyVar :: TyCon -> AssociatedTyNotParamOverLastTyVar
- GHC.Tc.Errors.Types: [ConstrainedClassMethodsDisabled] :: !Id -> !TcPredType -> DisabledClassExtension
+ GHC.Tc.Errors.Types: [ConstrainedClassMethodsDisabled] :: Id -> TcPredType -> DisabledClassExtension
- GHC.Tc.Errors.Types: [ImportLookupAmbiguous] :: !RdrName -> ![GlobalRdrElt] -> ImportLookupReason
+ GHC.Tc.Errors.Types: [ImportLookupAmbiguous] :: RdrName -> [GlobalRdrElt] -> ImportLookupReason
- GHC.Tc.Errors.Types: [ImportLookupBad] :: BadImportKind -> ModIface -> ImpDeclSpec -> IE GhcPs -> Bool -> ImportLookupReason
+ GHC.Tc.Errors.Types: [ImportLookupBad] :: BadImportKind -> ModIface -> ImpDeclSpec -> IE GhcPs -> ImportLookupExtensions -> ImportLookupReason
- GHC.Tc.Errors.Types: [ImportLookupQualified] :: !RdrName -> ImportLookupReason
+ GHC.Tc.Errors.Types: [ImportLookupQualified] :: RdrName -> ImportLookupReason
- GHC.Tc.Errors.Types: [MultiParamDisabled] :: !Int -> DisabledClassExtension
+ GHC.Tc.Errors.Types: [MultiParamDisabled] :: Int -> DisabledClassExtension
- GHC.Tc.Errors.Types: [TcRnAmbiguousName] :: !GlobalRdrEnv -> !RdrName -> !NonEmpty GlobalRdrElt -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnAmbiguousName] :: GlobalRdrEnv -> RdrName -> NonEmpty GlobalRdrElt -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnArityMismatch] :: !TyThing -> !Arity -> !Arity -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnArityMismatch] :: TyThing -> Arity -> Arity -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnBadFieldAnnotation] :: !Int -> !DataCon -> !BadFieldAnnotationReason -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnBadFieldAnnotation] :: Int -> DataCon -> BadFieldAnnotationReason -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnBadGenericMethod] :: !Name -> !Name -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnBadGenericMethod] :: Name -> Name -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnBadMethodErr] :: !Name -> !Name -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnBadMethodErr] :: Name -> Name -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnBadQuantPredHead] :: !Type -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnBadQuantPredHead] :: Type -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnBadTyConTelescope] :: !TyCon -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnBadTyConTelescope] :: TyCon -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnBangOnUnliftedType] :: !Type -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnBangOnUnliftedType] :: Type -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnBindingNameConflict] :: !RdrName -> !NonEmpty SrcSpan -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnBindingNameConflict] :: RdrName -> NonEmpty SrcSpan -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnBootMismatch] :: !HsBootOrSig -> !BootMismatch -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnBootMismatch] :: HsBootOrSig -> BootMismatch -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnCTupleTooLarge] :: !Int -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnCTupleTooLarge] :: Int -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnCannotBindScopedTyVarInPatSig] :: !NonEmpty (Name, TcTyVar) -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnCannotBindScopedTyVarInPatSig] :: NonEmpty (Name, TcTyVar) -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnCannotBindTyVarsInPatBind] :: !NonEmpty (Name, TcTyVar) -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnCannotBindTyVarsInPatBind] :: NonEmpty (Name, TcTyVar) -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnCannotDefaultKindVar] :: !TyVar -> !Kind -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnCannotDefaultKindVar] :: TyVar -> Kind -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnCannotDeriveInstance] :: !Class -> [Type] -> !Maybe (DerivStrategy GhcTc) -> !UsingGeneralizedNewtypeDeriving -> !DeriveInstanceErrReason -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnCannotDeriveInstance] :: Class -> [Type] -> Maybe (DerivStrategy GhcTc) -> UsingGeneralizedNewtypeDeriving -> DeriveInstanceErrReason -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnCharLiteralOutOfRange] :: !Char -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnCharLiteralOutOfRange] :: Char -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnClassExtensionDisabled] :: !Class -> !DisabledClassExtension -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnClassExtensionDisabled] :: Class -> DisabledClassExtension -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnClassKindNotConstraint] :: !Kind -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnClassKindNotConstraint] :: Kind -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnCommonFieldResultTypeMismatch] :: !DataCon -> !DataCon -> !FieldLabelString -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnCommonFieldResultTypeMismatch] :: DataCon -> DataCon -> FieldLabelString -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnCommonFieldTypeMismatch] :: !DataCon -> !DataCon -> !FieldLabelString -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnCommonFieldTypeMismatch] :: DataCon -> DataCon -> FieldLabelString -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnConstraintInKind] :: !Type -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnConstraintInKind] :: Type -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnDataConParentTypeMismatch] :: !DataCon -> !Type -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnDataConParentTypeMismatch] :: DataCon -> Type -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnDefaultSigMismatch] :: !Id -> !Type -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnDefaultSigMismatch] :: Id -> Type -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnDeprecatedModule] :: !ModuleName -> !WarningTxt GhcRn -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnDeprecatedModule] :: ModuleName -> WarningTxt GhcRn -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnDerivingDefaults] :: !Class -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnDerivingDefaults] :: Class -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnDifferentExportWarnings] :: !Name -> NonEmpty SrcSpan -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnDifferentExportWarnings] :: Name -> NonEmpty SrcSpan -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnDifferentNamesForTyVar] :: !Name -> !Name -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnDifferentNamesForTyVar] :: Name -> Name -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnDisconnectedTyVar] :: !Name -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnDisconnectedTyVar] :: Name -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnDodgyImports] :: !DodgyImportsReason -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnDodgyImports] :: DodgyImportsReason -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnDupInstanceDecls] :: !UnitState -> NonEmpty ClsInst -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnDupInstanceDecls] :: UnitState -> NonEmpty ClsInst -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnDuplicateDecls] :: !OccName -> !NonEmpty Name -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnDuplicateDecls] :: OccName -> NonEmpty Name -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnDuplicateFieldName] :: !RecordFieldPart -> NonEmpty RdrName -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnDuplicateFieldName] :: RecordFieldPart -> NonEmpty RdrName -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnDuplicateWarningDecls] :: !LocatedN RdrName -> !RdrName -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnDuplicateWarningDecls] :: LocatedN RdrName -> RdrName -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnEmptyCase] :: !HsMatchContextRn -> !BadEmptyCaseReason -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnEmptyCase] :: HsMatchContextRn -> BadEmptyCaseReason -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnEmptyDataDeclsDisabled] :: !Name -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnEmptyDataDeclsDisabled] :: Name -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnExistentialQuantificationDisabled] :: !DataCon -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnExistentialQuantificationDisabled] :: DataCon -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnExpectedValueId] :: !TcTyThing -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnExpectedValueId] :: TcTyThing -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnForAllEscapeError] :: !Type -> !Kind -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnForAllEscapeError] :: Type -> Kind -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnForAllRankErr] :: !Rank -> !Type -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnForAllRankErr] :: Rank -> Type -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnFunDepConflict] :: !UnitState -> NonEmpty ClsInst -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnFunDepConflict] :: UnitState -> NonEmpty ClsInst -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnGADTDataContext] :: !Name -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnGADTDataContext] :: Name -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnGADTsDisabled] :: !Name -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnGADTsDisabled] :: Name -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnGhciUnliftedBind] :: !Id -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnGhciUnliftedBind] :: Id -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnHasFieldResolvedIncomplete] :: !Name -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnHasFieldResolvedIncomplete] :: Name -> [ConLike] -> Int -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnHsigFixityMismatch] :: !TyThing -> !Fixity -> !Fixity -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnHsigFixityMismatch] :: TyThing -> Fixity -> Fixity -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnHsigMissingModuleExport] :: !OccName -> !UnitState -> !Module -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnHsigMissingModuleExport] :: OccName -> UnitState -> Module -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnHsigShapeMismatch] :: !HsigShapeMismatchReason -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnHsigShapeMismatch] :: HsigShapeMismatchReason -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnIgnoreSpecialisePragmaOnDefMethod] :: !Name -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnIgnoreSpecialisePragmaOnDefMethod] :: Name -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnIllegalBuiltinSyntax] :: SDoc -> RdrName -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnIllegalBuiltinSyntax] :: SigLike -> RdrName -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnIllegalConstraintSynonymOfKind] :: !Type -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnIllegalConstraintSynonymOfKind] :: Type -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnIllegalDataCon] :: !RdrName -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnIllegalDataCon] :: RdrName -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnIllegalDefaultClass] :: !Name -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnIllegalDefaultClass] :: Name -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnIllegalDerivingItem] :: !LHsSigType GhcRn -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnIllegalDerivingItem] :: LHsSigType GhcRn -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnIllegalFieldPunning] :: !Located RdrName -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnIllegalFieldPunning] :: Located RdrName -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnIllegalForeignType] :: !Maybe ArgOrResult -> !IllegalForeignTypeReason -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnIllegalForeignType] :: Maybe ArgOrResult -> IllegalForeignTypeReason -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnIllegalHsBootOrSigDecl] :: !HsBootOrSig -> !BadBootDecls -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnIllegalHsBootOrSigDecl] :: HsBootOrSig -> BadBootDecls -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnIllegalHsigDefaultMethods] :: !Name -> NonEmpty (LHsBind GhcRn) -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnIllegalHsigDefaultMethods] :: Name -> NonEmpty (LHsBind GhcRn) -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnIllegalImplicitParam] :: !Type -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnIllegalImplicitParam] :: Type -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnIllegalInferredTyVars] :: !NonEmpty (HsTyVarBndr Specificity GhcPs) -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnIllegalInferredTyVars] :: NonEmpty (HsTyVarBndr Specificity GhcPs) -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnIllegalInvisTyVarBndr] :: !LHsTyVarBndr (HsBndrVis GhcRn) GhcRn -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnIllegalInvisTyVarBndr] :: LHsTyVarBndr (HsBndrVis GhcRn) GhcRn -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnIllegalInvisibleTypePattern] :: HsTyPat GhcPs -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnIllegalInvisibleTypePattern] :: HsTyPat GhcRn -> BadInvisPatReason -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnIllegalNamedDefault] :: !LDefaultDecl GhcRn -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnIllegalNamedDefault] :: LDefaultDecl GhcRn -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnIllegalPatSynDecl] :: !LIdP GhcPs -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnIllegalPatSynDecl] :: LIdP GhcPs -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnIllegalRecordSyntax] :: Either (HsType GhcPs) (HsType GhcRn) -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnIllegalRecordSyntax] :: HsType GhcPs -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnIllegalRoleAnnotation] :: !RoleAnnotDecl GhcRn -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnIllegalRoleAnnotation] :: RoleAnnotDecl GhcRn -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnIllegalTermLevelUse] :: !Name -> !TermLevelUseErr -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnIllegalTermLevelUse] :: Bool -> RdrName -> Name -> TermLevelUseErr -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnIllegalTupleConstraint] :: !Type -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnIllegalTupleConstraint] :: Type -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnIllegalTypeOperatorDecl] :: !RdrName -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnIllegalTypeOperatorDecl] :: RdrName -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnIllegalTypeOperator] :: !SDoc -> !RdrName -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnIllegalTypeOperator] :: SDoc -> RdrName -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnIllegalViewPattern] :: !Pat GhcPs -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnIllegalViewPattern] :: Pat GhcPs -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnIllegalWildcardInType] :: Maybe Name -> !BadAnonWildcardContext -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnIllegalWildcardInType] :: Maybe Name -> BadAnonWildcardContext -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnIllegalWildcardTyVarBndr] :: !LHsTyVarBndr (HsBndrVis GhcRn) GhcRn -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnIllegalWildcardTyVarBndr] :: LHsTyVarBndr (HsBndrVis GhcRn) GhcRn -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnIllegalWildcardsInConstructor] :: !Name -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnIllegalWildcardsInConstructor] :: Name -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnIllegalWildcardsInRecord] :: !RecordFieldPart -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnIllegalWildcardsInRecord] :: RecordFieldPart -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnIllformedTypeArgument] :: !LHsExpr GhcRn -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnIllformedTypeArgument] :: LHsExpr GhcRn -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnIllformedTypePattern] :: !Pat GhcRn -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnIllformedTypePattern] :: Pat GhcRn -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnImplicitLift] :: Name -> !ErrInfo -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnImplicitLift] :: Name -> [ErrCtxtMsg] -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnImportLookup] :: !ImportLookupReason -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnImportLookup] :: ImportLookupReason -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnIncoherentRoles] :: !TyCon -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnIncoherentRoles] :: TyCon -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnIncompleteExportWarnings] :: !Name -> NonEmpty SrcSpan -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnIncompleteExportWarnings] :: Name -> NonEmpty SrcSpan -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnInterfaceError] :: !IfaceMessage -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnInterfaceError] :: IfaceMessage -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnInvalidCIdentifier] :: !CLabelString -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnInvalidCIdentifier] :: CLabelString -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnInvalidDefaultedTyVar] :: ![Ct] -> [(TcTyVar, Type)] -> NonEmpty TcTyVar -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnInvalidDefaultedTyVar] :: [Ct] -> [(TcTyVar, Type)] -> NonEmpty TcTyVar -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnInvalidInvisTyVarBndr] :: !Name -> !LHsTyVarBndr (HsBndrVis GhcRn) GhcRn -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnInvalidInvisTyVarBndr] :: Name -> LHsTyVarBndr (HsBndrVis GhcRn) GhcRn -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnInvalidRecordField] :: !Name -> !FieldLabelString -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnInvalidRecordField] :: Name -> FieldLabelString -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnInvalidReturnKind] :: !DataSort -> !AllowedDataResKind -> !Kind -> !Maybe SuggestUnliftedTypes -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnInvalidReturnKind] :: DataSort -> AllowedDataResKind -> Kind -> Maybe SuggestUnliftedTypes -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnInvalidVisibleKindArgument] :: !LHsType GhcRn -> !Type -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnInvalidVisibleKindArgument] :: LHsType GhcRn -> Type -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnInvalidWarningCategory] :: !WarningCategory -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnInvalidWarningCategory] :: WarningCategory -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnInvisBndrWithoutSig] :: !Name -> !LHsTyVarBndr (HsBndrVis GhcRn) GhcRn -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnInvisBndrWithoutSig] :: Name -> LHsTyVarBndr (HsBndrVis GhcRn) GhcRn -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnKindSignaturesDisabled] :: !Either (HsType GhcPs) (Name, HsType GhcRn) -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnKindSignaturesDisabled] :: Either (HsType GhcPs) (Name, HsType GhcRn) -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnLazyBangOnUnliftedType] :: !Type -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnLazyBangOnUnliftedType] :: Type -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnLinearFuncInKind] :: !Type -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnLinearFuncInKind] :: Type -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnLinearPatSyn] :: !Type -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnLinearPatSyn] :: Type -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnLookupInstance] :: !Class -> ![Type] -> !LookupInstanceErrReason -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnLookupInstance] :: Class -> [Type] -> LookupInstanceErrReason -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnMatchesHaveDiffNumArgs] :: !HsMatchContextRn -> !MatchArgBadMatches -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnMatchesHaveDiffNumArgs] :: HsMatchContextRn -> MatchArgBadMatches -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnMessageWithInfo] :: !UnitState -> !TcRnMessageDetailed -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnMessageWithInfo] :: UnitState -> TcRnMessageDetailed -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnMissingMain] :: !Bool -> !Module -> !OccName -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnMissingMain] :: Bool -> Module -> OccName -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnMultipleConForNewtype] :: !Name -> !Int -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnMultipleConForNewtype] :: Name -> Int -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnMultipleDefaultDeclarations] :: Class -> [LDefaultDecl GhcRn] -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnMultipleDefaultDeclarations] :: Class -> ClassDefaults -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnMultipleInlinePragmas] :: !Id -> !LocatedA InlinePragma -> !NonEmpty (LocatedA InlinePragma) -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnMultipleInlinePragmas] :: Id -> LocatedA InlinePragma -> NonEmpty (LocatedA InlinePragma) -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnNestedForallsContexts] :: !NestedForallsContextsIn -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnNestedForallsContexts] :: NestedForallsContextsIn -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnNoExplicitImportList] :: !ModuleName -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnNoExplicitImportList] :: ModuleName -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnNonCanonicalDefinition] :: !NonCanonicalDefinition -> !LHsSigType GhcRn -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnNonCanonicalDefinition] :: NonCanonicalDefinition -> LHsSigType GhcRn -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnNonOverloadedSpecialisePragma] :: !LIdP GhcRn -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnNonOverloadedSpecialisePragma] :: LIdP GhcRn -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnNonTypeVarArgInConstraint] :: !Type -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnNonTypeVarArgInConstraint] :: Type -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnNonUnaryTypeclassConstraint] :: !UserTypeCtxt -> !TypedThing -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnNonUnaryTypeclassConstraint] :: UserTypeCtxt -> TypedThing -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnNotInScope] :: NotInScopeError -> RdrName -> [ImportError] -> [GhcHint] -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnNotInScope] :: NotInScopeError -> RdrName -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnOversaturatedVisibleKindArg] :: !Type -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnOversaturatedVisibleKindArg] :: Type -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnPartialFieldSelector] :: !FieldLabel -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnPartialFieldSelector] :: FieldLabel -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnPartialTypeSignatures] :: !SuggestPartialTypeSignatures -> !ThetaType -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnPartialTypeSignatures] :: SuggestPartialTypeSignatures -> ThetaType -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnPatSynArityMismatch] :: !Name -> !Arity -> !Arity -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnPatSynArityMismatch] :: Name -> Arity -> Arity -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnPatSynEscapedCoercion] :: !Id -> !NonEmpty CoVar -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnPatSynEscapedCoercion] :: Id -> NonEmpty CoVar -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnPatSynExistentialInResult] :: !Name -> !TcSigmaType -> ![TyVar] -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnPatSynExistentialInResult] :: Name -> TcSigmaType -> [TyVar] -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnPatSynInvalidRhs] :: !Name -> !LPat GhcRn -> ![LIdP GhcRn] -> !PatSynInvalidRhsReason -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnPatSynInvalidRhs] :: Name -> LPat GhcRn -> [LIdP GhcRn] -> PatSynInvalidRhsReason -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnPatSynNotBidirectional] :: !Name -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnPatSynNotBidirectional] :: Name -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnQualifiedBinder] :: !RdrName -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnQualifiedBinder] :: RdrName -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnRecSelectorEscapedTyVar] :: !OccName -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnRecSelectorEscapedTyVar] :: OccName -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnRedundantSourceImport] :: !ModuleName -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnRedundantSourceImport] :: ModuleName -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnRoleAnnotationsDisabled] :: !TyCon -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnRoleAnnotationsDisabled] :: TyCon -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnRoleCountMismatch] :: !Int -> !LRoleAnnotDecl GhcRn -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnRoleCountMismatch] :: Int -> LRoleAnnotDecl GhcRn -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnRoleMismatch] :: !Name -> !Role -> !Role -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnRoleMismatch] :: Name -> Role -> Role -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnRoleValidationFailed] :: !Role -> !RoleValidationFailedReason -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnRoleValidationFailed] :: Role -> RoleValidationFailedReason -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnSafeImportsDisabled] :: !ModuleName -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnSafeImportsDisabled] :: ModuleName -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnSelfImport] :: !ModuleName -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnSelfImport] :: ModuleName -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnSimplifiableConstraint] :: !PredType -> !InstanceWhat -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnSimplifiableConstraint] :: PredType -> InstanceWhat -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnSimplifierTooManyIterations] :: Cts -> !IntWithInf -> WantedConstraints -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnSimplifierTooManyIterations] :: Cts -> IntWithInf -> WantedConstraints -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnSkolemEscape] :: ![TcTyVar] -> !TcTyVar -> !Type -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnSkolemEscape] :: [TcTyVar] -> TcTyVar -> Type -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnSolverDepthError] :: !Type -> !SubGoalDepth -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnSolverDepthError] :: Type -> SubGoalDepth -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnSpecialiseNotVisible] :: !Name -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnSpecialiseNotVisible] :: Name -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnSuperclassCycle] :: !SuperclassCycle -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnSuperclassCycle] :: SuperclassCycle -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnTermNameInType] :: RdrName -> [GhcHint] -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnTermNameInType] :: RdrName -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnTooManyBinders] :: !Kind -> ![LHsTyVarBndr (HsBndrVis GhcRn) GhcRn] -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnTooManyBinders] :: Kind -> [LHsTyVarBndr (HsBndrVis GhcRn) GhcRn] -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnTupleConstraintInst] :: !Class -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnTupleConstraintInst] :: Class -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnTupleTooLarge] :: !Int -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnTupleTooLarge] :: Int -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnTyFamResultDisabled] :: !Name -> !LHsTyVarBndr () GhcRn -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnTyFamResultDisabled] :: Name -> LHsTyVarBndr () GhcRn -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnTyFamsDisabled] :: !TyFamsDisabledReason -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnTyFamsDisabled] :: TyFamsDisabledReason -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnTyThingUsedWrong] :: !WrongThingSort -> !TcTyThing -> !Name -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnTyThingUsedWrong] :: WrongThingSort -> TcTyThing -> Name -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnTypeApplicationsDisabled] :: !TypeApplication -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnTypeApplicationsDisabled] :: HsType GhcPs -> TypeOrKind -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnTypeDataForbids] :: !TypeDataForbids -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnTypeDataForbids] :: TypeDataForbids -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnTypeDoesNotHaveFixedRuntimeRep] :: !Type -> !FixedRuntimeRepProvenance -> !ErrInfo -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnTypeDoesNotHaveFixedRuntimeRep] :: Type -> FixedRuntimeRepProvenance -> [ErrCtxtMsg] -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnTypeSynonymCycle] :: !TySynCycleTyCons -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnTypeSynonymCycle] :: TySynCycleTyCons -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnUnboxedTupleOrSumTypeFuncArg] :: UnboxedTupleOrSum -> !Type -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnUnboxedTupleOrSumTypeFuncArg] :: UnboxedTupleOrSum -> Type -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnUnexpectedAnnotation] :: !HsType GhcRn -> !HsBang -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnUnexpectedAnnotation] :: HsType GhcPs -> HsSrcBang -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnUnexpectedPragmas] :: !Id -> !NonEmpty (LSig GhcRn) -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnUnexpectedPragmas] :: Id -> NonEmpty (LSig GhcRn) -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnUninferrableTyVar] :: ![TyCoVar] -> !UninferrableTyVarCtx -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnUninferrableTyVar] :: [TyCoVar] -> UninferrableTyVarCtx -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnUnknownMessage] :: UnknownDiagnostic (DiagnosticOpts TcRnMessage) -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnUnknownMessage] :: UnknownDiagnosticFor TcRnMessage -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnUnpromotableThing] :: !Name -> !PromotionErr -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnUnpromotableThing] :: Name -> PromotionErr -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnUnusedImport] :: !ImportDecl GhcRn -> !UnusedImportReason -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnUnusedImport] :: ImportDecl GhcRn -> UnusedImportReason -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnUnusedName] :: !OccName -> !UnusedNameProv -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnUnusedName] :: OccName -> UnusedNameProv -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnUnusedRecordWildcard] :: ![Name] -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnUnusedRecordWildcard] :: [Name] -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnUserTypeError] :: !Type -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnUserTypeError] :: Type -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnVDQInTermType] :: !Maybe Type -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnVDQInTermType] :: Maybe Type -> TcRnMessage
- GHC.Tc.Errors.Types: [TcRnWithHsDocContext] :: !HsDocContext -> !TcRnMessage -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnWithHsDocContext] :: HsDocContext -> TcRnMessage -> TcRnMessage
- GHC.Tc.Errors.Types: [UnusedImportNameRecField] :: !Parent -> !OccName -> UnusedImportName
+ GHC.Tc.Errors.Types: [UnusedImportNameRecField] :: Parent -> OccName -> UnusedImportName
- GHC.Tc.Errors.Types: [UnusedImportNameRegular] :: !Name -> UnusedImportName
+ GHC.Tc.Errors.Types: [UnusedImportNameRegular] :: Name -> UnusedImportName
- GHC.Tc.Errors.Types: [UnusedImportSome] :: ![UnusedImportName] -> UnusedImportReason
+ GHC.Tc.Errors.Types: [UnusedImportSome] :: [UnusedImportName] -> UnusedImportReason
- GHC.Tc.Errors.Types: [ZonkerCannotDefaultConcrete] :: !FixedRuntimeRepOrigin -> ZonkerMessage
+ GHC.Tc.Errors.Types: [ZonkerCannotDefaultConcrete] :: FixedRuntimeRepOrigin -> ZonkerMessage
- GHC.Tc.Errors.Types: [alsoFailedLICC] :: FailedCoverageCondition -> !Bool
+ GHC.Tc.Errors.Types: [alsoFailedLICC] :: FailedCoverageCondition -> Bool
- GHC.Tc.Errors.Types: [errInfoContext] :: ErrInfo -> !SDoc
+ GHC.Tc.Errors.Types: [errInfoContext] :: ErrInfo -> [ErrCtxtMsg]
- GHC.Tc.Errors.Types: [errInfoSupplementary] :: ErrInfo -> !SDoc
+ GHC.Tc.Errors.Types: [errInfoSupplementary] :: ErrInfo -> Maybe (HoleFitDispConfig, [SupplementaryInfo])
- GHC.Tc.Errors.Types: [sr_supplementary] :: SolverReport -> [SolverReportSupplementary]
+ GHC.Tc.Errors.Types: [sr_supplementary] :: SolverReport -> [SupplementaryInfo]
- GHC.Tc.Errors.Types: [tcOptsIfaceOpts] :: TcRnMessageOpts -> !IfaceMessageOpts
+ GHC.Tc.Errors.Types: [tcOptsIfaceOpts] :: TcRnMessageOpts -> IfaceMessageOpts
- GHC.Tc.Errors.Types: [tcOptsShowContext] :: TcRnMessageOpts -> !Bool
+ GHC.Tc.Errors.Types: [tcOptsShowContext] :: TcRnMessageOpts -> Bool
- GHC.Tc.Errors.Types: mkTcRnUnknownMessage :: (Diagnostic a, Typeable a, DiagnosticOpts a ~ NoDiagnosticOpts) => a -> TcRnMessage
+ GHC.Tc.Errors.Types: mkTcRnUnknownMessage :: (Diagnostic a, Typeable a, DiagnosticOpts a ~ NoDiagnosticOpts, DiagnosticHint a ~ DiagnosticHint TcRnMessage) => a -> TcRnMessage
- GHC.Tc.Gen.Bind: tcLocalBinds :: HsLocalBinds GhcRn -> TcM thing -> TcM (HsLocalBinds GhcTc, HsWrapper, thing)
+ GHC.Tc.Gen.Bind: tcLocalBinds :: HsLocalBinds GhcRn -> TcM thing -> TcM (HsLocalBinds GhcTc, thing)
- GHC.Tc.Gen.Bind: tcValBinds :: TopLevelFlag -> [(RecFlag, LHsBinds GhcRn)] -> [LSig GhcRn] -> TcM thing -> TcM ([(RecFlag, LHsBinds GhcTc)], HsWrapper, thing)
+ GHC.Tc.Gen.Bind: tcValBinds :: TopLevelFlag -> [(RecFlag, LHsBinds GhcRn)] -> [LSig GhcRn] -> TcM thing -> TcM ([(RecFlag, LHsBinds GhcTc)], thing)
- GHC.Tc.Gen.Export: exports_from_avail :: Maybe (LocatedLI [LIE GhcPs]) -> GlobalRdrEnv -> ImportAvails -> Module -> RnM (Maybe [(LIE GhcRn, DefaultEnv, Avails)], Avails, ExportWarnNames GhcRn)
+ GHC.Tc.Gen.Export: exports_from_avail :: Maybe (LocatedLI [LIE GhcPs]) -> GlobalRdrEnv -> ImportAvails -> Module -> RnM (Maybe [(LIE GhcRn, Avails)], DefaultEnv, Avails, ExportWarnNames GhcRn)
- GHC.Tc.Gen.Head: [ETypeArg] :: forall (p :: TcPass). AppCtxt -> LHsWcType GhcRn -> !XETAType p -> HsExprArg p
+ GHC.Tc.Gen.Head: [ETypeArg] :: forall (p :: TcPass). AppCtxt -> LHsWcType GhcRn -> XETAType p -> HsExprArg p
- GHC.Tc.Gen.Head: [EValArg] :: forall (p :: TcPass). AppCtxt -> !XEVAType p -> LHsExpr (GhcPass (XPass p)) -> HsExprArg p
+ GHC.Tc.Gen.Head: [EValArg] :: forall (p :: TcPass). AppCtxt -> XEVAType p -> LHsExpr (GhcPass (XPass p)) -> HsExprArg p
- GHC.Tc.Gen.Head: tcInferId :: Name -> TcM (HsExpr GhcTc, TcSigmaType)
+ GHC.Tc.Gen.Head: tcInferId :: LocatedN (WithUserRdr Name) -> TcM (HsExpr GhcTc, TcSigmaType)
- GHC.Tc.Gen.HsType: addSigCtxt :: Outputable hs_ty => UserTypeCtxt -> LocatedA hs_ty -> TcM a -> TcM a
+ GHC.Tc.Gen.HsType: addSigCtxt :: UserTypeCtxt -> UserSigType GhcRn -> TcM a -> TcM a
- GHC.Tc.Gen.HsType: etaExpandAlgTyCon :: TyConFlavour tc -> SkolemInfo -> [TcTyConBinder] -> Kind -> TcM ([TcTyConBinder], Kind)
+ GHC.Tc.Gen.HsType: etaExpandAlgTyCon :: SkolemInfo -> [TcTyConBinder] -> Kind -> TcM ([TcTyConBinder], Kind)
- GHC.Tc.Gen.HsType: tcMult :: HsArrow GhcRn -> TcM Mult
+ GHC.Tc.Gen.HsType: tcMult :: LHsType GhcRn -> TcM Mult
- GHC.Tc.Gen.Match: tcCaseMatches :: (AnnoBody body, Outputable (body GhcTc)) => HsMatchContextRn -> TcMatchAltChecker body -> Scaled TcSigmaTypeFRR -> MatchGroup GhcRn (LocatedA (body GhcRn)) -> ExpRhoType -> TcM (HsWrapper, MatchGroup GhcTc (LocatedA (body GhcTc)))
+ GHC.Tc.Gen.Match: tcCaseMatches :: (AnnoBody body, Outputable (body GhcTc)) => HsMatchContextRn -> TcMatchAltChecker body -> Scaled TcSigmaTypeFRR -> MatchGroup GhcRn (LocatedA (body GhcRn)) -> ExpRhoType -> TcM (MatchGroup GhcTc (LocatedA (body GhcTc)))
- GHC.Tc.Gen.Splice: tcTypedSplice :: Name -> LHsExpr GhcRn -> ExpRhoType -> TcM (HsExpr GhcTc)
+ GHC.Tc.Gen.Splice: tcTypedSplice :: HsTypedSpliceResult -> HsTypedSplice GhcRn -> ExpRhoType -> TcM (HsExpr GhcTc)
- GHC.Tc.Instance.Class: matchEqualityInst :: Class -> [Type] -> (DataCon, Role, Type, Type)
+ GHC.Tc.Instance.Class: matchEqualityInst :: Class -> [Type] -> (Role, Type, Type)
- GHC.Tc.Instance.Class: matchGlobalInst :: DynFlags -> Bool -> Class -> [Type] -> TcM ClsInstResult
+ GHC.Tc.Instance.Class: matchGlobalInst :: DynFlags -> Bool -> Class -> [Type] -> Maybe CtLoc -> TcM ClsInstResult
- GHC.Tc.Solver: approximateWC :: Bool -> WantedConstraints -> Cts
+ GHC.Tc.Solver: approximateWC :: Bool -> WantedConstraints -> Bag Ct
- GHC.Tc.Solver: simplifyInfer :: TcLevel -> InferMode -> [TcIdSigInst] -> [(Name, TcTauType)] -> WantedConstraints -> TcM ([TcTyVar], [EvVar], TcEvBinds, Bool)
+ GHC.Tc.Solver: simplifyInfer :: TopLevelFlag -> TcLevel -> InferMode -> [TcIdSigInst] -> [(Name, TcTauType)] -> WantedConstraints -> TcM ([TcTyVar], [EvVar], TcEvBinds, Bool)
- GHC.Tc.Solver.InertSet: IC :: InertEqs -> InertFunEqs -> DictMap DictCt -> [QCInst] -> DictMap DictCt -> InertIrreds -> TcLevel -> Bool -> InertCans
+ GHC.Tc.Solver.InertSet: IC :: InertEqs -> InertFunEqs -> DictMap DictCt -> [QCInst] -> InertIrreds -> TcLevel -> Bool -> InertCans
- GHC.Tc.Solver.InertSet: IS :: InertCans -> CycleBreakerVarStack -> FunEqMap Reduction -> DictMap DictCt -> InertSet
+ GHC.Tc.Solver.InertSet: IS :: InertCans -> InertCans -> CycleBreakerVarStack -> FunEqMap Reduction -> DictMap DictCt -> DictMap DictCt -> InertSet
- GHC.Tc.Solver.InertSet: WL :: [Ct] -> [Ct] -> [Ct] -> [Ct] -> Bag Implication -> WorkList
+ GHC.Tc.Solver.InertSet: WL :: [Ct] -> [Ct] -> [Ct] -> [Ct] -> WorkList
- GHC.Tc.Solver.InertSet: [inert_safehask] :: InertCans -> DictMap DictCt
+ GHC.Tc.Solver.InertSet: [inert_safehask] :: InertSet -> DictMap DictCt
- GHC.Tc.Solver.Monad: ContinueWith :: !a -> StopOrContinue a
+ GHC.Tc.Solver.Monad: ContinueWith :: a -> StopOrContinue a
- GHC.Tc.Solver.Monad: Fresh :: CtEvidence -> MaybeNew
+ GHC.Tc.Solver.Monad: Fresh :: WantedCtEvidence -> MaybeNew
- GHC.Tc.Solver.Monad: QCI :: CtEvidence -> [TcTyVar] -> TcPredType -> ExpansionFuel -> QCInst
+ GHC.Tc.Solver.Monad: QCI :: CtEvidence -> [TcTyVar] -> TcThetaType -> TcPredType -> ExpansionFuel -> QCInst
- GHC.Tc.Solver.Monad: freshGoals :: [MaybeNew] -> [CtEvidence]
+ GHC.Tc.Solver.Monad: freshGoals :: [MaybeNew] -> [WantedCtEvidence]
- GHC.Tc.Solver.Monad: getTcEvTyCoVars :: EvBindsVar -> TcS TyCoVarSet
+ GHC.Tc.Solver.Monad: getTcEvTyCoVars :: EvBindsVar -> TcS [TcCoercion]
- GHC.Tc.Solver.Monad: getUnsolvedInerts :: TcS (Bag Implication, Cts)
+ GHC.Tc.Solver.Monad: getUnsolvedInerts :: TcS Cts
- GHC.Tc.Solver.Monad: lookupFamAppInert :: (CtFlavourRole -> Bool) -> TyCon -> [Type] -> TcS (Maybe (Reduction, CtFlavourRole))
+ GHC.Tc.Solver.Monad: lookupFamAppInert :: (CtFlavourRole -> Bool) -> TyCon -> [Type] -> TcS (Maybe EqCt)
- GHC.Tc.Solver.Monad: lookupInertDict :: InertCans -> CtLoc -> Class -> [Type] -> Maybe DictCt
+ GHC.Tc.Solver.Monad: lookupInertDict :: InertCans -> Class -> [Type] -> Maybe DictCt
- GHC.Tc.Solver.Monad: lookupSolvedDict :: InertSet -> CtLoc -> Class -> [Type] -> Maybe CtEvidence
+ GHC.Tc.Solver.Monad: lookupSolvedDict :: InertSet -> Class -> [Type] -> Maybe CtEvidence
- GHC.Tc.Solver.Monad: matchGlobalInst :: DynFlags -> Bool -> Class -> [Type] -> CtLoc -> TcS ClsInstResult
+ GHC.Tc.Solver.Monad: matchGlobalInst :: DynFlags -> Class -> [Type] -> CtLoc -> TcS ClsInstResult
- GHC.Tc.Solver.Monad: newGivenEvVar :: CtLoc -> (TcPredType, EvTerm) -> TcS CtEvidence
+ GHC.Tc.Solver.Monad: newGivenEvVar :: CtLoc -> (TcPredType, EvTerm) -> TcS GivenCtEvidence
- GHC.Tc.Solver.Monad: newWantedEq :: CtLoc -> RewriterSet -> Role -> TcType -> TcType -> TcS (CtEvidence, Coercion)
+ GHC.Tc.Solver.Monad: newWantedEq :: CtLoc -> RewriterSet -> Role -> TcType -> TcType -> TcS (WantedCtEvidence, Coercion)
- GHC.Tc.Solver.Monad: newWantedEvVarNC :: CtLoc -> RewriterSet -> TcPredType -> TcS CtEvidence
+ GHC.Tc.Solver.Monad: newWantedEvVarNC :: CtLoc -> RewriterSet -> TcPredType -> TcS WantedCtEvidence
- GHC.Tc.Solver.Monad: newWantedNC :: CtLoc -> RewriterSet -> PredType -> TcS CtEvidence
+ GHC.Tc.Solver.Monad: newWantedNC :: CtLoc -> RewriterSet -> PredType -> TcS WantedCtEvidence
- GHC.Tc.Solver.Monad: setWantedEq :: HasDebugCallStack => TcEvDest -> Coercion -> TcS ()
+ GHC.Tc.Solver.Monad: setWantedEq :: HasDebugCallStack => TcEvDest -> TcCoercion -> TcS ()
- GHC.Tc.Solver.Types: findDict :: DictMap a -> CtLoc -> Class -> [Type] -> Maybe a
+ GHC.Tc.Solver.Types: findDict :: DictMap a -> Class -> [Type] -> Maybe a
- GHC.Tc.TyCl: kcConDecls :: Foldable f => NewOrData -> TcKind -> f (LConDecl GhcRn) -> TcM ()
+ GHC.Tc.TyCl: kcConDecls :: TcKind -> DataDefnCons (LConDecl GhcRn) -> TcM ()
- GHC.Tc.TyCl: tcAddDataFamInstCtxt :: DataFamInstDecl GhcRn -> TcM a -> TcM a
+ GHC.Tc.TyCl: tcAddDataFamInstCtxt :: AssocInstInfo -> NewOrData -> DataFamInstDecl GhcRn -> TcM a -> TcM a
- GHC.Tc.TyCl: tcMkDataFamInstCtxt :: DataFamInstDecl GhcRn -> SDoc
+ GHC.Tc.TyCl: tcMkDataFamInstCtxt :: AssocInstInfo -> NewOrData -> DataFamInstDecl GhcRn -> ErrCtxtMsg
- GHC.Tc.TyCl.Build: buildClass :: Name -> [TyConBinder] -> [Role] -> [FunDep TyVar] -> Maybe (KnotTied ThetaType, [ClassATItem], [KnotTied MethInfo], ClassMinimalDef) -> TcRnIf m n Class
+ GHC.Tc.TyCl.Build: buildClass :: Name -> [TyConBinder] -> [Role] -> [FunDep TyVar] -> KnotTied ThetaType -> [ClassATItem] -> [KnotTied MethInfo] -> ClassMinimalDef -> Bool -> TcRnIf m n Class
- GHC.Tc.TyCl.Build: buildDataCon :: FamInstEnvs -> DataConBangOpts -> Name -> Bool -> TyConRepName -> [HsSrcBang] -> [FieldLabel] -> [TyVar] -> [TyCoVar] -> [InvisTVBinder] -> [EqSpec] -> KnotTied ThetaType -> [KnotTied (Scaled Type)] -> KnotTied Type -> KnotTied TyCon -> NameEnv ConTag -> TcRnIf m n DataCon
+ GHC.Tc.TyCl.Build: buildDataCon :: FamInstEnvs -> DataConBangOpts -> Name -> Bool -> TyConRepName -> [HsSrcBang] -> [FieldLabel] -> [TyVar] -> [TyCoVar] -> [TyVarBinder] -> [EqSpec] -> KnotTied ThetaType -> [KnotTied (Scaled Type)] -> KnotTied Type -> KnotTied TyCon -> NameEnv ConTag -> TcRnIf m n DataCon
- GHC.Tc.TyCl.Class: instDeclCtxt1 :: LHsSigType GhcRn -> SDoc
+ GHC.Tc.TyCl.Class: instDeclCtxt1 :: LHsSigType GhcRn -> ErrCtxtMsg
- GHC.Tc.TyCl.Class: instDeclCtxt2 :: Type -> SDoc
+ GHC.Tc.TyCl.Class: instDeclCtxt2 :: Type -> ErrCtxtMsg
- GHC.Tc.TyCl.Class: instDeclCtxt3 :: Class -> [Type] -> SDoc
+ GHC.Tc.TyCl.Class: instDeclCtxt3 :: Class -> [Type] -> ErrCtxtMsg
- GHC.Tc.Types: Brack :: ThStage -> PendingStuff -> ThStage
+ GHC.Tc.Types: Brack :: ThLevel -> PendingStuff -> ThLevel
- GHC.Tc.Types: Comp :: ThStage
+ GHC.Tc.Types: Comp :: ThLevel
- GHC.Tc.Types: Env :: !HscEnv -> {-# UNPACK #-} !Char -> gbl -> lcl -> Env gbl lcl
+ GHC.Tc.Types: Env :: HscEnv -> Char -> gbl -> lcl -> Env gbl lcl
- GHC.Tc.Types: IfLclEnv :: !Module -> IsBootInterface -> SDoc -> Maybe NameShape -> Maybe TypeEnv -> FastStringEnv TyVar -> FastStringEnv Id -> IfLclEnv
+ GHC.Tc.Types: IfLclEnv :: Module -> IsBootInterface -> SDoc -> Maybe NameShape -> Maybe TypeEnv -> FastStringEnv TyVar -> FastStringEnv Id -> IfLclEnv
- GHC.Tc.Types: ImpUserEverythingBut :: !NameSet -> ImpUserList
+ GHC.Tc.Types: ImpUserEverythingBut :: NameSet -> ImpUserList
- GHC.Tc.Types: ImpUserExplicit :: !GlobalRdrEnv -> ImpUserList
+ GHC.Tc.Types: ImpUserExplicit :: [AvailInfo] -> NameSet -> ImpUserList
- GHC.Tc.Types: ImpUserSpec :: !ImpDeclSpec -> !ImpUserList -> ImportUserSpec
+ GHC.Tc.Types: ImpUserSpec :: ImpDeclSpec -> ImpUserList -> ImportUserSpec
- GHC.Tc.Types: ImportAvails :: ImportedMods -> InstalledModuleEnv ModuleNameWithIsBoot -> Set UnitId -> Bool -> Set UnitId -> InstalledModuleEnv ModuleNameWithIsBoot -> [ModuleName] -> [Module] -> [Module] -> ImportAvails
+ GHC.Tc.Types: ImportAvails :: ImportedMods -> InstalledModuleEnv (Set ImportLevel, ModuleNameWithIsBoot) -> Set (ImportLevel, UnitId) -> Bool -> Set UnitId -> InstalledModuleEnv ModuleNameWithIsBoot -> [ModuleName] -> [Module] -> [Module] -> ImportAvails
- GHC.Tc.Types: RE :: !CtLoc -> !CtFlavour -> !EqRel -> !TcRef RewriterSet -> RewriteEnv
+ GHC.Tc.Types: RE :: CtLoc -> CtFlavour -> EqRel -> TcRef RewriterSet -> RewriteEnv
- GHC.Tc.Types: RunSplice :: TcRef [ForeignRef (Q ())] -> ThStage
+ GHC.Tc.Types: RunSplice :: TcRef [ForeignRef (Q ())] -> ThLevel
- GHC.Tc.Types: Splice :: SpliceType -> ThStage
+ GHC.Tc.Types: Splice :: SpliceType -> ThLevel -> ThLevel
- GHC.Tc.Types: TcGblEnv :: Module -> Module -> HscSource -> GlobalRdrEnv -> DefaultEnv -> DefaultEnv -> FixityEnv -> TypeEnv -> KnotVars (IORef TypeEnv) -> !InstEnv -> !FamInstEnv -> AnnEnv -> [AvailInfo] -> ImportAvails -> ![ImportUserSpec] -> DefUses -> TcRef [GlobalRdrElt] -> TcRef NameSet -> TcRef Bool -> TcRef Bool -> TcRef ([Linkable], PkgsLoaded) -> TcRef OccSet -> TcRef Integer -> [(Module, Fingerprint)] -> Maybe [(LIE GhcRn, Avails)] -> [LImportDecl GhcRn] -> Maybe (HsGroup GhcRn) -> TcRef [FilePath] -> TcRef [LHsDecl GhcPs] -> TcRef [(ForeignSrcLang, FilePath)] -> TcRef NameSet -> TcRef [(TcLclEnv, ThModFinalizers)] -> TcRef [String] -> TcRef (Map TypeRep Dynamic) -> TcRef (Maybe (ForeignRef (IORef QState))) -> TcRef THDocs -> Bag EvBind -> Maybe Id -> LHsBinds GhcTc -> NameSet -> [LTcSpecPrag] -> Warnings GhcRn -> [Annotation] -> [TyCon] -> NameSet -> [ClsInst] -> [FamInst] -> [LRuleDecl GhcTc] -> [LForeignDecl GhcTc] -> [PatSyn] -> (Maybe (LHsDoc GhcRn), Maybe (XRec GhcRn ModuleName)) -> !AnyHpcUsage -> SelfBootInfo -> Maybe Name -> TcRef Bool -> TcRef (Messages TcRnMessage) -> [TcPluginSolver] -> UniqFM TyCon [TcPluginRewriter] -> [FillDefaulting] -> [HoleFitPlugin] -> RealSrcSpan -> TcRef WantedConstraints -> !CompleteMatches -> TcRef CostCentreState -> TcRef (ModuleEnv Int) -> TcGblEnv
+ GHC.Tc.Types: TcGblEnv :: Module -> Module -> HscSource -> GlobalRdrEnv -> DefaultEnv -> DefaultEnv -> FixityEnv -> TypeEnv -> KnotVars (IORef TypeEnv) -> InstEnv -> FamInstEnv -> AnnEnv -> CompleteMatches -> [AvailInfo] -> ImportAvails -> [ImportUserSpec] -> DefUses -> TcRef [GlobalRdrElt] -> TcRef NameSet -> TcRef Bool -> TcRef ([Linkable], PkgsLoaded) -> TcRef OccSet -> TcRef Integer -> [(Module, Fingerprint)] -> Maybe [(LIE GhcRn, Avails)] -> [LImportDecl GhcRn] -> Maybe (HsGroup GhcRn) -> TcRef [FilePath] -> TcRef [LHsDecl GhcPs] -> TcRef [(ForeignSrcLang, FilePath)] -> TcRef NameSet -> TcRef [(TcLclEnv, ThModFinalizers)] -> TcRef [String] -> TcRef (Map TypeRep Dynamic) -> TcRef (Maybe (ForeignRef (IORef QState))) -> TcRef THDocs -> Bag EvBind -> Maybe Id -> LHsBinds GhcTc -> NameSet -> [LTcSpecPrag] -> Warnings GhcRn -> [Annotation] -> [TyCon] -> NameSet -> [ClsInst] -> [FamInst] -> [LRuleDecl GhcTc] -> [LForeignDecl GhcTc] -> [PatSyn] -> (Maybe (LHsDoc GhcRn), Maybe (XRec GhcRn ModuleName)) -> SelfBootInfo -> Maybe Name -> TcRef Bool -> TcRef (Messages TcRnMessage) -> [TcPluginSolver] -> UniqFM TyCon [TcPluginRewriter] -> [FillDefaulting] -> [HoleFitPlugin] -> RealSrcSpan -> TcRef WantedConstraints -> CompleteMatches -> TcRef CostCentreState -> TcRef (ModuleEnv Int) -> TcGblEnv
- GHC.Tc.Types: TcLclCtxt :: RealSrcSpan -> [ErrCtxt] -> Bool -> TcLevel -> TcBinderStack -> LocalRdrEnv -> ThStage -> ThBindEnv -> ArrowCtxt -> TcTypeEnv -> TcLclCtxt
+ GHC.Tc.Types: TcLclCtxt :: RealSrcSpan -> [ErrCtxt] -> Bool -> TcLevel -> TcBinderStack -> LocalRdrEnv -> ThLevel -> ThBindEnv -> ArrowCtxt -> TcTypeEnv -> TcLclCtxt
- GHC.Tc.Types: TcLclEnv :: !TcLclCtxt -> TcRef UsageEnv -> TcRef WantedConstraints -> TcRef (Messages TcRnMessage) -> TcLclEnv
+ GHC.Tc.Types: TcLclEnv :: TcLclCtxt -> TcRef UsageEnv -> TcRef WantedConstraints -> TcRef (Messages TcRnMessage) -> TcLclEnv
- GHC.Tc.Types: TcPluginRewriteTo :: !Reduction -> [Ct] -> TcPluginRewriteResult
+ GHC.Tc.Types: TcPluginRewriteTo :: Reduction -> [Ct] -> TcPluginRewriteResult
- GHC.Tc.Types: [env_top] :: Env gbl lcl -> !HscEnv
+ GHC.Tc.Types: [env_top] :: Env gbl lcl -> HscEnv
- GHC.Tc.Types: [env_ut] :: Env gbl lcl -> {-# UNPACK #-} !Char
+ GHC.Tc.Types: [env_ut] :: Env gbl lcl -> Char
- GHC.Tc.Types: [if_mod] :: IfLclEnv -> !Module
+ GHC.Tc.Types: [if_mod] :: IfLclEnv -> Module
- GHC.Tc.Types: [imp_dep_direct_pkgs] :: ImportAvails -> Set UnitId
+ GHC.Tc.Types: [imp_dep_direct_pkgs] :: ImportAvails -> Set (ImportLevel, UnitId)
- GHC.Tc.Types: [imp_direct_dep_mods] :: ImportAvails -> InstalledModuleEnv ModuleNameWithIsBoot
+ GHC.Tc.Types: [imp_direct_dep_mods] :: ImportAvails -> InstalledModuleEnv (Set ImportLevel, ModuleNameWithIsBoot)
- GHC.Tc.Types: [ius_decl] :: ImportUserSpec -> !ImpDeclSpec
+ GHC.Tc.Types: [ius_decl] :: ImportUserSpec -> ImpDeclSpec
- GHC.Tc.Types: [ius_imports] :: ImportUserSpec -> !ImpUserList
+ GHC.Tc.Types: [ius_imports] :: ImportUserSpec -> ImpUserList
- GHC.Tc.Types: [re_eq_rel] :: RewriteEnv -> !EqRel
+ GHC.Tc.Types: [re_eq_rel] :: RewriteEnv -> EqRel
- GHC.Tc.Types: [re_flavour] :: RewriteEnv -> !CtFlavour
+ GHC.Tc.Types: [re_flavour] :: RewriteEnv -> CtFlavour
- GHC.Tc.Types: [re_loc] :: RewriteEnv -> !CtLoc
+ GHC.Tc.Types: [re_loc] :: RewriteEnv -> CtLoc
- GHC.Tc.Types: [re_rewriters] :: RewriteEnv -> !TcRef RewriterSet
+ GHC.Tc.Types: [re_rewriters] :: RewriteEnv -> TcRef RewriterSet
- GHC.Tc.Types: [tcPluginReduction] :: TcPluginRewriteResult -> !Reduction
+ GHC.Tc.Types: [tcPluginReduction] :: TcPluginRewriteResult -> Reduction
- GHC.Tc.Types: [tcg_complete_matches] :: TcGblEnv -> !CompleteMatches
+ GHC.Tc.Types: [tcg_complete_matches] :: TcGblEnv -> CompleteMatches
- GHC.Tc.Types: [tcg_fam_inst_env] :: TcGblEnv -> !FamInstEnv
+ GHC.Tc.Types: [tcg_fam_inst_env] :: TcGblEnv -> FamInstEnv
- GHC.Tc.Types: [tcg_import_decls] :: TcGblEnv -> ![ImportUserSpec]
+ GHC.Tc.Types: [tcg_import_decls] :: TcGblEnv -> [ImportUserSpec]
- GHC.Tc.Types: [tcg_inst_env] :: TcGblEnv -> !InstEnv
+ GHC.Tc.Types: [tcg_inst_env] :: TcGblEnv -> InstEnv
- GHC.Tc.Types: [tcl_lcl_ctxt] :: TcLclEnv -> !TcLclCtxt
+ GHC.Tc.Types: [tcl_lcl_ctxt] :: TcLclEnv -> TcLclCtxt
- GHC.Tc.Types: [tcl_th_ctxt] :: TcLclCtxt -> ThStage
+ GHC.Tc.Types: [tcl_th_ctxt] :: TcLclCtxt -> ThLevel
- GHC.Tc.Types: type ErrCtxt = (Bool, TidyEnv -> ZonkM (TidyEnv, SDoc))
+ GHC.Tc.Types: type ErrCtxt = (Bool, TidyEnv -> ZonkM (TidyEnv, ErrCtxtMsg))
- GHC.Tc.Types: type ThBindEnv = NameEnv (TopLevelFlag, ThLevel)
+ GHC.Tc.Types: type ThBindEnv = NameEnv (TopLevelFlag, ThLevelIndex)
- GHC.Tc.Types.Constraint: CtGiven :: TcPredType -> EvVar -> CtLoc -> CtEvidence
+ GHC.Tc.Types.Constraint: CtGiven :: GivenCtEvidence -> CtEvidence
- GHC.Tc.Types.Constraint: CtLocEnv :: ![ErrCtxt] -> !RealSrcSpan -> !TcBinderStack -> !TcLevel -> !Bool -> !LocalRdrEnv -> CtLocEnv
+ GHC.Tc.Types.Constraint: CtLocEnv :: [ErrCtxt] -> RealSrcSpan -> TcBinderStack -> TcLevel -> Bool -> LocalRdrEnv -> CtLocEnv
- GHC.Tc.Types.Constraint: CtWanted :: TcPredType -> TcEvDest -> CtLoc -> RewriterSet -> CtEvidence
+ GHC.Tc.Types.Constraint: CtWanted :: WantedCtEvidence -> CtEvidence
- GHC.Tc.Types.Constraint: Implic :: TcLevel -> SkolemInfoAnon -> [TcTyVar] -> [EvVar] -> HasGivenEqs -> Bool -> !CtLocEnv -> WantedConstraints -> EvBindsVar -> VarSet -> VarSet -> ImplicStatus -> Implication
+ GHC.Tc.Types.Constraint: Implic :: TcLevel -> SkolemInfoAnon -> [TcTyVar] -> [EvVar] -> HasGivenEqs -> Bool -> CtLocEnv -> WantedConstraints -> EvBindsVar -> EvNeedSet -> EvNeedSet -> ImplicStatus -> Implication
- GHC.Tc.Types.Constraint: NCE_FRR :: CtLoc -> FixedRuntimeRepOrigin -> NonEmpty NotConcreteReason -> NotConcreteError
+ GHC.Tc.Types.Constraint: NCE_FRR :: CtLoc -> FixedRuntimeRepOrigin -> NotConcreteError
- GHC.Tc.Types.Constraint: QCI :: CtEvidence -> [TcTyVar] -> TcPredType -> ExpansionFuel -> QCInst
+ GHC.Tc.Types.Constraint: QCI :: CtEvidence -> [TcTyVar] -> TcThetaType -> TcPredType -> ExpansionFuel -> QCInst
- GHC.Tc.Types.Constraint: TyFamLHS :: TyCon -> [Xi] -> CanEqLHS
+ GHC.Tc.Types.Constraint: TyFamLHS :: TyCon -> [Type] -> CanEqLHS
- GHC.Tc.Types.Constraint: TyVarLHS :: TcTyVar -> CanEqLHS
+ GHC.Tc.Types.Constraint: TyVarLHS :: TyVar -> CanEqLHS
- GHC.Tc.Types.Constraint: [ctev_dest] :: CtEvidence -> TcEvDest
+ GHC.Tc.Types.Constraint: [ctev_dest] :: WantedCtEvidence -> TcEvDest
- GHC.Tc.Types.Constraint: [ctev_evar] :: CtEvidence -> EvVar
+ GHC.Tc.Types.Constraint: [ctev_evar] :: GivenCtEvidence -> EvVar
- GHC.Tc.Types.Constraint: [ctev_loc] :: CtEvidence -> CtLoc
+ GHC.Tc.Types.Constraint: [ctev_loc] :: WantedCtEvidence -> CtLoc
- GHC.Tc.Types.Constraint: [ctev_pred] :: CtEvidence -> TcPredType
+ GHC.Tc.Types.Constraint: [ctev_pred] :: WantedCtEvidence -> TcPredType
- GHC.Tc.Types.Constraint: [ctev_rewriters] :: CtEvidence -> RewriterSet
+ GHC.Tc.Types.Constraint: [ctev_rewriters] :: WantedCtEvidence -> RewriterSet
- GHC.Tc.Types.Constraint: [ctl_bndrs] :: CtLocEnv -> !TcBinderStack
+ GHC.Tc.Types.Constraint: [ctl_bndrs] :: CtLocEnv -> TcBinderStack
- GHC.Tc.Types.Constraint: [ctl_ctxt] :: CtLocEnv -> ![ErrCtxt]
+ GHC.Tc.Types.Constraint: [ctl_ctxt] :: CtLocEnv -> [ErrCtxt]
- GHC.Tc.Types.Constraint: [ctl_in_gen_code] :: CtLocEnv -> !Bool
+ GHC.Tc.Types.Constraint: [ctl_in_gen_code] :: CtLocEnv -> Bool
- GHC.Tc.Types.Constraint: [ctl_loc] :: CtLocEnv -> !RealSrcSpan
+ GHC.Tc.Types.Constraint: [ctl_loc] :: CtLocEnv -> RealSrcSpan
- GHC.Tc.Types.Constraint: [ctl_rdr] :: CtLocEnv -> !LocalRdrEnv
+ GHC.Tc.Types.Constraint: [ctl_rdr] :: CtLocEnv -> LocalRdrEnv
- GHC.Tc.Types.Constraint: [ctl_tclvl] :: CtLocEnv -> !TcLevel
+ GHC.Tc.Types.Constraint: [ctl_tclvl] :: CtLocEnv -> TcLevel
- GHC.Tc.Types.Constraint: [ic_env] :: Implication -> !CtLocEnv
+ GHC.Tc.Types.Constraint: [ic_env] :: Implication -> CtLocEnv
- GHC.Tc.Types.Constraint: canEqLHSKind :: CanEqLHS -> TcKind
+ GHC.Tc.Types.Constraint: canEqLHSKind :: CanEqLHS -> Kind
- GHC.Tc.Types.Constraint: canEqLHSType :: CanEqLHS -> TcType
+ GHC.Tc.Types.Constraint: canEqLHSType :: CanEqLHS -> Type
- GHC.Tc.Types.Constraint: canEqLHS_maybe :: Xi -> Maybe CanEqLHS
+ GHC.Tc.Types.Constraint: canEqLHS_maybe :: Type -> Maybe CanEqLHS
- GHC.Tc.Types.Constraint: canTyFamEqLHS_maybe :: Xi -> Maybe CanEqLHS
+ GHC.Tc.Types.Constraint: canTyFamEqLHS_maybe :: Type -> Maybe CanEqLHS
- GHC.Tc.Types.CtLoc: CtLoc :: CtOrigin -> CtLocEnv -> Maybe TypeOrKind -> !SubGoalDepth -> CtLoc
+ GHC.Tc.Types.CtLoc: CtLoc :: CtOrigin -> CtLocEnv -> Maybe TypeOrKind -> SubGoalDepth -> CtLoc
- GHC.Tc.Types.CtLoc: CtLocEnv :: ![ErrCtxt] -> !RealSrcSpan -> !TcBinderStack -> !TcLevel -> !Bool -> !LocalRdrEnv -> CtLocEnv
+ GHC.Tc.Types.CtLoc: CtLocEnv :: [ErrCtxt] -> RealSrcSpan -> TcBinderStack -> TcLevel -> Bool -> LocalRdrEnv -> CtLocEnv
- GHC.Tc.Types.CtLoc: [ctl_bndrs] :: CtLocEnv -> !TcBinderStack
+ GHC.Tc.Types.CtLoc: [ctl_bndrs] :: CtLocEnv -> TcBinderStack
- GHC.Tc.Types.CtLoc: [ctl_ctxt] :: CtLocEnv -> ![ErrCtxt]
+ GHC.Tc.Types.CtLoc: [ctl_ctxt] :: CtLocEnv -> [ErrCtxt]
- GHC.Tc.Types.CtLoc: [ctl_depth] :: CtLoc -> !SubGoalDepth
+ GHC.Tc.Types.CtLoc: [ctl_depth] :: CtLoc -> SubGoalDepth
- GHC.Tc.Types.CtLoc: [ctl_in_gen_code] :: CtLocEnv -> !Bool
+ GHC.Tc.Types.CtLoc: [ctl_in_gen_code] :: CtLocEnv -> Bool
- GHC.Tc.Types.CtLoc: [ctl_loc] :: CtLocEnv -> !RealSrcSpan
+ GHC.Tc.Types.CtLoc: [ctl_loc] :: CtLocEnv -> RealSrcSpan
- GHC.Tc.Types.CtLoc: [ctl_rdr] :: CtLocEnv -> !LocalRdrEnv
+ GHC.Tc.Types.CtLoc: [ctl_rdr] :: CtLocEnv -> LocalRdrEnv
- GHC.Tc.Types.CtLoc: [ctl_tclvl] :: CtLocEnv -> !TcLevel
+ GHC.Tc.Types.CtLoc: [ctl_tclvl] :: CtLocEnv -> TcLevel
- GHC.Tc.Types.ErrCtxt: type ErrCtxt = (Bool, TidyEnv -> ZonkM (TidyEnv, SDoc))
+ GHC.Tc.Types.ErrCtxt: type ErrCtxt = (Bool, TidyEnv -> ZonkM (TidyEnv, ErrCtxtMsg))
- GHC.Tc.Types.Evidence: CoEvBindsVar :: Unique -> IORef CoVarSet -> EvBindsVar
+ GHC.Tc.Types.Evidence: CoEvBindsVar :: Unique -> IORef [TcCoercion] -> EvBindsVar
- GHC.Tc.Types.Evidence: EvBindsVar :: Unique -> IORef EvBindMap -> IORef CoVarSet -> EvBindsVar
+ GHC.Tc.Types.Evidence: EvBindsVar :: Unique -> IORef EvBindMap -> IORef [TcCoercion] -> EvBindsVar
- GHC.Tc.Types.Evidence: [ebv_tcvs] :: EvBindsVar -> IORef CoVarSet
+ GHC.Tc.Types.Evidence: [ebv_tcvs] :: EvBindsVar -> IORef [TcCoercion]
- GHC.Tc.Types.LclEnv: TcLclCtxt :: RealSrcSpan -> [ErrCtxt] -> Bool -> TcLevel -> TcBinderStack -> LocalRdrEnv -> ThStage -> ThBindEnv -> ArrowCtxt -> TcTypeEnv -> TcLclCtxt
+ GHC.Tc.Types.LclEnv: TcLclCtxt :: RealSrcSpan -> [ErrCtxt] -> Bool -> TcLevel -> TcBinderStack -> LocalRdrEnv -> ThLevel -> ThBindEnv -> ArrowCtxt -> TcTypeEnv -> TcLclCtxt
- GHC.Tc.Types.LclEnv: TcLclEnv :: !TcLclCtxt -> TcRef UsageEnv -> TcRef WantedConstraints -> TcRef (Messages TcRnMessage) -> TcLclEnv
+ GHC.Tc.Types.LclEnv: TcLclEnv :: TcLclCtxt -> TcRef UsageEnv -> TcRef WantedConstraints -> TcRef (Messages TcRnMessage) -> TcLclEnv
- GHC.Tc.Types.LclEnv: [tcl_lcl_ctxt] :: TcLclEnv -> !TcLclCtxt
+ GHC.Tc.Types.LclEnv: [tcl_lcl_ctxt] :: TcLclEnv -> TcLclCtxt
- GHC.Tc.Types.LclEnv: [tcl_th_ctxt] :: TcLclCtxt -> ThStage
+ GHC.Tc.Types.LclEnv: [tcl_th_ctxt] :: TcLclCtxt -> ThLevel
- GHC.Tc.Types.LclEnv: type ThBindEnv = NameEnv (TopLevelFlag, ThLevel)
+ GHC.Tc.Types.LclEnv: type ThBindEnv = NameEnv (TopLevelFlag, ThLevelIndex)
- GHC.Tc.Types.Origin: ArgPosVis :: !Int -> ArgPos
+ GHC.Tc.Types.Origin: ArgPosVis :: Int -> ArgPos
- GHC.Tc.Types.Origin: ArrowCmdApp :: !HsCmd GhcRn -> !HsExpr GhcRn -> FRRArrowContext
+ GHC.Tc.Types.Origin: ArrowCmdApp :: HsCmd GhcRn -> HsExpr GhcRn -> FRRArrowContext
- GHC.Tc.Types.Origin: ArrowCmdArrApp :: !HsExpr GhcRn -> !HsExpr GhcRn -> !HsArrAppType -> FRRArrowContext
+ GHC.Tc.Types.Origin: ArrowCmdArrApp :: HsExpr GhcRn -> HsExpr GhcRn -> HsArrAppType -> FRRArrowContext
- GHC.Tc.Types.Origin: ArrowCmdResTy :: !HsCmd GhcRn -> FRRArrowContext
+ GHC.Tc.Types.Origin: ArrowCmdResTy :: HsCmd GhcRn -> FRRArrowContext
- GHC.Tc.Types.Origin: ArrowFun :: !HsExpr GhcRn -> FRRArrowContext
+ GHC.Tc.Types.Origin: ArrowFun :: HsExpr GhcRn -> FRRArrowContext
- GHC.Tc.Types.Origin: DerivOriginCoerce :: Id -> Type -> Type -> Bool -> CtOrigin
+ GHC.Tc.Types.Origin: DerivOriginCoerce :: Id -> Type -> Type -> StandaloneDeriv -> CtOrigin
- GHC.Tc.Types.Origin: DerivOriginDC :: DataCon -> Int -> Bool -> CtOrigin
+ GHC.Tc.Types.Origin: DerivOriginDC :: DataCon -> Int -> StandaloneDeriv -> CtOrigin
- GHC.Tc.Types.Origin: ExpectedFunTyArg :: !TypedThing -> !HsExpr (GhcPass p) -> ExpectedFunTyOrigin
+ GHC.Tc.Types.Origin: ExpectedFunTyArg :: TypedThing -> HsExpr (GhcPass p) -> ExpectedFunTyOrigin
- GHC.Tc.Types.Origin: ExpectedFunTyLam :: HsLamVariant -> !HsExpr GhcRn -> ExpectedFunTyOrigin
+ GHC.Tc.Types.Origin: ExpectedFunTyLam :: HsLamVariant -> HsExpr GhcRn -> ExpectedFunTyOrigin
- GHC.Tc.Types.Origin: ExpectedFunTyMatches :: !TypedThing -> !MatchGroup GhcRn (LHsExpr GhcRn) -> ExpectedFunTyOrigin
+ GHC.Tc.Types.Origin: ExpectedFunTyMatches :: TypedThing -> MatchGroup GhcRn (LHsExpr GhcRn) -> ExpectedFunTyOrigin
- GHC.Tc.Types.Origin: ExpectedFunTySyntaxOp :: !CtOrigin -> !HsExpr (GhcPass p) -> ExpectedFunTyOrigin
+ GHC.Tc.Types.Origin: ExpectedFunTySyntaxOp :: CtOrigin -> HsExpr (GhcPass p) -> ExpectedFunTyOrigin
- GHC.Tc.Types.Origin: ExpectedFunTyViewPat :: !HsExpr GhcRn -> ExpectedFunTyOrigin
+ GHC.Tc.Types.Origin: ExpectedFunTyViewPat :: HsExpr GhcRn -> ExpectedFunTyOrigin
- GHC.Tc.Types.Origin: FRRArrow :: !FRRArrowContext -> FixedRuntimeRepContext
+ GHC.Tc.Types.Origin: FRRArrow :: FRRArrowContext -> FixedRuntimeRepContext
- GHC.Tc.Types.Origin: FRRBindStmt :: !StmtOrigin -> FixedRuntimeRepContext
+ GHC.Tc.Types.Origin: FRRBindStmt :: StmtOrigin -> FixedRuntimeRepContext
- GHC.Tc.Types.Origin: FRRBinder :: !Name -> FixedRuntimeRepContext
+ GHC.Tc.Types.Origin: FRRBinder :: Name -> FixedRuntimeRepContext
- GHC.Tc.Types.Origin: FRRBodyStmt :: !StmtOrigin -> !Int -> FixedRuntimeRepContext
+ GHC.Tc.Types.Origin: FRRBodyStmt :: StmtOrigin -> Int -> FixedRuntimeRepContext
- GHC.Tc.Types.Origin: FRRDataConPatArg :: !DataCon -> !Int -> FixedRuntimeRepContext
+ GHC.Tc.Types.Origin: FRRDataConPatArg :: DataCon -> Int -> FixedRuntimeRepContext
- GHC.Tc.Types.Origin: FRRExpectedFunTy :: !ExpectedFunTyOrigin -> !Int -> FixedRuntimeRepContext
+ GHC.Tc.Types.Origin: FRRExpectedFunTy :: ExpectedFunTyOrigin -> Int -> FixedRuntimeRepContext
- GHC.Tc.Types.Origin: FRRRecordCon :: !RdrName -> !HsExpr GhcTc -> FixedRuntimeRepContext
+ GHC.Tc.Types.Origin: FRRRecordCon :: RdrName -> HsExpr GhcTc -> FixedRuntimeRepContext
- GHC.Tc.Types.Origin: FRRRecordUpdate :: !Name -> !HsExpr GhcRn -> FixedRuntimeRepContext
+ GHC.Tc.Types.Origin: FRRRecordUpdate :: Name -> HsExpr GhcRn -> FixedRuntimeRepContext
- GHC.Tc.Types.Origin: FRRRepPolyId :: !Name -> !RepPolyId -> !Position 'Neg -> FixedRuntimeRepContext
+ GHC.Tc.Types.Origin: FRRRepPolyId :: Name -> RepPolyId -> Position 'Neg -> FixedRuntimeRepContext
- GHC.Tc.Types.Origin: FRRRepPolyUnliftedNewtype :: !DataCon -> FixedRuntimeRepContext
+ GHC.Tc.Types.Origin: FRRRepPolyUnliftedNewtype :: DataCon -> FixedRuntimeRepContext
- GHC.Tc.Types.Origin: FRRUnboxedSum :: !Maybe Int -> FixedRuntimeRepContext
+ GHC.Tc.Types.Origin: FRRUnboxedSum :: Maybe Int -> FixedRuntimeRepContext
- GHC.Tc.Types.Origin: FRRUnboxedTuple :: !Int -> FixedRuntimeRepContext
+ GHC.Tc.Types.Origin: FRRUnboxedTuple :: Int -> FixedRuntimeRepContext
- GHC.Tc.Types.Origin: FRRUnboxedTupleSection :: !Int -> FixedRuntimeRepContext
+ GHC.Tc.Types.Origin: FRRUnboxedTupleSection :: Int -> FixedRuntimeRepContext
- GHC.Tc.Types.Origin: IsQC :: CtOrigin -> ClsInstOrQC
+ GHC.Tc.Types.Origin: IsQC :: PredType -> CtOrigin -> ClsInstOrQC
- GHC.Tc.Types.Origin: [Argument] :: forall (p :: Polarity). Int -> Position (FlipPolarity p) -> Position p
+ GHC.Tc.Types.Origin: [Argument] :: forall (p1 :: Polarity). Position p1 -> Position (FlipPolarity p1)
- GHC.Tc.Types.TH: Brack :: ThStage -> PendingStuff -> ThStage
+ GHC.Tc.Types.TH: Brack :: ThLevel -> PendingStuff -> ThLevel
- GHC.Tc.Types.TH: Comp :: ThStage
+ GHC.Tc.Types.TH: Comp :: ThLevel
- GHC.Tc.Types.TH: RunSplice :: TcRef [ForeignRef (Q ())] -> ThStage
+ GHC.Tc.Types.TH: RunSplice :: TcRef [ForeignRef (Q ())] -> ThLevel
- GHC.Tc.Types.TH: Splice :: SpliceType -> ThStage
+ GHC.Tc.Types.TH: Splice :: SpliceType -> ThLevel -> ThLevel
- GHC.Tc.Utils.Backpack: implicitRequirementsShallow :: HscEnv -> [(PkgQual, Located ModuleName)] -> IO ([ModuleName], [InstantiatedUnit])
+ GHC.Tc.Utils.Backpack: implicitRequirementsShallow :: HscEnv -> [(ImportLevel, PkgQual, Located ModuleName)] -> IO ([ModuleName], [InstantiatedUnit])
- GHC.Tc.Utils.Concrete: unifyConcrete :: HasDebugCallStack => FastString -> ConcreteTvOrigin -> TcType -> TcM TcMCoercionN
+ GHC.Tc.Utils.Concrete: unifyConcrete :: FastString -> ConcreteTvOrigin -> TcType -> TcM TcCoercionN
- GHC.Tc.Utils.Env: failIllegalTyCon :: WhatLooking -> Name -> TcM a
+ GHC.Tc.Utils.Env: failIllegalTyCon :: WhatLooking -> WithUserRdr Name -> TcM a
- GHC.Tc.Utils.Env: tcExtendLetEnv :: TopLevelFlag -> TcSigFun -> IsGroupClosed -> [Scaled TcId] -> TcM a -> TcM (a, HsWrapper)
+ GHC.Tc.Utils.Env: tcExtendLetEnv :: TopLevelFlag -> TcSigFun -> IsGroupClosed -> [Scaled TcId] -> TcM a -> TcM a
- GHC.Tc.Utils.Env: tcLookupConLike :: Name -> TcM ConLike
+ GHC.Tc.Utils.Env: tcLookupConLike :: WithUserRdr Name -> TcM ConLike
- GHC.Tc.Utils.Instantiate: mkOverLit :: forall (p :: Pass). OverLitVal -> TcM (HsLit (GhcPass p))
+ GHC.Tc.Utils.Instantiate: mkOverLit :: OverLitVal -> TcM (HsLit GhcTc)
- GHC.Tc.Utils.Monad: addDetailedDiagnostic :: (ErrInfo -> TcRnMessage) -> TcM ()
+ GHC.Tc.Utils.Monad: addDetailedDiagnostic :: ([ErrCtxtMsg] -> TcRnMessage) -> TcM ()
- GHC.Tc.Utils.Monad: addErrCtxt :: SDoc -> TcM a -> TcM a
+ GHC.Tc.Utils.Monad: addErrCtxt :: ErrCtxtMsg -> TcM a -> TcM a
- GHC.Tc.Utils.Monad: addErrCtxtM :: (TidyEnv -> ZonkM (TidyEnv, SDoc)) -> TcM a -> TcM a
+ GHC.Tc.Utils.Monad: addErrCtxtM :: (TidyEnv -> ZonkM (TidyEnv, ErrCtxtMsg)) -> TcM a -> TcM a
- GHC.Tc.Utils.Monad: addLandmarkErrCtxt :: SDoc -> TcM a -> TcM a
+ GHC.Tc.Utils.Monad: addLandmarkErrCtxt :: ErrCtxtMsg -> TcM a -> TcM a
- GHC.Tc.Utils.Monad: addLandmarkErrCtxtM :: (TidyEnv -> ZonkM (TidyEnv, SDoc)) -> TcM a -> TcM a
+ GHC.Tc.Utils.Monad: addLandmarkErrCtxtM :: (TidyEnv -> ZonkM (TidyEnv, ErrCtxtMsg)) -> TcM a -> TcM a
- GHC.Tc.Utils.Monad: getTcEvTyCoVars :: EvBindsVar -> TcM TyCoVarSet
+ GHC.Tc.Utils.Monad: getTcEvTyCoVars :: EvBindsVar -> TcM [TcCoercion]
- GHC.Tc.Utils.Monad: localAndImportedCompleteMatches :: CompleteMatches -> HscEnv -> ExternalPackageState -> CompleteMatches
+ GHC.Tc.Utils.Monad: localAndImportedCompleteMatches :: CompleteMatches -> ExternalPackageState -> IO CompleteMatches
- GHC.Tc.Utils.TcMType: Infer :: !InferResult -> ExpType
+ GHC.Tc.Utils.TcMType: Infer :: InferResult -> ExpType
- GHC.Tc.Utils.TcMType: isFilledCoercionHole :: CoercionHole -> TcM Bool
+ GHC.Tc.Utils.TcMType: isFilledCoercionHole :: CoercionHole -> ZonkM Bool
- GHC.Tc.Utils.TcMType: newCoercionHole :: CtLoc -> TcPredType -> TcM CoercionHole
+ GHC.Tc.Utils.TcMType: newCoercionHole :: TcPredType -> TcM CoercionHole
- GHC.Tc.Utils.TcMType: newInferExpType :: TcM ExpType
+ GHC.Tc.Utils.TcMType: newInferExpType :: InferInstFlag -> TcM ExpType
- GHC.Tc.Utils.TcMType: newInferExpTypeFRR :: FixedRuntimeRepContext -> TcM ExpTypeFRR
+ GHC.Tc.Utils.TcMType: newInferExpTypeFRR :: InferInstFlag -> FixedRuntimeRepContext -> TcM ExpTypeFRR
- GHC.Tc.Utils.TcMType: tcCheckUsage :: Name -> Mult -> TcM a -> TcM (a, HsWrapper)
+ GHC.Tc.Utils.TcMType: tcCheckUsage :: Name -> Mult -> TcM a -> TcM a
- GHC.Tc.Utils.TcType: IR :: Unique -> TcLevel -> Maybe FixedRuntimeRepContext -> IORef (Maybe TcType) -> InferResult
+ GHC.Tc.Utils.TcType: IR :: Unique -> TcLevel -> InferFRRFlag -> InferInstFlag -> IORef (Maybe TcType) -> InferResult
- GHC.Tc.Utils.TcType: Infer :: !InferResult -> ExpType
+ GHC.Tc.Utils.TcType: Infer :: InferResult -> ExpType
- GHC.Tc.Utils.TcType: Invisible :: !Specificity -> ForAllTyFlag
+ GHC.Tc.Utils.TcType: Invisible :: Specificity -> ForAllTyFlag
- GHC.Tc.Utils.TcType: TcLevel :: {-# UNPACK #-} !Int -> TcLevel
+ GHC.Tc.Utils.TcType: TcLevel :: Int -> TcLevel
- GHC.Tc.Utils.TcType: [ir_frr] :: InferResult -> Maybe FixedRuntimeRepContext
+ GHC.Tc.Utils.TcType: [ir_frr] :: InferResult -> InferFRRFlag
- GHC.Tc.Utils.TcType: isPredTy :: HasDebugCallStack => Type -> Bool
+ GHC.Tc.Utils.TcType: isPredTy :: Type -> Bool
- GHC.Tc.Utils.TcType: scopedSort :: [TyCoVar] -> [TyCoVar]
+ GHC.Tc.Utils.TcType: scopedSort :: [Var] -> [Var]
- GHC.Tc.Utils.Unify: [tef_fam_app] :: TyEqFlags a -> TyEqFamApp a
+ GHC.Tc.Utils.Unify: [tef_fam_app] :: TyEqFlags (m :: Type -> Type) a -> TyEqFamApp m a
- GHC.Tc.Utils.Unify: checkPromoteFreeVars :: CheckTyEqProblem -> TcTyVar -> TcLevel -> TyCoVarSet -> TcM CheckTyEqResult
+ GHC.Tc.Utils.Unify: checkPromoteFreeVars :: CheckTyEqProblem -> Name -> TcLevel -> TyCoVarSet -> TcM CheckTyEqResult
- GHC.Tc.Utils.Unify: checkTyEqRhs :: TyEqFlags a -> TcType -> TcM (PuResult a Reduction)
+ GHC.Tc.Utils.Unify: checkTyEqRhs :: Monad m => TyEqFlags m a -> TcType -> m (PuResult a Reduction)
- GHC.Tc.Utils.Unify: data LevelCheck
+ GHC.Tc.Utils.Unify: data LevelCheck (m :: Type -> Type)
- GHC.Tc.Utils.Unify: data TyEqFamApp a
+ GHC.Tc.Utils.Unify: data TyEqFamApp (m :: Type -> Type) a
- GHC.Tc.Utils.Unify: data TyEqFlags a
+ GHC.Tc.Utils.Unify: data TyEqFlags (m :: Type -> Type) a
- GHC.Tc.Utils.Unify: fillInferResult :: TcType -> InferResult -> TcM TcCoercionN
+ GHC.Tc.Utils.Unify: fillInferResult :: CtOrigin -> TcType -> InferResult -> TcM HsWrapper
- GHC.Tc.Utils.Unify: mapCheck :: (x -> TcM (PuResult a Reduction)) -> [x] -> TcM (PuResult a Reductions)
+ GHC.Tc.Utils.Unify: mapCheck :: Monad m => (x -> m (PuResult a Reduction)) -> [x] -> m (PuResult a Reductions)
- GHC.Tc.Utils.Unify: okCheckRefl :: TcType -> TcM (PuResult a Reduction)
+ GHC.Tc.Utils.Unify: okCheckRefl :: TcType -> PuResult a Reduction
- GHC.Tc.Utils.Unify: recurseIntoTyConApp :: TyEqFlags a -> TyCon -> [TcType] -> TcM (PuResult a Reduction)
+ GHC.Tc.Utils.Unify: recurseIntoTyConApp :: Monad m => TyEqFlags m a -> TyCon -> [TcType] -> m (PuResult a Reduction)
- GHC.Tc.Utils.Unify: simpleUnifyCheck :: UnifyCheckCaller -> TcTyVar -> TcType -> Bool
+ GHC.Tc.Utils.Unify: simpleUnifyCheck :: UnifyCheckCaller -> TcLevel -> TcTyVar -> TcType -> SimpleUnifyResult
- GHC.Tc.Utils.Unify: tcSubMult :: CtOrigin -> Mult -> Mult -> TcM HsWrapper
+ GHC.Tc.Utils.Unify: tcSubMult :: CtOrigin -> Mult -> Mult -> TcM ()
- GHC.Tc.Utils.Unify: tcSubType :: CtOrigin -> UserTypeCtxt -> TcSigmaType -> ExpRhoType -> TcM HsWrapper
+ GHC.Tc.Utils.Unify: tcSubType :: CtOrigin -> UserTypeCtxt -> Maybe TypedThing -> TcSigmaType -> ExpRhoType -> TcM HsWrapper
- GHC.Tc.Utils.Unify: tcWrapResultMono :: HsExpr GhcRn -> HsExpr GhcTc -> TcRhoType -> ExpRhoType -> TcM (HsExpr GhcTc)
+ GHC.Tc.Utils.Unify: tcWrapResultMono :: HasDebugCallStack => HsExpr GhcRn -> HsExpr GhcTc -> TcRhoType -> ExpRhoType -> TcM (HsExpr GhcTc)
- GHC.Tc.Zonk.Env: SkolemiseFlexi :: ZonkFlexi
+ GHC.Tc.Zonk.Env: SkolemiseFlexi :: IORef [TyVar] -> ZonkFlexi
- GHC.Tc.Zonk.Env: ZonkEnv :: !ZonkFlexi -> TyCoVarEnv TyCoVar -> IdEnv Id -> IORef (TyVarEnv Type) -> ZonkEnv
+ GHC.Tc.Zonk.Env: ZonkEnv :: ZonkFlexi -> TyCoVarEnv TyCoVar -> IdEnv Id -> IORef (TyVarEnv Type) -> ZonkEnv
- GHC.Tc.Zonk.Env: [ze_flexi] :: ZonkEnv -> !ZonkFlexi
+ GHC.Tc.Zonk.Env: [ze_flexi] :: ZonkEnv -> ZonkFlexi
- GHC.ThToHs: convertToHsDecls :: Origin -> SrcSpan -> [Dec] -> Either RunSpliceFailReason [LHsDecl GhcPs]
+ GHC.ThToHs: convertToHsDecls :: EnumSet Extension -> Origin -> SrcSpan -> [Dec] -> Either RunSpliceFailReason [LHsDecl GhcPs]
- GHC.ThToHs: convertToHsExpr :: Origin -> SrcSpan -> Exp -> Either RunSpliceFailReason (LHsExpr GhcPs)
+ GHC.ThToHs: convertToHsExpr :: EnumSet Extension -> Origin -> SrcSpan -> Exp -> Either RunSpliceFailReason (LHsExpr GhcPs)
- GHC.ThToHs: convertToHsType :: Origin -> SrcSpan -> Type -> Either RunSpliceFailReason (LHsType GhcPs)
+ GHC.ThToHs: convertToHsType :: EnumSet Extension -> Origin -> SrcSpan -> Type -> Either RunSpliceFailReason (LHsType GhcPs)
- GHC.ThToHs: convertToPat :: Origin -> SrcSpan -> Pat -> Either RunSpliceFailReason (LPat GhcPs)
+ GHC.ThToHs: convertToPat :: EnumSet Extension -> Origin -> SrcSpan -> Pat -> Either RunSpliceFailReason (LPat GhcPs)
- GHC.ThToHs: thRdrNameGuesses :: Name -> [RdrName]
+ GHC.ThToHs: thRdrNameGuesses :: Bool -> Name -> [RdrName]
- GHC.Types.Basic: AlwaysTailCalled :: {-# UNPACK #-} !JoinArity -> TailCallInfo
+ GHC.Types.Basic: AlwaysTailCalled :: JoinArity -> TailCallInfo
- GHC.Types.Basic: IAmALoopBreaker :: !RulesOnly -> !TailCallInfo -> OccInfo
+ GHC.Types.Basic: IAmALoopBreaker :: RulesOnly -> TailCallInfo -> OccInfo
- GHC.Types.Basic: IAmData :: TypeOrData
+ GHC.Types.Basic: IAmData :: NewOrData -> TypeOrData
- GHC.Types.Basic: JoinPoint :: {-# UNPACK #-} !Int -> JoinPointHood
+ GHC.Types.Basic: JoinPoint :: Int -> JoinPointHood
- GHC.Types.Basic: ManyOccs :: !TailCallInfo -> OccInfo
+ GHC.Types.Basic: ManyOccs :: TailCallInfo -> OccInfo
- GHC.Types.Basic: OneOcc :: !InsideLam -> {-# UNPACK #-} !BranchCount -> !InterestingCxt -> !TailCallInfo -> OccInfo
+ GHC.Types.Basic: OneOcc :: InsideLam -> BranchCount -> InterestingCxt -> TailCallInfo -> OccInfo
- GHC.Types.Basic: [occ_in_lam] :: OccInfo -> !InsideLam
+ GHC.Types.Basic: [occ_in_lam] :: OccInfo -> InsideLam
- GHC.Types.Basic: [occ_int_cxt] :: OccInfo -> !InterestingCxt
+ GHC.Types.Basic: [occ_int_cxt] :: OccInfo -> InterestingCxt
- GHC.Types.Basic: [occ_n_br] :: OccInfo -> {-# UNPACK #-} !BranchCount
+ GHC.Types.Basic: [occ_n_br] :: OccInfo -> BranchCount
- GHC.Types.Basic: [occ_rules_only] :: OccInfo -> !RulesOnly
+ GHC.Types.Basic: [occ_rules_only] :: OccInfo -> RulesOnly
- GHC.Types.Basic: [occ_tail] :: OccInfo -> !TailCallInfo
+ GHC.Types.Basic: [occ_tail] :: OccInfo -> TailCallInfo
- GHC.Types.Cpr: AllFieldsSame :: !Cpr -> UnpackConFieldsResult
+ GHC.Types.Cpr: AllFieldsSame :: Cpr -> UnpackConFieldsResult
- GHC.Types.Cpr: CprType :: !Arity -> !Cpr -> CprType
+ GHC.Types.Cpr: CprType :: Arity -> Cpr -> CprType
- GHC.Types.Cpr: ForeachField :: ![Cpr] -> UnpackConFieldsResult
+ GHC.Types.Cpr: ForeachField :: [Cpr] -> UnpackConFieldsResult
- GHC.Types.Cpr: [ct_arty] :: CprType -> !Arity
+ GHC.Types.Cpr: [ct_arty] :: CprType -> Arity
- GHC.Types.Cpr: [ct_cpr] :: CprType -> !Cpr
+ GHC.Types.Cpr: [ct_cpr] :: CprType -> Cpr
- GHC.Types.DefaultEnv: ClassDefaults :: Class -> [Type] -> Maybe Module -> Maybe (WarningTxt GhcRn) -> ClassDefaults
+ GHC.Types.DefaultEnv: ClassDefaults :: Class -> [Type] -> DefaultProvenance -> Maybe (WarningTxt GhcRn) -> ClassDefaults
- GHC.Types.Demand: DE :: !VarEnv Demand -> !Divergence -> DmdEnv
+ GHC.Types.Demand: DE :: VarEnv Demand -> Divergence -> DmdEnv
- GHC.Types.Demand: DmdType :: !DmdEnv -> ![Demand] -> DmdType
+ GHC.Types.Demand: DmdType :: DmdEnv -> [Demand] -> DmdType
- GHC.Types.Demand: Poly :: !Boxity -> !CardNonOnce -> SubDemand
+ GHC.Types.Demand: Poly :: Boxity -> CardNonOnce -> SubDemand
- GHC.Types.Demand: Prod :: !Boxity -> ![Demand] -> SubDemand
+ GHC.Types.Demand: Prod :: Boxity -> [Demand] -> SubDemand
- GHC.Types.Demand: [de_div] :: DmdEnv -> !Divergence
+ GHC.Types.Demand: [de_div] :: DmdEnv -> Divergence
- GHC.Types.Demand: [de_fvs] :: DmdEnv -> !VarEnv Demand
+ GHC.Types.Demand: [de_fvs] :: DmdEnv -> VarEnv Demand
- GHC.Types.Demand: [dt_args] :: DmdType -> ![Demand]
+ GHC.Types.Demand: [dt_args] :: DmdType -> [Demand]
- GHC.Types.Demand: [dt_env] :: DmdType -> !DmdEnv
+ GHC.Types.Demand: [dt_env] :: DmdType -> DmdEnv
- GHC.Types.Error: -- | Type of configuration options for the diagnostic.
+ GHC.Types.Error: -- | Type of hint this diagnostic can provide. By default, this is
- GHC.Types.Error: DiagnosticMessage :: !DecoratedSDoc -> !DiagnosticReason -> [GhcHint] -> DiagnosticMessage
+ GHC.Types.Error: DiagnosticMessage :: DecoratedSDoc -> DiagnosticReason -> [GhcHint] -> DiagnosticMessage
- GHC.Types.Error: SuggestAddInlineOrNoInlinePragma :: !Var -> !Activation -> GhcHint
+ GHC.Types.Error: SuggestAddInlineOrNoInlinePragma :: Var -> Activation -> GhcHint
- GHC.Types.Error: SuggestAddPhaseToCompetingRule :: !RuleName -> GhcHint
+ GHC.Types.Error: SuggestAddPhaseToCompetingRule :: RuleName -> GhcHint
- GHC.Types.Error: SuggestAddSignatureCabalFile :: !ModuleName -> GhcHint
+ GHC.Types.Error: SuggestAddSignatureCabalFile :: ModuleName -> GhcHint
- GHC.Types.Error: SuggestAddToHSigExportList :: !Name -> !Maybe Module -> GhcHint
+ GHC.Types.Error: SuggestAddToHSigExportList :: Name -> Maybe Module -> GhcHint
- GHC.Types.Error: SuggestAnyExtension :: !SDoc -> [Extension] -> LanguageExtensionHint
+ GHC.Types.Error: SuggestAnyExtension :: SDoc -> [Extension] -> LanguageExtensionHint
- GHC.Types.Error: SuggestBindToWildcard :: !LHsExpr GhcTc -> GhcHint
+ GHC.Types.Error: SuggestBindToWildcard :: LHsExpr GhcTc -> GhcHint
- GHC.Types.Error: SuggestCorrectPragmaName :: ![String] -> GhcHint
+ GHC.Types.Error: SuggestCorrectPragmaName :: [String] -> GhcHint
- GHC.Types.Error: SuggestExtension :: !LanguageExtensionHint -> GhcHint
+ GHC.Types.Error: SuggestExtension :: LanguageExtensionHint -> GhcHint
- GHC.Types.Error: SuggestExtensionInOrderTo :: !SDoc -> !Extension -> LanguageExtensionHint
+ GHC.Types.Error: SuggestExtensionInOrderTo :: SDoc -> Extension -> LanguageExtensionHint
- GHC.Types.Error: SuggestExtensions :: !SDoc -> [Extension] -> LanguageExtensionHint
+ GHC.Types.Error: SuggestExtensions :: SDoc -> [Extension] -> LanguageExtensionHint
- GHC.Types.Error: SuggestMoveToDeclarationSite :: SDoc -> RdrName -> GhcHint
+ GHC.Types.Error: SuggestMoveToDeclarationSite :: SigLike -> RdrName -> GhcHint
- GHC.Types.Error: SuggestSignatureInstantiations :: !ModuleName -> [InstantiationSuggestion] -> GhcHint
+ GHC.Types.Error: SuggestSignatureInstantiations :: ModuleName -> [InstantiationSuggestion] -> GhcHint
- GHC.Types.Error: SuggestSingleExtension :: !SDoc -> !Extension -> LanguageExtensionHint
+ GHC.Types.Error: SuggestSingleExtension :: SDoc -> Extension -> LanguageExtensionHint
- GHC.Types.Error: SuggestUseWhitespaceAfter :: !OperatorWhitespaceSymbol -> GhcHint
+ GHC.Types.Error: SuggestUseWhitespaceAfter :: OperatorWhitespaceSymbol -> GhcHint
- GHC.Types.Error: SuggestUseWhitespaceAround :: !String -> !OperatorWhitespaceOccurrence -> GhcHint
+ GHC.Types.Error: SuggestUseWhitespaceAround :: String -> OperatorWhitespaceOccurrence -> GhcHint
- GHC.Types.Error: WarningWithCategory :: !WarningCategory -> DiagnosticReason
+ GHC.Types.Error: WarningWithCategory :: WarningCategory -> DiagnosticReason
- GHC.Types.Error: WarningWithFlags :: !NonEmpty WarningFlag -> DiagnosticReason
+ GHC.Types.Error: WarningWithFlags :: NonEmpty WarningFlag -> DiagnosticReason
- GHC.Types.Error: [UnknownDiagnostic] :: forall a opts. (Diagnostic a, Typeable a) => (opts -> DiagnosticOpts a) -> a -> UnknownDiagnostic opts
+ GHC.Types.Error: [UnknownDiagnostic] :: forall a opts hint. (Diagnostic a, Typeable a) => (opts -> DiagnosticOpts a) -> (DiagnosticHint a -> hint) -> a -> UnknownDiagnostic opts hint
- GHC.Types.Error: [diagMessage] :: DiagnosticMessage -> !DecoratedSDoc
+ GHC.Types.Error: [diagMessage] :: DiagnosticMessage -> DecoratedSDoc
- GHC.Types.Error: [diagReason] :: DiagnosticMessage -> !DiagnosticReason
+ GHC.Types.Error: [diagReason] :: DiagnosticMessage -> DiagnosticReason
- GHC.Types.Error: class HasDefaultDiagnosticOpts DiagnosticOpts a => Diagnostic a where {
+ GHC.Types.Error: class (Outputable DiagnosticHint a, HasDefaultDiagnosticOpts DiagnosticOpts a) => Diagnostic a where {
- GHC.Types.Error: data UnknownDiagnostic opts
+ GHC.Types.Error: data UnknownDiagnostic opts hint
- GHC.Types.Error: diagnosticHints :: Diagnostic a => a -> [GhcHint]
+ GHC.Types.Error: diagnosticHints :: Diagnostic a => a -> [DiagnosticHint a]
- GHC.Types.Error: embedUnknownDiagnostic :: (Diagnostic a, Typeable a) => (opts -> DiagnosticOpts a) -> a -> UnknownDiagnostic opts
+ GHC.Types.Error: embedUnknownDiagnostic :: (Diagnostic a, Typeable a) => (opts -> DiagnosticOpts a) -> a -> UnknownDiagnostic opts (DiagnosticHint a)
- GHC.Types.Error: mkSimpleUnknownDiagnostic :: (Diagnostic a, Typeable a, DiagnosticOpts a ~ NoDiagnosticOpts) => a -> UnknownDiagnostic b
+ GHC.Types.Error: mkSimpleUnknownDiagnostic :: (Diagnostic a, Typeable a, DiagnosticOpts a ~ NoDiagnosticOpts) => a -> UnknownDiagnostic b (DiagnosticHint a)
- GHC.Types.Error: mkUnknownDiagnostic :: (Typeable a, Diagnostic a) => a -> UnknownDiagnostic (DiagnosticOpts a)
+ GHC.Types.Error: mkUnknownDiagnostic :: (Typeable a, Diagnostic a) => a -> UnknownDiagnosticFor a
- GHC.Types.Error.Codes: constructorCode :: (Generic diag, GDiagnosticCode (Rep diag)) => diag -> Maybe DiagnosticCode
+ GHC.Types.Error.Codes: constructorCode :: forall namespace diag. (Generic diag, GDiagnosticCode namespace (Rep diag)) => diag -> Maybe DiagnosticCode
- GHC.Types.Error.Codes: constructorCodes :: (Generic diag, GDiagnosticCodes '[diag] (Rep diag)) => Map DiagnosticCode String
+ GHC.Types.Error.Codes: constructorCodes :: forall namespace diag. (Generic diag, GDiagnosticCodes namespace '[diag] (Rep diag)) => Map DiagnosticCode String
- GHC.Types.Error.Codes: type family GhcDiagnosticCode (c :: Symbol) = (n :: Nat) | n -> c
+ GHC.Types.Error.Codes: type family ConRecursInto (con :: Symbol) :: Maybe Type
- GHC.Types.GREInfo: ConInfo :: !ConLikeInfo -> !ConFieldInfo -> ConInfo
+ GHC.Types.GREInfo: ConInfo :: ConLikeInfo -> ConFieldInfo -> ConInfo
- GHC.Types.GREInfo: DataConName :: !Name -> ConLikeName
+ GHC.Types.GREInfo: DataConName :: Name -> ConLikeName
- GHC.Types.GREInfo: IAmConLike :: !ConInfo -> GREInfo
+ GHC.Types.GREInfo: IAmConLike :: ConInfo -> GREInfo
- GHC.Types.GREInfo: IAmRecField :: !RecFieldInfo -> GREInfo
+ GHC.Types.GREInfo: IAmRecField :: RecFieldInfo -> GREInfo
- GHC.Types.GREInfo: IAmTyCon :: !TyConFlavour Name -> GREInfo
+ GHC.Types.GREInfo: IAmTyCon :: TyConFlavour Name -> GREInfo
- GHC.Types.GREInfo: PatSynName :: !Name -> ConLikeName
+ GHC.Types.GREInfo: PatSynName :: Name -> ConLikeName
- GHC.Types.GREInfo: RecFieldInfo :: !FieldLabel -> !UniqSet ConLikeName -> RecFieldInfo
+ GHC.Types.GREInfo: RecFieldInfo :: FieldLabel -> UniqSet ConLikeName -> RecFieldInfo
- GHC.Types.GREInfo: [conFieldInfo] :: ConInfo -> !ConFieldInfo
+ GHC.Types.GREInfo: [conFieldInfo] :: ConInfo -> ConFieldInfo
- GHC.Types.GREInfo: [conLikeInfo] :: ConInfo -> !ConLikeInfo
+ GHC.Types.GREInfo: [conLikeInfo] :: ConInfo -> ConLikeInfo
- GHC.Types.GREInfo: [conLikeName_Name] :: ConLikeName -> !Name
+ GHC.Types.GREInfo: [conLikeName_Name] :: ConLikeName -> Name
- GHC.Types.GREInfo: [recFieldCons] :: RecFieldInfo -> !UniqSet ConLikeName
+ GHC.Types.GREInfo: [recFieldCons] :: RecFieldInfo -> UniqSet ConLikeName
- GHC.Types.GREInfo: [recFieldLabel] :: RecFieldInfo -> !FieldLabel
+ GHC.Types.GREInfo: [recFieldLabel] :: RecFieldInfo -> FieldLabel
- GHC.Types.GREInfo: mkConInfo :: ConLikeInfo -> Arity -> [FieldLabel] -> ConInfo
+ GHC.Types.GREInfo: mkConInfo :: ConLikeInfo -> VisArity -> [FieldLabel] -> ConInfo
- GHC.Types.Hint: ImportDataCon :: Maybe (ModuleName, Bool) -> OccName -> ImportSuggestion
+ GHC.Types.Hint: ImportDataCon :: Maybe ModuleName -> Bool -> Bool -> OccName -> ImportSuggestion
- GHC.Types.Hint: InstantiationSuggestion :: !ModuleName -> !Module -> InstantiationSuggestion
+ GHC.Types.Hint: InstantiationSuggestion :: ModuleName -> Module -> InstantiationSuggestion
- GHC.Types.Hint: SuggestAddInlineOrNoInlinePragma :: !Var -> !Activation -> GhcHint
+ GHC.Types.Hint: SuggestAddInlineOrNoInlinePragma :: Var -> Activation -> GhcHint
- GHC.Types.Hint: SuggestAddPhaseToCompetingRule :: !RuleName -> GhcHint
+ GHC.Types.Hint: SuggestAddPhaseToCompetingRule :: RuleName -> GhcHint
- GHC.Types.Hint: SuggestAddSignatureCabalFile :: !ModuleName -> GhcHint
+ GHC.Types.Hint: SuggestAddSignatureCabalFile :: ModuleName -> GhcHint
- GHC.Types.Hint: SuggestAddToHSigExportList :: !Name -> !Maybe Module -> GhcHint
+ GHC.Types.Hint: SuggestAddToHSigExportList :: Name -> Maybe Module -> GhcHint
- GHC.Types.Hint: SuggestAnyExtension :: !SDoc -> [Extension] -> LanguageExtensionHint
+ GHC.Types.Hint: SuggestAnyExtension :: SDoc -> [Extension] -> LanguageExtensionHint
- GHC.Types.Hint: SuggestBindToWildcard :: !LHsExpr GhcTc -> GhcHint
+ GHC.Types.Hint: SuggestBindToWildcard :: LHsExpr GhcTc -> GhcHint
- GHC.Types.Hint: SuggestCorrectPragmaName :: ![String] -> GhcHint
+ GHC.Types.Hint: SuggestCorrectPragmaName :: [String] -> GhcHint
- GHC.Types.Hint: SuggestExtension :: !LanguageExtensionHint -> GhcHint
+ GHC.Types.Hint: SuggestExtension :: LanguageExtensionHint -> GhcHint
- GHC.Types.Hint: SuggestExtensionInOrderTo :: !SDoc -> !Extension -> LanguageExtensionHint
+ GHC.Types.Hint: SuggestExtensionInOrderTo :: SDoc -> Extension -> LanguageExtensionHint
- GHC.Types.Hint: SuggestExtensions :: !SDoc -> [Extension] -> LanguageExtensionHint
+ GHC.Types.Hint: SuggestExtensions :: SDoc -> [Extension] -> LanguageExtensionHint
- GHC.Types.Hint: SuggestMoveToDeclarationSite :: SDoc -> RdrName -> GhcHint
+ GHC.Types.Hint: SuggestMoveToDeclarationSite :: SigLike -> RdrName -> GhcHint
- GHC.Types.Hint: SuggestSignatureInstantiations :: !ModuleName -> [InstantiationSuggestion] -> GhcHint
+ GHC.Types.Hint: SuggestSignatureInstantiations :: ModuleName -> [InstantiationSuggestion] -> GhcHint
- GHC.Types.Hint: SuggestSingleExtension :: !SDoc -> !Extension -> LanguageExtensionHint
+ GHC.Types.Hint: SuggestSingleExtension :: SDoc -> Extension -> LanguageExtensionHint
- GHC.Types.Hint: SuggestUseWhitespaceAfter :: !OperatorWhitespaceSymbol -> GhcHint
+ GHC.Types.Hint: SuggestUseWhitespaceAfter :: OperatorWhitespaceSymbol -> GhcHint
- GHC.Types.Hint: SuggestUseWhitespaceAround :: !String -> !OperatorWhitespaceOccurrence -> GhcHint
+ GHC.Types.Hint: SuggestUseWhitespaceAround :: String -> OperatorWhitespaceOccurrence -> GhcHint
- GHC.Types.Hint: [ies_suggest_import_from] :: ImportSuggestion -> Maybe (ModuleName, Bool)
+ GHC.Types.Hint: [ies_suggest_import_from] :: ImportSuggestion -> Maybe ModuleName
- GHC.Types.HpcInfo: NoHpcInfo :: AnyHpcUsage -> HpcInfo
+ GHC.Types.HpcInfo: NoHpcInfo :: HpcInfo
- GHC.Types.HpcInfo: emptyHpcInfo :: AnyHpcUsage -> HpcInfo
+ GHC.Types.HpcInfo: emptyHpcInfo :: HpcInfo
- GHC.Types.Id: idDetails :: Id -> IdDetails
+ GHC.Types.Id: idDetails :: HasCallStack => Id -> IdDetails
- GHC.Types.Id: idMult :: Id -> Mult
+ GHC.Types.Id: idMult :: HasDebugCallStack => Id -> Mult
- GHC.Types.Id.Info: AlwaysTailCalled :: {-# UNPACK #-} !JoinArity -> TailCallInfo
+ GHC.Types.Id.Info: AlwaysTailCalled :: JoinArity -> TailCallInfo
- GHC.Types.Id.Info: IAmALoopBreaker :: !RulesOnly -> !TailCallInfo -> OccInfo
+ GHC.Types.Id.Info: IAmALoopBreaker :: RulesOnly -> TailCallInfo -> OccInfo
- GHC.Types.Id.Info: ManyOccs :: !TailCallInfo -> OccInfo
+ GHC.Types.Id.Info: ManyOccs :: TailCallInfo -> OccInfo
- GHC.Types.Id.Info: OneOcc :: !InsideLam -> {-# UNPACK #-} !BranchCount -> !InterestingCxt -> !TailCallInfo -> OccInfo
+ GHC.Types.Id.Info: OneOcc :: InsideLam -> BranchCount -> InterestingCxt -> TailCallInfo -> OccInfo
- GHC.Types.Id.Info: RecSelId :: RecSelParent -> FieldLabel -> Bool -> ([ConLike], [ConLike]) -> IdDetails
+ GHC.Types.Id.Info: RecSelId :: RecSelParent -> FieldLabel -> Bool -> RecSelInfo -> IdDetails
- GHC.Types.Id.Info: TickBox :: Module -> {-# UNPACK #-} !TickBoxId -> TickBoxOp
+ GHC.Types.Id.Info: TickBox :: Module -> TickBoxId -> TickBoxOp
- GHC.Types.Id.Info: [occ_in_lam] :: OccInfo -> !InsideLam
+ GHC.Types.Id.Info: [occ_in_lam] :: OccInfo -> InsideLam
- GHC.Types.Id.Info: [occ_int_cxt] :: OccInfo -> !InterestingCxt
+ GHC.Types.Id.Info: [occ_int_cxt] :: OccInfo -> InterestingCxt
- GHC.Types.Id.Info: [occ_n_br] :: OccInfo -> {-# UNPACK #-} !BranchCount
+ GHC.Types.Id.Info: [occ_n_br] :: OccInfo -> BranchCount
- GHC.Types.Id.Info: [occ_rules_only] :: OccInfo -> !RulesOnly
+ GHC.Types.Id.Info: [occ_rules_only] :: OccInfo -> RulesOnly
- GHC.Types.Id.Info: [occ_tail] :: OccInfo -> !TailCallInfo
+ GHC.Types.Id.Info: [occ_tail] :: OccInfo -> TailCallInfo
- GHC.Types.Id.Info: [sel_cons] :: IdDetails -> ([ConLike], [ConLike])
+ GHC.Types.Id.Info: [sel_cons] :: IdDetails -> RecSelInfo
- GHC.Types.Id.Make: BangOpts :: !Bool -> !Bool -> !Bool -> !Bool -> BangOpts
+ GHC.Types.Id.Make: BangOpts :: Bool -> Bool -> Bool -> Bool -> BangOpts
- GHC.Types.Id.Make: SrcBangOpts :: !BangOpts -> DataConBangOpts
+ GHC.Types.Id.Make: SrcBangOpts :: BangOpts -> DataConBangOpts
- GHC.Types.Id.Make: [bang_opt_strict_data] :: BangOpts -> !Bool
+ GHC.Types.Id.Make: [bang_opt_strict_data] :: BangOpts -> Bool
- GHC.Types.Id.Make: [bang_opt_unbox_disable] :: BangOpts -> !Bool
+ GHC.Types.Id.Make: [bang_opt_unbox_disable] :: BangOpts -> Bool
- GHC.Types.Id.Make: [bang_opt_unbox_small] :: BangOpts -> !Bool
+ GHC.Types.Id.Make: [bang_opt_unbox_small] :: BangOpts -> Bool
- GHC.Types.Id.Make: [bang_opt_unbox_strict] :: BangOpts -> !Bool
+ GHC.Types.Id.Make: [bang_opt_unbox_strict] :: BangOpts -> Bool
- GHC.Types.Id.Make: mkDataConRep :: DataConBangOpts -> FamInstEnvs -> Name -> DataCon -> UniqSM DataConRep
+ GHC.Types.Id.Make: mkDataConRep :: DataConBangOpts -> FamInstEnvs -> Name -> DataCon -> UniqSM (DataConRep, [HsImplBang], [StrictnessMark])
- GHC.Types.Literal: LitNumber :: !LitNumType -> !Integer -> Literal
+ GHC.Types.Literal: LitNumber :: LitNumType -> Integer -> Literal
- GHC.Types.Literal: LitString :: !ByteString -> Literal
+ GHC.Types.Literal: LitString :: ByteString -> Literal
- GHC.Types.Name: pprModulePrefix :: PprStyle -> Module -> OccName -> SDoc
+ GHC.Types.Name: pprModulePrefix :: PprStyle -> Module -> Maybe ModuleName -> OccName -> SDoc
- GHC.Types.Name: pprPrefixName :: NamedThing a => a -> SDoc
+ GHC.Types.Name: pprPrefixName :: (Outputable a, NamedThing a) => a -> SDoc
- GHC.Types.Name.Cache: NameCache :: {-# UNPACK #-} !Char -> {-# UNPACK #-} !MVar OrigNameCache -> NameCache
+ GHC.Types.Name.Cache: NameCache :: Char -> MVar OrigNameCache -> NameCache
- GHC.Types.Name.Cache: [nsNames] :: NameCache -> {-# UNPACK #-} !MVar OrigNameCache
+ GHC.Types.Name.Cache: [nsNames] :: NameCache -> MVar OrigNameCache
- GHC.Types.Name.Cache: [nsUniqChar] :: NameCache -> {-# UNPACK #-} !Char
+ GHC.Types.Name.Cache: [nsUniqChar] :: NameCache -> Char
- GHC.Types.Name.Ppr: mkQualModule :: UnitState -> Maybe HomeUnit -> QueryQualifyModule
+ GHC.Types.Name.Ppr: mkQualModule :: UnitState -> UnitEnv -> QueryQualifyModule
- GHC.Types.Name.Reader: DataConName :: !Name -> ConLikeName
+ GHC.Types.Name.Reader: DataConName :: Name -> ConLikeName
- GHC.Types.Name.Reader: GRE :: !Name -> !Parent -> !Bool -> !Bag ImportSpec -> info -> GlobalRdrEltX info
+ GHC.Types.Name.Reader: GRE :: Name -> Parent -> Bool -> Bag ImportSpec -> info -> GlobalRdrEltX info
- GHC.Types.Name.Reader: IAmConLike :: !ConInfo -> GREInfo
+ GHC.Types.Name.Reader: IAmConLike :: ConInfo -> GREInfo
- GHC.Types.Name.Reader: IAmRecField :: !RecFieldInfo -> GREInfo
+ GHC.Types.Name.Reader: IAmRecField :: RecFieldInfo -> GREInfo
- GHC.Types.Name.Reader: IAmTyCon :: !TyConFlavour Name -> GREInfo
+ GHC.Types.Name.Reader: IAmTyCon :: TyConFlavour Name -> GREInfo
- GHC.Types.Name.Reader: ImpDeclSpec :: !Module -> !ModuleName -> !PkgQual -> !Bool -> !SrcSpan -> !IsBootInterface -> ImpDeclSpec
+ GHC.Types.Name.Reader: ImpDeclSpec :: Module -> ModuleName -> PkgQual -> Bool -> SrcSpan -> IsBootInterface -> ImportLevel -> ImpDeclSpec
- GHC.Types.Name.Reader: ImpSome :: !Bool -> !SrcSpan -> ImpItemSpec
+ GHC.Types.Name.Reader: ImpSome :: Bool -> SrcSpan -> ImpItemSpec
- GHC.Types.Name.Reader: ImpSpec :: !ImpDeclSpec -> !ImpItemSpec -> ImportSpec
+ GHC.Types.Name.Reader: ImpSpec :: ImpDeclSpec -> ImpItemSpec -> ImportSpec
- GHC.Types.Name.Reader: ParentIs :: !Name -> Parent
+ GHC.Types.Name.Reader: ParentIs :: Name -> Parent
- GHC.Types.Name.Reader: PatSynName :: !Name -> ConLikeName
+ GHC.Types.Name.Reader: PatSynName :: Name -> ConLikeName
- GHC.Types.Name.Reader: RecFieldInfo :: !FieldLabel -> !UniqSet ConLikeName -> RecFieldInfo
+ GHC.Types.Name.Reader: RecFieldInfo :: FieldLabel -> UniqSet ConLikeName -> RecFieldInfo
- GHC.Types.Name.Reader: [LookupChildren] :: forall info. OccName -> LookupChild -> LookupGRE info
+ GHC.Types.Name.Reader: [LookupChildren] :: ParentGRE -> OccName -> LookupGRE GREInfo
- GHC.Types.Name.Reader: [RelevantGREs] :: !FieldsOrSelectors -> !Bool -> !Bool -> WhichGREs GREInfo
+ GHC.Types.Name.Reader: [RelevantGREs] :: FieldsOrSelectors -> Bool -> Bool -> WhichGREs GREInfo
- GHC.Types.Name.Reader: [conLikeName_Name] :: ConLikeName -> !Name
+ GHC.Types.Name.Reader: [conLikeName_Name] :: ConLikeName -> Name
- GHC.Types.Name.Reader: [gre_imp] :: GlobalRdrEltX info -> !Bag ImportSpec
+ GHC.Types.Name.Reader: [gre_imp] :: GlobalRdrEltX info -> Bag ImportSpec
- GHC.Types.Name.Reader: [gre_lcl] :: GlobalRdrEltX info -> !Bool
+ GHC.Types.Name.Reader: [gre_lcl] :: GlobalRdrEltX info -> Bool
- GHC.Types.Name.Reader: [gre_name] :: GlobalRdrEltX info -> !Name
+ GHC.Types.Name.Reader: [gre_name] :: GlobalRdrEltX info -> Name
- GHC.Types.Name.Reader: [gre_par] :: GlobalRdrEltX info -> !Parent
+ GHC.Types.Name.Reader: [gre_par] :: GlobalRdrEltX info -> Parent
- GHC.Types.Name.Reader: [is_as] :: ImpDeclSpec -> !ModuleName
+ GHC.Types.Name.Reader: [is_as] :: ImpDeclSpec -> ModuleName
- GHC.Types.Name.Reader: [is_decl] :: ImportSpec -> !ImpDeclSpec
+ GHC.Types.Name.Reader: [is_decl] :: ImportSpec -> ImpDeclSpec
- GHC.Types.Name.Reader: [is_dloc] :: ImpDeclSpec -> !SrcSpan
+ GHC.Types.Name.Reader: [is_dloc] :: ImpDeclSpec -> SrcSpan
- GHC.Types.Name.Reader: [is_explicit] :: ImpItemSpec -> !Bool
+ GHC.Types.Name.Reader: [is_explicit] :: ImpItemSpec -> Bool
- GHC.Types.Name.Reader: [is_iloc] :: ImpItemSpec -> !SrcSpan
+ GHC.Types.Name.Reader: [is_iloc] :: ImpItemSpec -> SrcSpan
- GHC.Types.Name.Reader: [is_isboot] :: ImpDeclSpec -> !IsBootInterface
+ GHC.Types.Name.Reader: [is_isboot] :: ImpDeclSpec -> IsBootInterface
- GHC.Types.Name.Reader: [is_item] :: ImportSpec -> !ImpItemSpec
+ GHC.Types.Name.Reader: [is_item] :: ImportSpec -> ImpItemSpec
- GHC.Types.Name.Reader: [is_mod] :: ImpDeclSpec -> !Module
+ GHC.Types.Name.Reader: [is_mod] :: ImpDeclSpec -> Module
- GHC.Types.Name.Reader: [is_pkg_qual] :: ImpDeclSpec -> !PkgQual
+ GHC.Types.Name.Reader: [is_pkg_qual] :: ImpDeclSpec -> PkgQual
- GHC.Types.Name.Reader: [is_qual] :: ImpDeclSpec -> !Bool
+ GHC.Types.Name.Reader: [is_qual] :: ImpDeclSpec -> Bool
- GHC.Types.Name.Reader: [par_is] :: Parent -> !Name
+ GHC.Types.Name.Reader: [par_is] :: Parent -> Name
- GHC.Types.Name.Reader: [recFieldCons] :: RecFieldInfo -> !UniqSet ConLikeName
+ GHC.Types.Name.Reader: [recFieldCons] :: RecFieldInfo -> UniqSet ConLikeName
- GHC.Types.Name.Reader: [recFieldLabel] :: RecFieldInfo -> !FieldLabel
+ GHC.Types.Name.Reader: [recFieldLabel] :: RecFieldInfo -> FieldLabel
- GHC.Types.PkgQual: OtherPkg :: !UnitId -> PkgQual
+ GHC.Types.PkgQual: OtherPkg :: UnitId -> PkgQual
- GHC.Types.PkgQual: ThisPkg :: !UnitId -> PkgQual
+ GHC.Types.PkgQual: ThisPkg :: UnitId -> PkgQual
- GHC.Types.RepType: BoxedRep :: {-# UNPACK #-} !Maybe Levity -> PrimRep
+ GHC.Types.RepType: BoxedRep :: Maybe Levity -> PrimRep
- GHC.Types.SourceFile: HsBootOrSig :: !HsBootOrSig -> HscSource
+ GHC.Types.SourceFile: HsBootOrSig :: HsBootOrSig -> HscSource
- GHC.Types.SrcLoc: BufSpan :: {-# UNPACK #-} !BufPos -> {-# UNPACK #-} !BufPos -> BufSpan
+ GHC.Types.SrcLoc: BufSpan :: BufPos -> BufPos -> BufSpan
- GHC.Types.SrcLoc: DifferentLine :: !Int -> !Int -> DeltaPos
+ GHC.Types.SrcLoc: DifferentLine :: Int -> Int -> DeltaPos
- GHC.Types.SrcLoc: EpaDelta :: !SrcSpan -> !DeltaPos -> !a -> EpaLocation' a
+ GHC.Types.SrcLoc: EpaDelta :: SrcSpan -> DeltaPos -> a -> EpaLocation' a
- GHC.Types.SrcLoc: EpaSpan :: !SrcSpan -> EpaLocation' a
+ GHC.Types.SrcLoc: EpaSpan :: SrcSpan -> EpaLocation' a
- GHC.Types.SrcLoc: PsLoc :: !RealSrcLoc -> !BufPos -> PsLoc
+ GHC.Types.SrcLoc: PsLoc :: RealSrcLoc -> BufPos -> PsLoc
- GHC.Types.SrcLoc: PsSpan :: !RealSrcSpan -> !BufSpan -> PsSpan
+ GHC.Types.SrcLoc: PsSpan :: RealSrcSpan -> BufSpan -> PsSpan
- GHC.Types.SrcLoc: RealSrcLoc :: !RealSrcLoc -> !Maybe BufPos -> SrcLoc
+ GHC.Types.SrcLoc: RealSrcLoc :: RealSrcLoc -> Maybe BufPos -> SrcLoc
- GHC.Types.SrcLoc: RealSrcSpan :: !RealSrcSpan -> !Maybe BufSpan -> SrcSpan
+ GHC.Types.SrcLoc: RealSrcSpan :: RealSrcSpan -> Maybe BufSpan -> SrcSpan
- GHC.Types.SrcLoc: SameLine :: !Int -> DeltaPos
+ GHC.Types.SrcLoc: SameLine :: Int -> DeltaPos
- GHC.Types.SrcLoc: UnhelpfulLoc :: !FastString -> SrcLoc
+ GHC.Types.SrcLoc: UnhelpfulLoc :: FastString -> SrcLoc
- GHC.Types.SrcLoc: UnhelpfulOther :: !FastString -> UnhelpfulSpanReason
+ GHC.Types.SrcLoc: UnhelpfulOther :: FastString -> UnhelpfulSpanReason
- GHC.Types.SrcLoc: UnhelpfulSpan :: !UnhelpfulSpanReason -> SrcSpan
+ GHC.Types.SrcLoc: UnhelpfulSpan :: UnhelpfulSpanReason -> SrcSpan
- GHC.Types.SrcLoc: [bufSpanEnd] :: BufSpan -> {-# UNPACK #-} !BufPos
+ GHC.Types.SrcLoc: [bufSpanEnd] :: BufSpan -> BufPos
- GHC.Types.SrcLoc: [bufSpanStart] :: BufSpan -> {-# UNPACK #-} !BufPos
+ GHC.Types.SrcLoc: [bufSpanStart] :: BufSpan -> BufPos
- GHC.Types.SrcLoc: [deltaColumn] :: DeltaPos -> !Int
+ GHC.Types.SrcLoc: [deltaColumn] :: DeltaPos -> Int
- GHC.Types.SrcLoc: [deltaLine] :: DeltaPos -> !Int
+ GHC.Types.SrcLoc: [deltaLine] :: DeltaPos -> Int
- GHC.Types.SrcLoc: [psBufPos] :: PsLoc -> !BufPos
+ GHC.Types.SrcLoc: [psBufPos] :: PsLoc -> BufPos
- GHC.Types.SrcLoc: [psBufSpan] :: PsSpan -> !BufSpan
+ GHC.Types.SrcLoc: [psBufSpan] :: PsSpan -> BufSpan
- GHC.Types.SrcLoc: [psRealLoc] :: PsLoc -> !RealSrcLoc
+ GHC.Types.SrcLoc: [psRealLoc] :: PsLoc -> RealSrcLoc
- GHC.Types.SrcLoc: [psRealSpan] :: PsSpan -> !RealSrcSpan
+ GHC.Types.SrcLoc: [psRealSpan] :: PsSpan -> RealSrcSpan
- GHC.Types.Target: Target :: !TargetId -> !Bool -> !UnitId -> !Maybe (InputFileBuffer, UTCTime) -> Target
+ GHC.Types.Target: Target :: TargetId -> Bool -> UnitId -> Maybe (InputFileBuffer, UTCTime) -> Target
- GHC.Types.Target: TargetFile :: !FilePath -> !Maybe Phase -> TargetId
+ GHC.Types.Target: TargetFile :: FilePath -> Maybe Phase -> TargetId
- GHC.Types.Target: TargetModule :: !ModuleName -> TargetId
+ GHC.Types.Target: TargetModule :: ModuleName -> TargetId
- GHC.Types.Target: [targetAllowObjCode] :: Target -> !Bool
+ GHC.Types.Target: [targetAllowObjCode] :: Target -> Bool
- GHC.Types.Target: [targetContents] :: Target -> !Maybe (InputFileBuffer, UTCTime)
+ GHC.Types.Target: [targetContents] :: Target -> Maybe (InputFileBuffer, UTCTime)
- GHC.Types.Target: [targetId] :: Target -> !TargetId
+ GHC.Types.Target: [targetId] :: Target -> TargetId
- GHC.Types.Target: [targetUnitId] :: Target -> !UnitId
+ GHC.Types.Target: [targetUnitId] :: Target -> UnitId
- GHC.Types.Tickish: Breakpoint :: XBreakpoint pass -> !Int -> [XTickishId pass] -> Module -> GenTickish (pass :: TickishPass)
+ GHC.Types.Tickish: Breakpoint :: XBreakpoint pass -> BreakpointId -> [XTickishId pass] -> GenTickish (pass :: TickishPass)
- GHC.Types.Tickish: HpcTick :: Module -> !Int -> GenTickish (pass :: TickishPass)
+ GHC.Types.Tickish: HpcTick :: Module -> Int -> GenTickish (pass :: TickishPass)
- GHC.Types.Tickish: ProfNote :: CostCentre -> !Bool -> !Bool -> GenTickish (pass :: TickishPass)
+ GHC.Types.Tickish: ProfNote :: CostCentre -> Bool -> Bool -> GenTickish (pass :: TickishPass)
- GHC.Types.Tickish: [breakpointId] :: GenTickish (pass :: TickishPass) -> !Int
+ GHC.Types.Tickish: [breakpointId] :: GenTickish (pass :: TickishPass) -> BreakpointId
- GHC.Types.Tickish: [profNoteCount] :: GenTickish (pass :: TickishPass) -> !Bool
+ GHC.Types.Tickish: [profNoteCount] :: GenTickish (pass :: TickishPass) -> Bool
- GHC.Types.Tickish: [profNoteScope] :: GenTickish (pass :: TickishPass) -> !Bool
+ GHC.Types.Tickish: [profNoteScope] :: GenTickish (pass :: TickishPass) -> Bool
- GHC.Types.Tickish: [tickId] :: GenTickish (pass :: TickishPass) -> !Int
+ GHC.Types.Tickish: [tickId] :: GenTickish (pass :: TickishPass) -> Int
- GHC.Types.Unique.FM: delListFromUFM :: Uniquable key => UniqFM key elt -> [key] -> UniqFM key elt
+ GHC.Types.Unique.FM: delListFromUFM :: (Uniquable key, Foldable f) => UniqFM key elt -> f key -> UniqFM key elt
- GHC.Types.Unique.FM: delListFromUFM_Directly :: forall {k} (key :: k) elt. UniqFM key elt -> [Unique] -> UniqFM key elt
+ GHC.Types.Unique.FM: delListFromUFM_Directly :: forall {k} f (key :: k) elt. Foldable f => UniqFM key elt -> f Unique -> UniqFM key elt
- GHC.Types.Var: Invisible :: !Specificity -> ForAllTyFlag
+ GHC.Types.Var: Invisible :: Specificity -> ForAllTyFlag
- GHC.Types.Var: idDetails :: Id -> IdDetails
+ GHC.Types.Var: idDetails :: HasCallStack => Id -> IdDetails
- GHC.Types.Var.Env: delVarEnvList :: VarEnv a -> [Var] -> VarEnv a
+ GHC.Types.Var.Env: delVarEnvList :: Foldable f => VarEnv a -> f Var -> VarEnv a
- GHC.Unit.Env: HomeUnitEnv :: !UnitState -> !Maybe [UnitDatabase UnitId] -> DynFlags -> HomePackageTable -> !Maybe HomeUnit -> HomeUnitEnv
+ GHC.Unit.Env: HomeUnitEnv :: UnitState -> Maybe [UnitDatabase UnitId] -> DynFlags -> HomePackageTable -> Maybe HomeUnit -> HomeUnitEnv
- GHC.Unit.Env: UnitEnv :: {-# UNPACK #-} !ExternalUnitCache -> UnitId -> !HomeUnitGraph -> !Platform -> !GhcNameVersion -> UnitEnv
+ GHC.Unit.Env: UnitEnv :: ExternalUnitCache -> UnitId -> ModuleGraph -> HomeUnitGraph -> Platform -> GhcNameVersion -> UnitEnv
- GHC.Unit.Env: [homeUnitEnv_home_unit] :: HomeUnitEnv -> !Maybe HomeUnit
+ GHC.Unit.Env: [homeUnitEnv_home_unit] :: HomeUnitEnv -> Maybe HomeUnit
- GHC.Unit.Env: [homeUnitEnv_unit_dbs] :: HomeUnitEnv -> !Maybe [UnitDatabase UnitId]
+ GHC.Unit.Env: [homeUnitEnv_unit_dbs] :: HomeUnitEnv -> Maybe [UnitDatabase UnitId]
- GHC.Unit.Env: [homeUnitEnv_units] :: HomeUnitEnv -> !UnitState
+ GHC.Unit.Env: [homeUnitEnv_units] :: HomeUnitEnv -> UnitState
- GHC.Unit.Env: [ue_eps] :: UnitEnv -> {-# UNPACK #-} !ExternalUnitCache
+ GHC.Unit.Env: [ue_eps] :: UnitEnv -> ExternalUnitCache
- GHC.Unit.Env: [ue_home_unit_graph] :: UnitEnv -> !HomeUnitGraph
+ GHC.Unit.Env: [ue_home_unit_graph] :: UnitEnv -> HomeUnitGraph
- GHC.Unit.Env: [ue_namever] :: UnitEnv -> !GhcNameVersion
+ GHC.Unit.Env: [ue_namever] :: UnitEnv -> GhcNameVersion
- GHC.Unit.Env: [ue_platform] :: UnitEnv -> !Platform
+ GHC.Unit.Env: [ue_platform] :: UnitEnv -> Platform
- GHC.Unit.External: EPS :: !InstalledModuleEnv ModuleNameWithIsBoot -> !PackageIfaceTable -> InstalledModuleEnv (UniqDSet ModuleName) -> !PackageTypeEnv -> !ModuleEnv (IO Linkable) -> !PackageInstEnv -> !PackageFamInstEnv -> !PackageRuleBase -> !PackageAnnEnv -> !PackageCompleteMatches -> !ModuleEnv FamInstEnv -> !EpsStats -> !ModuleEnv DefaultEnv -> ExternalPackageState
+ GHC.Unit.External: EPS :: InstalledModuleEnv ModuleNameWithIsBoot -> PackageIfaceTable -> InstalledModuleEnv (UniqDSet ModuleName) -> PackageTypeEnv -> ModuleEnv (IO Linkable) -> PackageInstEnv -> PackageFamInstEnv -> PackageRuleBase -> PackageAnnEnv -> PackageCompleteMatches -> ModuleEnv FamInstEnv -> EpsStats -> ModuleEnv DefaultEnv -> ExternalPackageState
- GHC.Unit.External: EpsStats :: !Int -> !Int -> !Int -> !Int -> !Int -> !Int -> !Int -> EpsStats
+ GHC.Unit.External: EpsStats :: Int -> Int -> Int -> Int -> Int -> Int -> Int -> EpsStats
- GHC.Unit.External: [eps_PIT] :: ExternalPackageState -> !PackageIfaceTable
+ GHC.Unit.External: [eps_PIT] :: ExternalPackageState -> PackageIfaceTable
- GHC.Unit.External: [eps_PTE] :: ExternalPackageState -> !PackageTypeEnv
+ GHC.Unit.External: [eps_PTE] :: ExternalPackageState -> PackageTypeEnv
- GHC.Unit.External: [eps_ann_env] :: ExternalPackageState -> !PackageAnnEnv
+ GHC.Unit.External: [eps_ann_env] :: ExternalPackageState -> PackageAnnEnv
- GHC.Unit.External: [eps_complete_matches] :: ExternalPackageState -> !PackageCompleteMatches
+ GHC.Unit.External: [eps_complete_matches] :: ExternalPackageState -> PackageCompleteMatches
- GHC.Unit.External: [eps_defaults] :: ExternalPackageState -> !ModuleEnv DefaultEnv
+ GHC.Unit.External: [eps_defaults] :: ExternalPackageState -> ModuleEnv DefaultEnv
- GHC.Unit.External: [eps_fam_inst_env] :: ExternalPackageState -> !PackageFamInstEnv
+ GHC.Unit.External: [eps_fam_inst_env] :: ExternalPackageState -> PackageFamInstEnv
- GHC.Unit.External: [eps_iface_bytecode] :: ExternalPackageState -> !ModuleEnv (IO Linkable)
+ GHC.Unit.External: [eps_iface_bytecode] :: ExternalPackageState -> ModuleEnv (IO Linkable)
- GHC.Unit.External: [eps_inst_env] :: ExternalPackageState -> !PackageInstEnv
+ GHC.Unit.External: [eps_inst_env] :: ExternalPackageState -> PackageInstEnv
- GHC.Unit.External: [eps_is_boot] :: ExternalPackageState -> !InstalledModuleEnv ModuleNameWithIsBoot
+ GHC.Unit.External: [eps_is_boot] :: ExternalPackageState -> InstalledModuleEnv ModuleNameWithIsBoot
- GHC.Unit.External: [eps_mod_fam_inst_env] :: ExternalPackageState -> !ModuleEnv FamInstEnv
+ GHC.Unit.External: [eps_mod_fam_inst_env] :: ExternalPackageState -> ModuleEnv FamInstEnv
- GHC.Unit.External: [eps_rule_base] :: ExternalPackageState -> !PackageRuleBase
+ GHC.Unit.External: [eps_rule_base] :: ExternalPackageState -> PackageRuleBase
- GHC.Unit.External: [eps_stats] :: ExternalPackageState -> !EpsStats
+ GHC.Unit.External: [eps_stats] :: ExternalPackageState -> EpsStats
- GHC.Unit.External: [n_decls_in] :: EpsStats -> !Int
+ GHC.Unit.External: [n_decls_in] :: EpsStats -> Int
- GHC.Unit.External: [n_decls_out] :: EpsStats -> !Int
+ GHC.Unit.External: [n_decls_out] :: EpsStats -> Int
- GHC.Unit.External: [n_ifaces_in] :: EpsStats -> !Int
+ GHC.Unit.External: [n_ifaces_in] :: EpsStats -> Int
- GHC.Unit.External: [n_insts_in] :: EpsStats -> !Int
+ GHC.Unit.External: [n_insts_in] :: EpsStats -> Int
- GHC.Unit.External: [n_insts_out] :: EpsStats -> !Int
+ GHC.Unit.External: [n_insts_out] :: EpsStats -> Int
- GHC.Unit.External: [n_rules_in] :: EpsStats -> !Int
+ GHC.Unit.External: [n_rules_in] :: EpsStats -> Int
- GHC.Unit.External: [n_rules_out] :: EpsStats -> !Int
+ GHC.Unit.External: [n_rules_out] :: EpsStats -> Int
- GHC.Unit.Finder: FinderCache :: (UnitEnv -> IO ()) -> (InstalledModuleWithIsBoot -> InstalledFindResult -> IO ()) -> (InstalledModuleWithIsBoot -> IO (Maybe InstalledFindResult)) -> (FilePath -> IO Fingerprint) -> FinderCache
+ GHC.Unit.Finder: FinderCache :: (UnitEnv -> IO ()) -> (InstalledModule -> InstalledFindResult -> IO ()) -> (InstalledModule -> IO (Maybe InstalledFindResult)) -> (FilePath -> IO Fingerprint) -> FinderCache
- GHC.Unit.Finder: InstalledFound :: ModLocation -> InstalledModule -> InstalledFindResult
+ GHC.Unit.Finder: InstalledFound :: ModLocation -> InstalledFindResult
- GHC.Unit.Finder: [addToFinderCache] :: FinderCache -> InstalledModuleWithIsBoot -> InstalledFindResult -> IO ()
+ GHC.Unit.Finder: [addToFinderCache] :: FinderCache -> InstalledModule -> InstalledFindResult -> IO ()
- GHC.Unit.Finder: [lookupFinderCache] :: FinderCache -> InstalledModuleWithIsBoot -> IO (Maybe InstalledFindResult)
+ GHC.Unit.Finder: [lookupFinderCache] :: FinderCache -> InstalledModule -> IO (Maybe InstalledFindResult)
- GHC.Unit.Finder: addHomeModuleToFinder :: FinderCache -> HomeUnit -> ModuleNameWithIsBoot -> ModLocation -> IO Module
+ GHC.Unit.Finder: addHomeModuleToFinder :: FinderCache -> HomeUnit -> ModuleName -> ModLocation -> HscSource -> IO Module
- GHC.Unit.Finder: addModuleToFinder :: FinderCache -> ModuleWithIsBoot -> ModLocation -> IO ()
+ GHC.Unit.Finder: addModuleToFinder :: FinderCache -> Module -> ModLocation -> HscSource -> IO ()
- GHC.Unit.Finder: findExactModule :: FinderCache -> FinderOpts -> UnitEnvGraph FinderOpts -> UnitState -> Maybe HomeUnit -> InstalledModule -> IO InstalledFindResult
+ GHC.Unit.Finder: findExactModule :: HscEnv -> InstalledModule -> IsBootInterface -> IO InstalledFindResult
- GHC.Unit.Finder: findPluginModule :: FinderCache -> FinderOpts -> UnitState -> Maybe HomeUnit -> ModuleName -> IO FindResult
+ GHC.Unit.Finder: findPluginModule :: HscEnv -> ModuleName -> IO FindResult
- GHC.Unit.Finder: mkHomeModLocation :: FinderOpts -> ModuleName -> OsPath -> ModLocation
+ GHC.Unit.Finder: mkHomeModLocation :: FinderOpts -> ModuleName -> OsPath -> FileExt -> HscSource -> ModLocation
- GHC.Unit.Finder.Types: FinderCache :: (UnitEnv -> IO ()) -> (InstalledModuleWithIsBoot -> InstalledFindResult -> IO ()) -> (InstalledModuleWithIsBoot -> IO (Maybe InstalledFindResult)) -> (FilePath -> IO Fingerprint) -> FinderCache
+ GHC.Unit.Finder.Types: FinderCache :: (UnitEnv -> IO ()) -> (InstalledModule -> InstalledFindResult -> IO ()) -> (InstalledModule -> IO (Maybe InstalledFindResult)) -> (FilePath -> IO Fingerprint) -> FinderCache
- GHC.Unit.Finder.Types: InstalledFound :: ModLocation -> InstalledModule -> InstalledFindResult
+ GHC.Unit.Finder.Types: InstalledFound :: ModLocation -> InstalledFindResult
- GHC.Unit.Finder.Types: [addToFinderCache] :: FinderCache -> InstalledModuleWithIsBoot -> InstalledFindResult -> IO ()
+ GHC.Unit.Finder.Types: [addToFinderCache] :: FinderCache -> InstalledModule -> InstalledFindResult -> IO ()
- GHC.Unit.Finder.Types: [lookupFinderCache] :: FinderCache -> InstalledModuleWithIsBoot -> IO (Maybe InstalledFindResult)
+ GHC.Unit.Finder.Types: [lookupFinderCache] :: FinderCache -> InstalledModule -> IO (Maybe InstalledFindResult)
- GHC.Unit.Home.ModInfo: HomeModInfo :: !ModIface -> ModDetails -> !HomeModLinkable -> HomeModInfo
+ GHC.Unit.Home.ModInfo: HomeModInfo :: ModIface -> ModDetails -> HomeModLinkable -> HomeModInfo
- GHC.Unit.Home.ModInfo: HomeModLinkable :: !Maybe Linkable -> !Maybe Linkable -> HomeModLinkable
+ GHC.Unit.Home.ModInfo: HomeModLinkable :: Maybe Linkable -> Maybe Linkable -> HomeModLinkable
- GHC.Unit.Home.ModInfo: [hm_iface] :: HomeModInfo -> !ModIface
+ GHC.Unit.Home.ModInfo: [hm_iface] :: HomeModInfo -> ModIface
- GHC.Unit.Home.ModInfo: [hm_linkable] :: HomeModInfo -> !HomeModLinkable
+ GHC.Unit.Home.ModInfo: [hm_linkable] :: HomeModInfo -> HomeModLinkable
- GHC.Unit.Home.ModInfo: [homeMod_bytecode] :: HomeModLinkable -> !Maybe Linkable
+ GHC.Unit.Home.ModInfo: [homeMod_bytecode] :: HomeModLinkable -> Maybe Linkable
- GHC.Unit.Home.ModInfo: [homeMod_object] :: HomeModLinkable -> !Maybe Linkable
+ GHC.Unit.Home.ModInfo: [homeMod_object] :: HomeModLinkable -> Maybe Linkable
- GHC.Unit.Module.Deps: ImportAvails :: ImportedMods -> InstalledModuleEnv ModuleNameWithIsBoot -> Set UnitId -> Bool -> Set UnitId -> InstalledModuleEnv ModuleNameWithIsBoot -> [ModuleName] -> [Module] -> [Module] -> ImportAvails
+ GHC.Unit.Module.Deps: ImportAvails :: ImportedMods -> InstalledModuleEnv (Set ImportLevel, ModuleNameWithIsBoot) -> Set (ImportLevel, UnitId) -> Bool -> Set UnitId -> InstalledModuleEnv ModuleNameWithIsBoot -> [ModuleName] -> [Module] -> [Module] -> ImportAvails
- GHC.Unit.Module.Deps: UsageHomeModule :: ModuleName -> UnitId -> Fingerprint -> [(OccName, Fingerprint)] -> Maybe Fingerprint -> IsSafeImport -> Usage
+ GHC.Unit.Module.Deps: UsageHomeModule :: ModuleName -> UnitId -> Fingerprint -> [(OccName, Fingerprint)] -> Maybe HomeModImport -> IsSafeImport -> Usage
- GHC.Unit.Module.Deps: [imp_dep_direct_pkgs] :: ImportAvails -> Set UnitId
+ GHC.Unit.Module.Deps: [imp_dep_direct_pkgs] :: ImportAvails -> Set (ImportLevel, UnitId)
- GHC.Unit.Module.Deps: [imp_direct_dep_mods] :: ImportAvails -> InstalledModuleEnv ModuleNameWithIsBoot
+ GHC.Unit.Module.Deps: [imp_direct_dep_mods] :: ImportAvails -> InstalledModuleEnv (Set ImportLevel, ModuleNameWithIsBoot)
- GHC.Unit.Module.Deps: [usg_exports] :: Usage -> Maybe Fingerprint
+ GHC.Unit.Module.Deps: [usg_exports] :: Usage -> Maybe HomeModImport
- GHC.Unit.Module.Graph: ModNodeKeyWithUid :: !ModuleNameWithIsBoot -> !UnitId -> ModNodeKeyWithUid
+ GHC.Unit.Module.Graph: ModNodeKeyWithUid :: ModuleNameWithIsBoot -> UnitId -> ModNodeKeyWithUid
- GHC.Unit.Module.Graph: ModuleNode :: [NodeKey] -> ModSummary -> ModuleGraphNode
+ GHC.Unit.Module.Graph: ModuleNode :: [ModuleNodeEdge] -> ModuleNodeInfo -> ModuleGraphNode
- GHC.Unit.Module.Graph: NodeKey_Link :: !UnitId -> NodeKey
+ GHC.Unit.Module.Graph: NodeKey_Link :: UnitId -> NodeKey
- GHC.Unit.Module.Graph: NodeKey_Module :: {-# UNPACK #-} !ModNodeKeyWithUid -> NodeKey
+ GHC.Unit.Module.Graph: NodeKey_Module :: ModNodeKeyWithUid -> NodeKey
- GHC.Unit.Module.Graph: NodeKey_Unit :: {-# UNPACK #-} !InstantiatedUnit -> NodeKey
+ GHC.Unit.Module.Graph: NodeKey_Unit :: InstantiatedUnit -> NodeKey
- GHC.Unit.Module.Graph: [mnkModuleName] :: ModNodeKeyWithUid -> !ModuleNameWithIsBoot
+ GHC.Unit.Module.Graph: [mnkModuleName] :: ModNodeKeyWithUid -> ModuleNameWithIsBoot
- GHC.Unit.Module.Graph: [mnkUnitId] :: ModNodeKeyWithUid -> !UnitId
+ GHC.Unit.Module.Graph: [mnkUnitId] :: ModNodeKeyWithUid -> UnitId
- GHC.Unit.Module.Graph: filterToposortToModules :: [SCC ModuleGraphNode] -> [SCC ModSummary]
+ GHC.Unit.Module.Graph: filterToposortToModules :: [SCC ModuleGraphNode] -> [SCC ModuleNodeInfo]
- GHC.Unit.Module.Graph: mgLookupModule :: ModuleGraph -> Module -> Maybe ModSummary
+ GHC.Unit.Module.Graph: mgLookupModule :: ModuleGraph -> Module -> Maybe ModuleNodeInfo
- GHC.Unit.Module.Imported: ImportedModsVal :: ModuleName -> SrcSpan -> IsSafeImport -> Bool -> !GlobalRdrEnv -> Bool -> ImportedModsVal
+ GHC.Unit.Module.Imported: ImportedModsVal :: ModuleName -> SrcSpan -> IsSafeImport -> ImportLevel -> Bool -> GlobalRdrEnv -> Bool -> ImportedModsVal
- GHC.Unit.Module.Imported: [imv_all_exports] :: ImportedModsVal -> !GlobalRdrEnv
+ GHC.Unit.Module.Imported: [imv_all_exports] :: ImportedModsVal -> GlobalRdrEnv
- GHC.Unit.Module.ModDetails: ModDetails :: [AvailInfo] -> !TypeEnv -> !DefaultEnv -> InstEnv -> ![FamInst] -> ![CoreRule] -> ![Annotation] -> CompleteMatches -> ModDetails
+ GHC.Unit.Module.ModDetails: ModDetails :: [AvailInfo] -> TypeEnv -> DefaultEnv -> InstEnv -> [FamInst] -> [CoreRule] -> [Annotation] -> CompleteMatches -> ModDetails
- GHC.Unit.Module.ModDetails: [md_anns] :: ModDetails -> ![Annotation]
+ GHC.Unit.Module.ModDetails: [md_anns] :: ModDetails -> [Annotation]
- GHC.Unit.Module.ModDetails: [md_defaults] :: ModDetails -> !DefaultEnv
+ GHC.Unit.Module.ModDetails: [md_defaults] :: ModDetails -> DefaultEnv
- GHC.Unit.Module.ModDetails: [md_fam_insts] :: ModDetails -> ![FamInst]
+ GHC.Unit.Module.ModDetails: [md_fam_insts] :: ModDetails -> [FamInst]
- GHC.Unit.Module.ModDetails: [md_rules] :: ModDetails -> ![CoreRule]
+ GHC.Unit.Module.ModDetails: [md_rules] :: ModDetails -> [CoreRule]
- GHC.Unit.Module.ModDetails: [md_types] :: ModDetails -> !TypeEnv
+ GHC.Unit.Module.ModDetails: [md_types] :: ModDetails -> TypeEnv
- GHC.Unit.Module.ModGuts: CgGuts :: !Module -> [TyCon] -> CoreProgram -> [CostCentre] -> !ForeignStubs -> ![(ForeignSrcLang, FilePath)] -> !Set UnitId -> !Maybe ModBreaks -> [SptEntry] -> CgGuts
+ GHC.Unit.Module.ModGuts: CgGuts :: Module -> [TyCon] -> CoreProgram -> [CostCentre] -> ForeignStubs -> [(ForeignSrcLang, FilePath)] -> Set UnitId -> Maybe ModBreaks -> [SptEntry] -> CgGuts
- GHC.Unit.Module.ModGuts: ModGuts :: !Module -> HscSource -> SrcSpan -> ![AvailInfo] -> !Dependencies -> ![Usage] -> !Bool -> !GlobalRdrEnv -> !FixityEnv -> ![TyCon] -> !DefaultEnv -> ![ClsInst] -> ![FamInst] -> ![PatSyn] -> ![CoreRule] -> !CoreProgram -> !ForeignStubs -> ![(ForeignSrcLang, FilePath)] -> !Warnings GhcRn -> [Annotation] -> CompleteMatches -> !HpcInfo -> !Maybe ModBreaks -> InstEnv -> FamInstEnv -> !NameSet -> SafeHaskellMode -> Bool -> !Maybe Docs -> ModGuts
+ GHC.Unit.Module.ModGuts: ModGuts :: Module -> HscSource -> SrcSpan -> [AvailInfo] -> Dependencies -> Maybe [Usage] -> GlobalRdrEnv -> FixityEnv -> [TyCon] -> DefaultEnv -> [ClsInst] -> [FamInst] -> [PatSyn] -> [CoreRule] -> CoreProgram -> ForeignStubs -> [(ForeignSrcLang, FilePath)] -> Warnings GhcRn -> [Annotation] -> CompleteMatches -> HpcInfo -> Maybe ModBreaks -> InstEnv -> FamInstEnv -> NameSet -> SafeHaskellMode -> Bool -> Maybe Docs -> ModGuts
- GHC.Unit.Module.ModGuts: [cg_dep_pkgs] :: CgGuts -> !Set UnitId
+ GHC.Unit.Module.ModGuts: [cg_dep_pkgs] :: CgGuts -> Set UnitId
- GHC.Unit.Module.ModGuts: [cg_foreign] :: CgGuts -> !ForeignStubs
+ GHC.Unit.Module.ModGuts: [cg_foreign] :: CgGuts -> ForeignStubs
- GHC.Unit.Module.ModGuts: [cg_foreign_files] :: CgGuts -> ![(ForeignSrcLang, FilePath)]
+ GHC.Unit.Module.ModGuts: [cg_foreign_files] :: CgGuts -> [(ForeignSrcLang, FilePath)]
- GHC.Unit.Module.ModGuts: [cg_modBreaks] :: CgGuts -> !Maybe ModBreaks
+ GHC.Unit.Module.ModGuts: [cg_modBreaks] :: CgGuts -> Maybe ModBreaks
- GHC.Unit.Module.ModGuts: [cg_module] :: CgGuts -> !Module
+ GHC.Unit.Module.ModGuts: [cg_module] :: CgGuts -> Module
- GHC.Unit.Module.ModGuts: [mg_binds] :: ModGuts -> !CoreProgram
+ GHC.Unit.Module.ModGuts: [mg_binds] :: ModGuts -> CoreProgram
- GHC.Unit.Module.ModGuts: [mg_boot_exports] :: ModGuts -> !NameSet
+ GHC.Unit.Module.ModGuts: [mg_boot_exports] :: ModGuts -> NameSet
- GHC.Unit.Module.ModGuts: [mg_defaults] :: ModGuts -> !DefaultEnv
+ GHC.Unit.Module.ModGuts: [mg_defaults] :: ModGuts -> DefaultEnv
- GHC.Unit.Module.ModGuts: [mg_deps] :: ModGuts -> !Dependencies
+ GHC.Unit.Module.ModGuts: [mg_deps] :: ModGuts -> Dependencies
- GHC.Unit.Module.ModGuts: [mg_docs] :: ModGuts -> !Maybe Docs
+ GHC.Unit.Module.ModGuts: [mg_docs] :: ModGuts -> Maybe Docs
- GHC.Unit.Module.ModGuts: [mg_exports] :: ModGuts -> ![AvailInfo]
+ GHC.Unit.Module.ModGuts: [mg_exports] :: ModGuts -> [AvailInfo]
- GHC.Unit.Module.ModGuts: [mg_fam_insts] :: ModGuts -> ![FamInst]
+ GHC.Unit.Module.ModGuts: [mg_fam_insts] :: ModGuts -> [FamInst]
- GHC.Unit.Module.ModGuts: [mg_fix_env] :: ModGuts -> !FixityEnv
+ GHC.Unit.Module.ModGuts: [mg_fix_env] :: ModGuts -> FixityEnv
- GHC.Unit.Module.ModGuts: [mg_foreign] :: ModGuts -> !ForeignStubs
+ GHC.Unit.Module.ModGuts: [mg_foreign] :: ModGuts -> ForeignStubs
- GHC.Unit.Module.ModGuts: [mg_foreign_files] :: ModGuts -> ![(ForeignSrcLang, FilePath)]
+ GHC.Unit.Module.ModGuts: [mg_foreign_files] :: ModGuts -> [(ForeignSrcLang, FilePath)]
- GHC.Unit.Module.ModGuts: [mg_hpc_info] :: ModGuts -> !HpcInfo
+ GHC.Unit.Module.ModGuts: [mg_hpc_info] :: ModGuts -> HpcInfo
- GHC.Unit.Module.ModGuts: [mg_insts] :: ModGuts -> ![ClsInst]
+ GHC.Unit.Module.ModGuts: [mg_insts] :: ModGuts -> [ClsInst]
- GHC.Unit.Module.ModGuts: [mg_modBreaks] :: ModGuts -> !Maybe ModBreaks
+ GHC.Unit.Module.ModGuts: [mg_modBreaks] :: ModGuts -> Maybe ModBreaks
- GHC.Unit.Module.ModGuts: [mg_module] :: ModGuts -> !Module
+ GHC.Unit.Module.ModGuts: [mg_module] :: ModGuts -> Module
- GHC.Unit.Module.ModGuts: [mg_patsyns] :: ModGuts -> ![PatSyn]
+ GHC.Unit.Module.ModGuts: [mg_patsyns] :: ModGuts -> [PatSyn]
- GHC.Unit.Module.ModGuts: [mg_rdr_env] :: ModGuts -> !GlobalRdrEnv
+ GHC.Unit.Module.ModGuts: [mg_rdr_env] :: ModGuts -> GlobalRdrEnv
- GHC.Unit.Module.ModGuts: [mg_rules] :: ModGuts -> ![CoreRule]
+ GHC.Unit.Module.ModGuts: [mg_rules] :: ModGuts -> [CoreRule]
- GHC.Unit.Module.ModGuts: [mg_tcs] :: ModGuts -> ![TyCon]
+ GHC.Unit.Module.ModGuts: [mg_tcs] :: ModGuts -> [TyCon]
- GHC.Unit.Module.ModGuts: [mg_usages] :: ModGuts -> ![Usage]
+ GHC.Unit.Module.ModGuts: [mg_usages] :: ModGuts -> Maybe [Usage]
- GHC.Unit.Module.ModGuts: [mg_warns] :: ModGuts -> !Warnings GhcRn
+ GHC.Unit.Module.ModGuts: [mg_warns] :: ModGuts -> Warnings GhcRn
- GHC.Unit.Module.ModIface: IfaceTopEnv :: !IfGlobalRdrEnv -> ![IfaceImport] -> IfaceTopEnv
+ GHC.Unit.Module.ModIface: IfaceTopEnv :: DetOrdAvails -> [IfaceImport] -> IfaceTopEnv
- GHC.Unit.Module.ModIface: [FullIfaceBinHandle] :: !Maybe FullBinData -> IfaceBinHandle 'ModIfaceFinal
+ GHC.Unit.Module.ModIface: [FullIfaceBinHandle] :: Maybe FullBinData -> IfaceBinHandle 'ModIfaceFinal
- GHC.Unit.Module.ModIface: [ifaceImports] :: IfaceTopEnv -> ![IfaceImport]
+ GHC.Unit.Module.ModIface: [ifaceImports] :: IfaceTopEnv -> [IfaceImport]
- GHC.Unit.Module.ModIface: [ifaceTopExports] :: IfaceTopEnv -> !IfGlobalRdrEnv
+ GHC.Unit.Module.ModIface: [ifaceTopExports] :: IfaceTopEnv -> DetOrdAvails
- GHC.Unit.Module.ModIface: completePartialModIface :: PartialModIface -> [(Fingerprint, IfaceDecl)] -> Maybe [IfaceBindingX IfaceMaybeRhs IfaceTopBndrInfo] -> ModIfaceBackend -> ModIface
+ GHC.Unit.Module.ModIface: completePartialModIface :: PartialModIface -> Fingerprint -> [(Fingerprint, IfaceDecl)] -> Maybe IfaceSimplifiedCore -> IfaceAbiHashes -> IfaceCache -> ModIface
- GHC.Unit.Module.ModIface: pattern ModIface :: Module -> Maybe Module -> HscSource -> Dependencies -> [Usage] -> [IfaceExport] -> Bool -> [(OccName, Fixity)] -> IfaceWarnings -> [IfaceAnnotation] -> [IfaceDeclExts phase] -> Maybe [IfaceBindingX IfaceMaybeRhs IfaceTopBndrInfo] -> IfaceForeign -> [IfaceDefault] -> Maybe IfaceTopEnv -> [IfaceClsInst] -> [IfaceFamInst] -> [IfaceRule] -> AnyHpcUsage -> IfaceTrustInfo -> Bool -> [IfaceCompleteMatch] -> Maybe Docs -> IfaceBackendExts phase -> ExtensibleFields -> Fingerprint -> IfaceBinHandle phase -> ModIface_ phase
+ GHC.Unit.Module.ModIface: pattern ModIface :: IfaceModInfo -> Module -> Maybe Module -> HscSource -> Fingerprint -> Dependencies -> IfacePublic_ phase -> [IfaceExport] -> [(OccName, Fixity)] -> IfaceWarnings -> [IfaceAnnotation] -> [IfaceDeclExts phase] -> Maybe IfaceSimplifiedCore -> [IfaceDefault] -> IfaceTopEnv -> [IfaceClsInst] -> [IfaceFamInst] -> [IfaceRule] -> IfaceTrustInfo -> Bool -> [IfaceCompleteMatch] -> Maybe Docs -> IfaceAbiHashesExts phase -> ExtensibleFields -> IfaceBinHandle phase -> Maybe IfaceSelfRecomp -> (OccName -> Maybe Fixity) -> (OccName -> Maybe (OccName, Fingerprint)) -> (OccName -> Maybe (WarningTxt GhcRn)) -> (Name -> Maybe (WarningTxt GhcRn)) -> ModIface_ phase
- GHC.Unit.Module.ModIface: set_mi_top_env :: forall (phase :: ModIfacePhase). Maybe IfaceTopEnv -> ModIface_ phase -> ModIface_ phase
+ GHC.Unit.Module.ModIface: set_mi_top_env :: forall (phase :: ModIfacePhase). IfaceTopEnv -> ModIface_ phase -> ModIface_ phase
- GHC.Unit.Module.ModIface: type family IfaceBackendExts (phase :: ModIfacePhase) = (bk :: Type) | bk -> phase
+ GHC.Unit.Module.ModIface: type family IfaceAbiHashesExts (phase :: ModIfacePhase) = (bk :: Type) | bk -> phase
- GHC.Unit.Module.ModSummary: ModSummary :: Module -> HscSource -> ModLocation -> Fingerprint -> Maybe UTCTime -> !Maybe UTCTime -> Maybe UTCTime -> Maybe UTCTime -> [(PkgQual, Located ModuleName)] -> [(PkgQual, Located ModuleName)] -> !Bool -> Maybe HsParsedModule -> FilePath -> DynFlags -> Maybe StringBuffer -> ModSummary
+ GHC.Unit.Module.ModSummary: ModSummary :: Module -> HscSource -> ModLocation -> Fingerprint -> Maybe UTCTime -> Maybe UTCTime -> Maybe UTCTime -> Maybe UTCTime -> [Located ModuleName] -> [(ImportLevel, PkgQual, Located ModuleName)] -> Maybe HsParsedModule -> FilePath -> DynFlags -> Maybe StringBuffer -> ModSummary
- GHC.Unit.Module.ModSummary: [ms_dyn_obj_date] :: ModSummary -> !Maybe UTCTime
+ GHC.Unit.Module.ModSummary: [ms_dyn_obj_date] :: ModSummary -> Maybe UTCTime
- GHC.Unit.Module.ModSummary: [ms_srcimps] :: ModSummary -> [(PkgQual, Located ModuleName)]
+ GHC.Unit.Module.ModSummary: [ms_srcimps] :: ModSummary -> [Located ModuleName]
- GHC.Unit.Module.ModSummary: [ms_textual_imps] :: ModSummary -> [(PkgQual, Located ModuleName)]
+ GHC.Unit.Module.ModSummary: [ms_textual_imps] :: ModSummary -> [(ImportLevel, PkgQual, Located ModuleName)]
- GHC.Unit.Module.ModSummary: msDeps :: ModSummary -> [(PkgQual, GenWithIsBoot (Located ModuleName))]
+ GHC.Unit.Module.ModSummary: msDeps :: ModSummary -> [(ImportLevel, PkgQual, GenWithIsBoot (Located ModuleName))]
- GHC.Unit.Module.ModSummary: ms_home_imps :: ModSummary -> [(PkgQual, Located ModuleName)]
+ GHC.Unit.Module.ModSummary: ms_home_imps :: ModSummary -> [(ImportLevel, PkgQual, Located ModuleName)]
- GHC.Unit.Module.ModSummary: ms_imps :: ModSummary -> [(PkgQual, Located ModuleName)]
+ GHC.Unit.Module.ModSummary: ms_imps :: ModSummary -> [(ImportLevel, PkgQual, Located ModuleName)]
- GHC.Unit.Module.ModSummary: ms_plugin_imps :: ModSummary -> [(PkgQual, Located ModuleName)]
+ GHC.Unit.Module.ModSummary: ms_plugin_imps :: ModSummary -> [(ImportLevel, PkgQual, Located ModuleName)]
- GHC.Unit.Module.Status: HscRecomp :: CgGuts -> !ModLocation -> !PartialModIface -> !Maybe Fingerprint -> HscBackendAction
+ GHC.Unit.Module.Status: HscRecomp :: CgGuts -> ModLocation -> PartialModIface -> Maybe Fingerprint -> HscBackendAction
- GHC.Unit.Module.Status: [hscs_mod_location] :: HscBackendAction -> !ModLocation
+ GHC.Unit.Module.Status: [hscs_mod_location] :: HscBackendAction -> ModLocation
- GHC.Unit.Module.Status: [hscs_old_iface_hash] :: HscBackendAction -> !Maybe Fingerprint
+ GHC.Unit.Module.Status: [hscs_old_iface_hash] :: HscBackendAction -> Maybe Fingerprint
- GHC.Unit.Module.Status: [hscs_partial_iface] :: HscBackendAction -> !PartialModIface
+ GHC.Unit.Module.Status: [hscs_partial_iface] :: HscBackendAction -> PartialModIface
- GHC.Unit.Module.Warnings: InWarningCategory :: !EpToken "in" -> !SourceText -> LocatedE WarningCategory -> InWarningCategory
+ GHC.Unit.Module.Warnings: InWarningCategory :: EpToken "in" -> SourceText -> LocatedE WarningCategory -> InWarningCategory
- GHC.Unit.Module.Warnings: [iwc_in] :: InWarningCategory -> !EpToken "in"
+ GHC.Unit.Module.Warnings: [iwc_in] :: InWarningCategory -> EpToken "in"
- GHC.Unit.Module.Warnings: [iwc_st] :: InWarningCategory -> !SourceText
+ GHC.Unit.Module.Warnings: [iwc_st] :: InWarningCategory -> SourceText
- GHC.Unit.State: CloseUnitErr :: !UnitId -> !Maybe UnitId -> UnitErr
+ GHC.Unit.State: CloseUnitErr :: UnitId -> Maybe UnitId -> UnitErr
- GHC.Unit.State: ModUnusable :: !UnusableUnit -> ModuleOrigin
+ GHC.Unit.State: ModUnusable :: UnusableUnit -> ModuleOrigin
- GHC.Unit.State: PackageFlagErr :: !PackageFlag -> ![(UnitInfo, UnusableUnitReason)] -> UnitErr
+ GHC.Unit.State: PackageFlagErr :: PackageFlag -> [(UnitInfo, UnusableUnitReason)] -> UnitErr
- GHC.Unit.State: TrustFlagErr :: !TrustFlag -> ![(UnitInfo, UnusableUnitReason)] -> UnitErr
+ GHC.Unit.State: TrustFlagErr :: TrustFlag -> [(UnitInfo, UnusableUnitReason)] -> UnitErr
- GHC.Unit.State: UnitState :: UnitInfoMap -> PreloadUnitClosure -> UniqFM PackageName UnitId -> UniqMap UnitId UnitId -> UniqMap UnitId UnitId -> [UnitId] -> [(Unit, Maybe PackageArg)] -> [UnitId] -> !ModuleNameProvidersMap -> !ModuleNameProvidersMap -> UniqMap ModuleName [InstantiatedModule] -> !Bool -> UnitState
+ GHC.Unit.State: UnitState :: UnitInfoMap -> PreloadUnitClosure -> UniqFM PackageName UnitId -> UniqMap UnitId UnitId -> UniqMap UnitId UnitId -> [UnitId] -> [(Unit, Maybe PackageArg)] -> [UnitId] -> ModuleNameProvidersMap -> ModuleNameProvidersMap -> UniqMap ModuleName [InstantiatedModule] -> Bool -> UnitState
- GHC.Unit.State: UnusableUnit :: !Unit -> !UnusableUnitReason -> !Bool -> UnusableUnit
+ GHC.Unit.State: UnusableUnit :: Unit -> UnusableUnitReason -> Bool -> UnusableUnit
- GHC.Unit.State: [allowVirtualUnits] :: UnitState -> !Bool
+ GHC.Unit.State: [allowVirtualUnits] :: UnitState -> Bool
- GHC.Unit.State: [moduleNameProvidersMap] :: UnitState -> !ModuleNameProvidersMap
+ GHC.Unit.State: [moduleNameProvidersMap] :: UnitState -> ModuleNameProvidersMap
- GHC.Unit.State: [pluginModuleNameProvidersMap] :: UnitState -> !ModuleNameProvidersMap
+ GHC.Unit.State: [pluginModuleNameProvidersMap] :: UnitState -> ModuleNameProvidersMap
- GHC.Unit.State: [uuIsReexport] :: UnusableUnit -> !Bool
+ GHC.Unit.State: [uuIsReexport] :: UnusableUnit -> Bool
- GHC.Unit.State: [uuReason] :: UnusableUnit -> !UnusableUnitReason
+ GHC.Unit.State: [uuReason] :: UnusableUnit -> UnusableUnitReason
- GHC.Unit.State: [uuUnit] :: UnusableUnit -> !Unit
+ GHC.Unit.State: [uuUnit] :: UnusableUnit -> Unit
- GHC.Unit.Types: InstantiatedUnit :: !FastString -> !Unique -> !unit -> !GenInstantiations unit -> UniqDSet ModuleName -> GenInstantiatedUnit unit
+ GHC.Unit.Types: InstantiatedUnit :: FastString -> Unique -> unit -> GenInstantiations unit -> UniqDSet ModuleName -> GenInstantiatedUnit unit
- GHC.Unit.Types: Module :: !unit -> !ModuleName -> GenModule unit
+ GHC.Unit.Types: Module :: unit -> ModuleName -> GenModule unit
- GHC.Unit.Types: RealUnit :: !Definite uid -> GenUnit uid
+ GHC.Unit.Types: RealUnit :: Definite uid -> GenUnit uid
- GHC.Unit.Types: VirtUnit :: {-# UNPACK #-} !GenInstantiatedUnit uid -> GenUnit uid
+ GHC.Unit.Types: VirtUnit :: GenInstantiatedUnit uid -> GenUnit uid
- GHC.Unit.Types: [instUnitFS] :: GenInstantiatedUnit unit -> !FastString
+ GHC.Unit.Types: [instUnitFS] :: GenInstantiatedUnit unit -> FastString
- GHC.Unit.Types: [instUnitInstanceOf] :: GenInstantiatedUnit unit -> !unit
+ GHC.Unit.Types: [instUnitInstanceOf] :: GenInstantiatedUnit unit -> unit
- GHC.Unit.Types: [instUnitInsts] :: GenInstantiatedUnit unit -> !GenInstantiations unit
+ GHC.Unit.Types: [instUnitInsts] :: GenInstantiatedUnit unit -> GenInstantiations unit
- GHC.Unit.Types: [instUnitKey] :: GenInstantiatedUnit unit -> !Unique
+ GHC.Unit.Types: [instUnitKey] :: GenInstantiatedUnit unit -> Unique
- GHC.Unit.Types: [moduleName] :: GenModule unit -> !ModuleName
+ GHC.Unit.Types: [moduleName] :: GenModule unit -> ModuleName
- GHC.Unit.Types: [moduleUnit] :: GenModule unit -> !unit
+ GHC.Unit.Types: [moduleUnit] :: GenModule unit -> unit
- GHC.Utils.Binary: FSTable :: !FastMutInt -> !IORef (UniqFM FastString (Int, FastString)) -> FSTable
+ GHC.Utils.Binary: FSTable :: FastMutInt -> IORef (UniqFM FastString (Int, FastString)) -> FSTable
- GHC.Utils.Binary: FullBinData :: ReaderUserData -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !BinArray -> FullBinData
+ GHC.Utils.Binary: FullBinData :: ReaderUserData -> Int -> Int -> Int -> BinArray -> FullBinData
- GHC.Utils.Binary: GenericSymbolTable :: !FastMutInt -> !IORef (m Int) -> !IORef [Key m] -> GenericSymbolTable (m :: Type -> Type)
+ GHC.Utils.Binary: GenericSymbolTable :: FastMutInt -> IORef (m Int) -> IORef [Key m] -> GenericSymbolTable (m :: Type -> Type)
- GHC.Utils.Binary: RelBin :: {-# UNPACK #-} !Bin a -> {-# UNPACK #-} !RelBinPtr a -> RelBin (a :: k)
+ GHC.Utils.Binary: RelBin :: Bin a -> RelBinPtr a -> RelBin (a :: k)
- GHC.Utils.Binary: [fbd_buffer] :: FullBinData -> {-# UNPACK #-} !BinArray
+ GHC.Utils.Binary: [fbd_buffer] :: FullBinData -> BinArray
- GHC.Utils.Binary: [fbd_off_e] :: FullBinData -> {-# UNPACK #-} !Int
+ GHC.Utils.Binary: [fbd_off_e] :: FullBinData -> Int
- GHC.Utils.Binary: [fbd_off_s] :: FullBinData -> {-# UNPACK #-} !Int
+ GHC.Utils.Binary: [fbd_off_s] :: FullBinData -> Int
- GHC.Utils.Binary: [fbd_size] :: FullBinData -> {-# UNPACK #-} !Int
+ GHC.Utils.Binary: [fbd_size] :: FullBinData -> Int
- GHC.Utils.Binary: [fs_tab_map] :: FSTable -> !IORef (UniqFM FastString (Int, FastString))
+ GHC.Utils.Binary: [fs_tab_map] :: FSTable -> IORef (UniqFM FastString (Int, FastString))
- GHC.Utils.Binary: [fs_tab_next] :: FSTable -> !FastMutInt
+ GHC.Utils.Binary: [fs_tab_next] :: FSTable -> FastMutInt
- GHC.Utils.Binary: [gen_symtab_map] :: GenericSymbolTable (m :: Type -> Type) -> !IORef (m Int)
+ GHC.Utils.Binary: [gen_symtab_map] :: GenericSymbolTable (m :: Type -> Type) -> IORef (m Int)
- GHC.Utils.Binary: [gen_symtab_next] :: GenericSymbolTable (m :: Type -> Type) -> !FastMutInt
+ GHC.Utils.Binary: [gen_symtab_next] :: GenericSymbolTable (m :: Type -> Type) -> FastMutInt
- GHC.Utils.Binary: [gen_symtab_to_write] :: GenericSymbolTable (m :: Type -> Type) -> !IORef [Key m]
+ GHC.Utils.Binary: [gen_symtab_to_write] :: GenericSymbolTable (m :: Type -> Type) -> IORef [Key m]
- GHC.Utils.Binary: [relBin_anchor] :: RelBin (a :: k) -> {-# UNPACK #-} !Bin a
+ GHC.Utils.Binary: [relBin_anchor] :: RelBin (a :: k) -> Bin a
- GHC.Utils.Binary: [relBin_offset] :: RelBin (a :: k) -> {-# UNPACK #-} !RelBinPtr a
+ GHC.Utils.Binary: [relBin_offset] :: RelBin (a :: k) -> RelBinPtr a
- GHC.Utils.BufHandle: BufHandle :: {-# UNPACK #-} !Ptr Word8 -> {-# UNPACK #-} !FastMutInt -> Handle -> BufHandle
+ GHC.Utils.BufHandle: BufHandle :: Ptr Word8 -> FastMutInt -> Handle -> BufHandle
- GHC.Utils.Containers.Internal.StrictPair: (:*:) :: !a -> !b -> StrictPair a b
+ GHC.Utils.Containers.Internal.StrictPair: (:*:) :: a -> b -> StrictPair a b
- GHC.Utils.Error: -- | Type of configuration options for the diagnostic.
+ GHC.Utils.Error: -- | Type of hint this diagnostic can provide. By default, this is
- GHC.Utils.Error: DiagOpts :: !EnumSet WarningFlag -> !EnumSet WarningFlag -> !WarningCategorySet -> !WarningCategorySet -> !Bool -> !Bool -> !Maybe Int -> !SDocContext -> DiagOpts
+ GHC.Utils.Error: DiagOpts :: EnumSet WarningFlag -> EnumSet WarningFlag -> WarningCategorySet -> WarningCategorySet -> Bool -> Bool -> Maybe Int -> SDocContext -> DiagOpts
- GHC.Utils.Error: [diag_custom_warning_categories] :: DiagOpts -> !WarningCategorySet
+ GHC.Utils.Error: [diag_custom_warning_categories] :: DiagOpts -> WarningCategorySet
- GHC.Utils.Error: [diag_fatal_custom_warning_categories] :: DiagOpts -> !WarningCategorySet
+ GHC.Utils.Error: [diag_fatal_custom_warning_categories] :: DiagOpts -> WarningCategorySet
- GHC.Utils.Error: [diag_fatal_warning_flags] :: DiagOpts -> !EnumSet WarningFlag
+ GHC.Utils.Error: [diag_fatal_warning_flags] :: DiagOpts -> EnumSet WarningFlag
- GHC.Utils.Error: [diag_max_errors] :: DiagOpts -> !Maybe Int
+ GHC.Utils.Error: [diag_max_errors] :: DiagOpts -> Maybe Int
- GHC.Utils.Error: [diag_ppr_ctx] :: DiagOpts -> !SDocContext
+ GHC.Utils.Error: [diag_ppr_ctx] :: DiagOpts -> SDocContext
- GHC.Utils.Error: [diag_reverse_errors] :: DiagOpts -> !Bool
+ GHC.Utils.Error: [diag_reverse_errors] :: DiagOpts -> Bool
- GHC.Utils.Error: [diag_warn_is_error] :: DiagOpts -> !Bool
+ GHC.Utils.Error: [diag_warn_is_error] :: DiagOpts -> Bool
- GHC.Utils.Error: [diag_warning_flags] :: DiagOpts -> !EnumSet WarningFlag
+ GHC.Utils.Error: [diag_warning_flags] :: DiagOpts -> EnumSet WarningFlag
- GHC.Utils.Error: class HasDefaultDiagnosticOpts DiagnosticOpts a => Diagnostic a where {
+ GHC.Utils.Error: class (Outputable DiagnosticHint a, HasDefaultDiagnosticOpts DiagnosticOpts a) => Diagnostic a where {
- GHC.Utils.Error: diagnosticHints :: Diagnostic a => a -> [GhcHint]
+ GHC.Utils.Error: diagnosticHints :: Diagnostic a => a -> [DiagnosticHint a]
- GHC.Utils.Fingerprint: Fingerprint :: {-# UNPACK #-} !Word64 -> {-# UNPACK #-} !Word64 -> Fingerprint
+ GHC.Utils.Fingerprint: Fingerprint :: Word64 -> Word64 -> Fingerprint
- GHC.Utils.Logger: LogFlags :: SDocContext -> SDocContext -> !EnumSet DumpFlag -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Maybe FilePath -> !FilePath -> !Maybe FilePath -> !Bool -> !Bool -> !Int -> !Maybe Ways -> LogFlags
+ GHC.Utils.Logger: LogFlags :: SDocContext -> SDocContext -> EnumSet DumpFlag -> Bool -> Bool -> Bool -> Bool -> Bool -> Maybe FilePath -> FilePath -> Maybe FilePath -> Bool -> Bool -> Int -> Maybe Ways -> LogFlags
- GHC.Utils.Logger: [log_diagnostics_as_json] :: LogFlags -> !Bool
+ GHC.Utils.Logger: [log_diagnostics_as_json] :: LogFlags -> Bool
- GHC.Utils.Logger: [log_dump_dir] :: LogFlags -> !Maybe FilePath
+ GHC.Utils.Logger: [log_dump_dir] :: LogFlags -> Maybe FilePath
- GHC.Utils.Logger: [log_dump_flags] :: LogFlags -> !EnumSet DumpFlag
+ GHC.Utils.Logger: [log_dump_flags] :: LogFlags -> EnumSet DumpFlag
- GHC.Utils.Logger: [log_dump_prefix] :: LogFlags -> !FilePath
+ GHC.Utils.Logger: [log_dump_prefix] :: LogFlags -> FilePath
- GHC.Utils.Logger: [log_dump_prefix_override] :: LogFlags -> !Maybe FilePath
+ GHC.Utils.Logger: [log_dump_prefix_override] :: LogFlags -> Maybe FilePath
- GHC.Utils.Logger: [log_dump_to_file] :: LogFlags -> !Bool
+ GHC.Utils.Logger: [log_dump_to_file] :: LogFlags -> Bool
- GHC.Utils.Logger: [log_enable_debug] :: LogFlags -> !Bool
+ GHC.Utils.Logger: [log_enable_debug] :: LogFlags -> Bool
- GHC.Utils.Logger: [log_enable_timestamps] :: LogFlags -> !Bool
+ GHC.Utils.Logger: [log_enable_timestamps] :: LogFlags -> Bool
- GHC.Utils.Logger: [log_show_caret] :: LogFlags -> !Bool
+ GHC.Utils.Logger: [log_show_caret] :: LogFlags -> Bool
- GHC.Utils.Logger: [log_show_warn_groups] :: LogFlags -> !Bool
+ GHC.Utils.Logger: [log_show_warn_groups] :: LogFlags -> Bool
- GHC.Utils.Logger: [log_verbosity] :: LogFlags -> !Int
+ GHC.Utils.Logger: [log_verbosity] :: LogFlags -> Int
- GHC.Utils.Logger: [log_ways] :: LogFlags -> !Maybe Ways
+ GHC.Utils.Logger: [log_ways] :: LogFlags -> Maybe Ways
- GHC.Utils.Logger: [log_with_ways] :: LogFlags -> !Bool
+ GHC.Utils.Logger: [log_with_ways] :: LogFlags -> Bool
- GHC.Utils.Misc: expectNonEmpty :: HasDebugCallStack => String -> [a] -> NonEmpty a
+ GHC.Utils.Misc: expectNonEmpty :: HasCallStack => [a] -> NonEmpty a
- GHC.Utils.Misc: expectOnly :: HasDebugCallStack => String -> [a] -> a
+ GHC.Utils.Misc: expectOnly :: HasCallStack => [a] -> a
- GHC.Utils.Misc: zipEqual :: HasDebugCallStack => String -> [a] -> [b] -> [(a, b)]
+ GHC.Utils.Misc: zipEqual :: HasDebugCallStack => [a] -> [b] -> [(a, b)]
- GHC.Utils.Misc: zipWith3Equal :: HasDebugCallStack => String -> (a -> b -> c -> d) -> [a] -> [b] -> [c] -> [d]
+ GHC.Utils.Misc: zipWith3Equal :: HasDebugCallStack => (a -> b -> c -> d) -> [a] -> [b] -> [c] -> [d]
- GHC.Utils.Misc: zipWith4Equal :: HasDebugCallStack => String -> (a -> b -> c -> d -> e) -> [a] -> [b] -> [c] -> [d] -> [e]
+ GHC.Utils.Misc: zipWith4Equal :: HasDebugCallStack => (a -> b -> c -> d -> e) -> [a] -> [b] -> [c] -> [d] -> [e]
- GHC.Utils.Misc: zipWithEqual :: HasDebugCallStack => String -> (a -> b -> c) -> [a] -> [b] -> [c]
+ GHC.Utils.Misc: zipWithEqual :: HasDebugCallStack => (a -> b -> c) -> [a] -> [b] -> [c]
- GHC.Utils.Outputable: JoinPoint :: {-# UNPACK #-} !Int -> JoinPointHood
+ GHC.Utils.Outputable: JoinPoint :: Int -> JoinPointHood
- GHC.Utils.Outputable: PromTickCtx :: !Bool -> !Bool -> PromotionTickContext
+ GHC.Utils.Outputable: PromTickCtx :: Bool -> Bool -> PromotionTickContext
- GHC.Utils.Outputable: SDC :: !PprStyle -> !Scheme -> !PprColour -> !Bool -> !Int -> !Int -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !FastString -> SDoc -> SDocContext
+ GHC.Utils.Outputable: SDC :: PprStyle -> Scheme -> PprColour -> Bool -> Int -> Int -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> (FastString -> SDoc) -> SDocContext
- GHC.Utils.Outputable: [ptcListTuplePuns] :: PromotionTickContext -> !Bool
+ GHC.Utils.Outputable: [ptcListTuplePuns] :: PromotionTickContext -> Bool
- GHC.Utils.Outputable: [ptcPrintRedundantPromTicks] :: PromotionTickContext -> !Bool
+ GHC.Utils.Outputable: [ptcPrintRedundantPromTicks] :: PromotionTickContext -> Bool
- GHC.Utils.Outputable: [sdocCanUseUnicode] :: SDocContext -> !Bool
+ GHC.Utils.Outputable: [sdocCanUseUnicode] :: SDocContext -> Bool
- GHC.Utils.Outputable: [sdocColScheme] :: SDocContext -> !Scheme
+ GHC.Utils.Outputable: [sdocColScheme] :: SDocContext -> Scheme
- GHC.Utils.Outputable: [sdocDefaultDepth] :: SDocContext -> !Int
+ GHC.Utils.Outputable: [sdocDefaultDepth] :: SDocContext -> Int
- GHC.Utils.Outputable: [sdocErrorSpans] :: SDocContext -> !Bool
+ GHC.Utils.Outputable: [sdocErrorSpans] :: SDocContext -> Bool
- GHC.Utils.Outputable: [sdocHexWordLiterals] :: SDocContext -> !Bool
+ GHC.Utils.Outputable: [sdocHexWordLiterals] :: SDocContext -> Bool
- GHC.Utils.Outputable: [sdocLastColour] :: SDocContext -> !PprColour
+ GHC.Utils.Outputable: [sdocLastColour] :: SDocContext -> PprColour
- GHC.Utils.Outputable: [sdocLineLength] :: SDocContext -> !Int
+ GHC.Utils.Outputable: [sdocLineLength] :: SDocContext -> Int
- GHC.Utils.Outputable: [sdocLinearTypes] :: SDocContext -> !Bool
+ GHC.Utils.Outputable: [sdocLinearTypes] :: SDocContext -> Bool
- GHC.Utils.Outputable: [sdocListTuplePuns] :: SDocContext -> !Bool
+ GHC.Utils.Outputable: [sdocListTuplePuns] :: SDocContext -> Bool
- GHC.Utils.Outputable: [sdocPprDebug] :: SDocContext -> !Bool
+ GHC.Utils.Outputable: [sdocPprDebug] :: SDocContext -> Bool
- GHC.Utils.Outputable: [sdocPrintAxiomIncomps] :: SDocContext -> !Bool
+ GHC.Utils.Outputable: [sdocPrintAxiomIncomps] :: SDocContext -> Bool
- GHC.Utils.Outputable: [sdocPrintCaseAsLet] :: SDocContext -> !Bool
+ GHC.Utils.Outputable: [sdocPrintCaseAsLet] :: SDocContext -> Bool
- GHC.Utils.Outputable: [sdocPrintEqualityRelations] :: SDocContext -> !Bool
+ GHC.Utils.Outputable: [sdocPrintEqualityRelations] :: SDocContext -> Bool
- GHC.Utils.Outputable: [sdocPrintErrIndexLinks] :: SDocContext -> !Bool
+ GHC.Utils.Outputable: [sdocPrintErrIndexLinks] :: SDocContext -> Bool
- GHC.Utils.Outputable: [sdocPrintExplicitCoercions] :: SDocContext -> !Bool
+ GHC.Utils.Outputable: [sdocPrintExplicitCoercions] :: SDocContext -> Bool
- GHC.Utils.Outputable: [sdocPrintExplicitForalls] :: SDocContext -> !Bool
+ GHC.Utils.Outputable: [sdocPrintExplicitForalls] :: SDocContext -> Bool
- GHC.Utils.Outputable: [sdocPrintExplicitKinds] :: SDocContext -> !Bool
+ GHC.Utils.Outputable: [sdocPrintExplicitKinds] :: SDocContext -> Bool
- GHC.Utils.Outputable: [sdocPrintExplicitRuntimeReps] :: SDocContext -> !Bool
+ GHC.Utils.Outputable: [sdocPrintExplicitRuntimeReps] :: SDocContext -> Bool
- GHC.Utils.Outputable: [sdocPrintPotentialInstances] :: SDocContext -> !Bool
+ GHC.Utils.Outputable: [sdocPrintPotentialInstances] :: SDocContext -> Bool
- GHC.Utils.Outputable: [sdocPrintTypeAbbreviations] :: SDocContext -> !Bool
+ GHC.Utils.Outputable: [sdocPrintTypeAbbreviations] :: SDocContext -> Bool
- GHC.Utils.Outputable: [sdocPrintTypecheckerElaboration] :: SDocContext -> !Bool
+ GHC.Utils.Outputable: [sdocPrintTypecheckerElaboration] :: SDocContext -> Bool
- GHC.Utils.Outputable: [sdocPrintUnicodeSyntax] :: SDocContext -> !Bool
+ GHC.Utils.Outputable: [sdocPrintUnicodeSyntax] :: SDocContext -> Bool
- GHC.Utils.Outputable: [sdocShouldUseColor] :: SDocContext -> !Bool
+ GHC.Utils.Outputable: [sdocShouldUseColor] :: SDocContext -> Bool
- GHC.Utils.Outputable: [sdocStarIsType] :: SDocContext -> !Bool
+ GHC.Utils.Outputable: [sdocStarIsType] :: SDocContext -> Bool
- GHC.Utils.Outputable: [sdocStyle] :: SDocContext -> !PprStyle
+ GHC.Utils.Outputable: [sdocStyle] :: SDocContext -> PprStyle
- GHC.Utils.Outputable: [sdocSuppressCoercionTypes] :: SDocContext -> !Bool
+ GHC.Utils.Outputable: [sdocSuppressCoercionTypes] :: SDocContext -> Bool
- GHC.Utils.Outputable: [sdocSuppressCoercions] :: SDocContext -> !Bool
+ GHC.Utils.Outputable: [sdocSuppressCoercions] :: SDocContext -> Bool
- GHC.Utils.Outputable: [sdocSuppressIdInfo] :: SDocContext -> !Bool
+ GHC.Utils.Outputable: [sdocSuppressIdInfo] :: SDocContext -> Bool
- GHC.Utils.Outputable: [sdocSuppressModulePrefixes] :: SDocContext -> !Bool
+ GHC.Utils.Outputable: [sdocSuppressModulePrefixes] :: SDocContext -> Bool
- GHC.Utils.Outputable: [sdocSuppressStgExts] :: SDocContext -> !Bool
+ GHC.Utils.Outputable: [sdocSuppressStgExts] :: SDocContext -> Bool
- GHC.Utils.Outputable: [sdocSuppressStgReps] :: SDocContext -> !Bool
+ GHC.Utils.Outputable: [sdocSuppressStgReps] :: SDocContext -> Bool
- GHC.Utils.Outputable: [sdocSuppressTicks] :: SDocContext -> !Bool
+ GHC.Utils.Outputable: [sdocSuppressTicks] :: SDocContext -> Bool
- GHC.Utils.Outputable: [sdocSuppressTypeApplications] :: SDocContext -> !Bool
+ GHC.Utils.Outputable: [sdocSuppressTypeApplications] :: SDocContext -> Bool
- GHC.Utils.Outputable: [sdocSuppressTypeSignatures] :: SDocContext -> !Bool
+ GHC.Utils.Outputable: [sdocSuppressTypeSignatures] :: SDocContext -> Bool
- GHC.Utils.Outputable: [sdocSuppressUnfoldings] :: SDocContext -> !Bool
+ GHC.Utils.Outputable: [sdocSuppressUnfoldings] :: SDocContext -> Bool
- GHC.Utils.Outputable: [sdocSuppressUniques] :: SDocContext -> !Bool
+ GHC.Utils.Outputable: [sdocSuppressUniques] :: SDocContext -> Bool
- GHC.Utils.Outputable: [sdocSuppressVarKinds] :: SDocContext -> !Bool
+ GHC.Utils.Outputable: [sdocSuppressVarKinds] :: SDocContext -> Bool
- GHC.Utils.Outputable: [sdocUnitIdForUser] :: SDocContext -> !FastString -> SDoc
+ GHC.Utils.Outputable: [sdocUnitIdForUser] :: SDocContext -> FastString -> SDoc
- GHC.Utils.Outputable: type QueryQualifyName = Module -> OccName -> QualifyName
+ GHC.Utils.Outputable: type QueryQualifyName = Module -> Maybe ModuleName -> OccName -> QualifyName
- GHC.Utils.Panic: panicDoc :: String -> SDoc -> a
+ GHC.Utils.Panic: panicDoc :: HasCallStack => String -> SDoc -> a
- GHC.Utils.Panic: throwGhcException :: GhcException -> a
+ GHC.Utils.Panic: throwGhcException :: HasCallStack => GhcException -> a
- GHC.Utils.Ppr: Chr :: {-# UNPACK #-} !Char -> TextDetails
+ GHC.Utils.Ppr: Chr :: Char -> TextDetails
- GHC.Utils.Ppr: LStr :: {-# UNPACK #-} !PtrString -> TextDetails
+ GHC.Utils.Ppr: LStr :: PtrString -> TextDetails
- GHC.Utils.Ppr: RStr :: {-# UNPACK #-} !Int -> {-# UNPACK #-} !Char -> TextDetails
+ GHC.Utils.Ppr: RStr :: Int -> Char -> TextDetails
- GHC.Utils.TmpFs: PathsToClean :: !Set FilePath -> !Set FilePath -> PathsToClean
+ GHC.Utils.TmpFs: PathsToClean :: Set FilePath -> Set FilePath -> PathsToClean
- GHC.Utils.TmpFs: [ptcCurrentModule] :: PathsToClean -> !Set FilePath
+ GHC.Utils.TmpFs: [ptcCurrentModule] :: PathsToClean -> Set FilePath
- GHC.Utils.TmpFs: [ptcGhcSession] :: PathsToClean -> !Set FilePath
+ GHC.Utils.TmpFs: [ptcGhcSession] :: PathsToClean -> Set FilePath
- Language.Haskell.Syntax: XModule :: !XXModule p -> HsModule p
+ Language.Haskell.Syntax: XModule :: XXModule p -> HsModule p
- Language.Haskell.Syntax.Binds: MinimalSig :: XMinimalSig pass -> LBooleanFormula (LIdP pass) -> Sig pass
+ Language.Haskell.Syntax.Binds: MinimalSig :: XMinimalSig pass -> LBooleanFormula pass -> Sig pass
- Language.Haskell.Syntax.Binds: XFixitySig :: !XXFixitySig pass -> FixitySig pass
+ Language.Haskell.Syntax.Binds: XFixitySig :: XXFixitySig pass -> FixitySig pass
- Language.Haskell.Syntax.Binds: XHsBindsLR :: !XXHsBindsLR idL idR -> HsBindLR idL idR
+ Language.Haskell.Syntax.Binds: XHsBindsLR :: XXHsBindsLR idL idR -> HsBindLR idL idR
- Language.Haskell.Syntax.Binds: XHsIPBinds :: !XXHsIPBinds id -> HsIPBinds id
+ Language.Haskell.Syntax.Binds: XHsIPBinds :: XXHsIPBinds id -> HsIPBinds id
- Language.Haskell.Syntax.Binds: XHsLocalBindsLR :: !XXHsLocalBindsLR idL idR -> HsLocalBindsLR idL idR
+ Language.Haskell.Syntax.Binds: XHsLocalBindsLR :: XXHsLocalBindsLR idL idR -> HsLocalBindsLR idL idR
- Language.Haskell.Syntax.Binds: XIPBind :: !XXIPBind id -> IPBind id
+ Language.Haskell.Syntax.Binds: XIPBind :: XXIPBind id -> IPBind id
- Language.Haskell.Syntax.Binds: XPatSynBind :: !XXPatSynBind idL idR -> PatSynBind idL idR
+ Language.Haskell.Syntax.Binds: XPatSynBind :: XXPatSynBind idL idR -> PatSynBind idL idR
- Language.Haskell.Syntax.Binds: XSig :: !XXSig pass -> Sig pass
+ Language.Haskell.Syntax.Binds: XSig :: XXSig pass -> Sig pass
- Language.Haskell.Syntax.Binds: XValBindsLR :: !XXValBindsLR idL idR -> HsValBindsLR idL idR
+ Language.Haskell.Syntax.Binds: XValBindsLR :: XXValBindsLR idL idR -> HsValBindsLR idL idR
- Language.Haskell.Syntax.Binds: type HsPatSynDetails pass = HsConDetails Void LIdP pass [RecordPatSynField pass]
+ Language.Haskell.Syntax.Binds: type HsPatSynDetails pass = HsConDetails LIdP pass [RecordPatSynField pass]
- Language.Haskell.Syntax.Decls: ConDeclGADT :: XConDeclGADT pass -> NonEmpty (LIdP pass) -> XRec pass (HsOuterSigTyVarBndrs pass) -> Maybe (LHsContext pass) -> HsConDeclGADTDetails pass -> LHsType pass -> Maybe (LHsDoc pass) -> ConDecl pass
+ Language.Haskell.Syntax.Decls: ConDeclGADT :: XConDeclGADT pass -> NonEmpty (LIdP pass) -> XRec pass (HsOuterSigTyVarBndrs pass) -> [HsForAllTelescope pass] -> Maybe (LHsContext pass) -> HsConDeclGADTDetails pass -> LHsType pass -> Maybe (LHsDoc pass) -> ConDecl pass
- Language.Haskell.Syntax.Decls: HsRule :: XHsRule pass -> XRec pass RuleName -> Activation -> Maybe [LHsTyVarBndr () (NoGhcTc pass)] -> [LRuleBndr pass] -> XRec pass (HsExpr pass) -> XRec pass (HsExpr pass) -> RuleDecl pass
+ Language.Haskell.Syntax.Decls: HsRule :: XHsRule pass -> XRec pass RuleName -> Activation -> RuleBndrs pass -> XRec pass (HsExpr pass) -> XRec pass (HsExpr pass) -> RuleDecl pass
- Language.Haskell.Syntax.Decls: PrefixConGADT :: !XPrefixConGADT pass -> [HsScaled pass (LBangType pass)] -> HsConDeclGADTDetails pass
+ Language.Haskell.Syntax.Decls: PrefixConGADT :: XPrefixConGADT pass -> [HsConDeclField pass] -> HsConDeclGADTDetails pass
- Language.Haskell.Syntax.Decls: RecConGADT :: !XRecConGADT pass -> XRec pass [LConDeclField pass] -> HsConDeclGADTDetails pass
+ Language.Haskell.Syntax.Decls: RecConGADT :: XRecConGADT pass -> XRec pass [LHsConDeclRecField pass] -> HsConDeclGADTDetails pass
- Language.Haskell.Syntax.Decls: XAnnDecl :: !XXAnnDecl pass -> AnnDecl pass
+ Language.Haskell.Syntax.Decls: XAnnDecl :: XXAnnDecl pass -> AnnDecl pass
- Language.Haskell.Syntax.Decls: XClsInstDecl :: !XXClsInstDecl pass -> ClsInstDecl pass
+ Language.Haskell.Syntax.Decls: XClsInstDecl :: XXClsInstDecl pass -> ClsInstDecl pass
- Language.Haskell.Syntax.Decls: XConDecl :: !XXConDecl pass -> ConDecl pass
+ Language.Haskell.Syntax.Decls: XConDecl :: XXConDecl pass -> ConDecl pass
- Language.Haskell.Syntax.Decls: XConDeclGADTDetails :: !XXConDeclGADTDetails pass -> HsConDeclGADTDetails pass
+ Language.Haskell.Syntax.Decls: XConDeclGADTDetails :: XXConDeclGADTDetails pass -> HsConDeclGADTDetails pass
- Language.Haskell.Syntax.Decls: XDefaultDecl :: !XXDefaultDecl pass -> DefaultDecl pass
+ Language.Haskell.Syntax.Decls: XDefaultDecl :: XXDefaultDecl pass -> DefaultDecl pass
- Language.Haskell.Syntax.Decls: XDerivClauseTys :: !XXDerivClauseTys pass -> DerivClauseTys pass
+ Language.Haskell.Syntax.Decls: XDerivClauseTys :: XXDerivClauseTys pass -> DerivClauseTys pass
- Language.Haskell.Syntax.Decls: XDerivDecl :: !XXDerivDecl pass -> DerivDecl pass
+ Language.Haskell.Syntax.Decls: XDerivDecl :: XXDerivDecl pass -> DerivDecl pass
- Language.Haskell.Syntax.Decls: XFamEqn :: !XXFamEqn pass rhs -> FamEqn pass rhs
+ Language.Haskell.Syntax.Decls: XFamEqn :: XXFamEqn pass rhs -> FamEqn pass rhs
- Language.Haskell.Syntax.Decls: XFamilyDecl :: !XXFamilyDecl pass -> FamilyDecl pass
+ Language.Haskell.Syntax.Decls: XFamilyDecl :: XXFamilyDecl pass -> FamilyDecl pass
- Language.Haskell.Syntax.Decls: XFamilyResultSig :: !XXFamilyResultSig pass -> FamilyResultSig pass
+ Language.Haskell.Syntax.Decls: XFamilyResultSig :: XXFamilyResultSig pass -> FamilyResultSig pass
- Language.Haskell.Syntax.Decls: XForeignDecl :: !XXForeignDecl pass -> ForeignDecl pass
+ Language.Haskell.Syntax.Decls: XForeignDecl :: XXForeignDecl pass -> ForeignDecl pass
- Language.Haskell.Syntax.Decls: XForeignExport :: !XXForeignExport pass -> ForeignExport pass
+ Language.Haskell.Syntax.Decls: XForeignExport :: XXForeignExport pass -> ForeignExport pass
- Language.Haskell.Syntax.Decls: XForeignImport :: !XXForeignImport pass -> ForeignImport pass
+ Language.Haskell.Syntax.Decls: XForeignImport :: XXForeignImport pass -> ForeignImport pass
- Language.Haskell.Syntax.Decls: XFunDep :: !XXFunDep pass -> FunDep pass
+ Language.Haskell.Syntax.Decls: XFunDep :: XXFunDep pass -> FunDep pass
- Language.Haskell.Syntax.Decls: XHsDataDefn :: !XXHsDataDefn pass -> HsDataDefn pass
+ Language.Haskell.Syntax.Decls: XHsDataDefn :: XXHsDataDefn pass -> HsDataDefn pass
- Language.Haskell.Syntax.Decls: XHsDecl :: !XXHsDecl p -> HsDecl p
+ Language.Haskell.Syntax.Decls: XHsDecl :: XXHsDecl p -> HsDecl p
- Language.Haskell.Syntax.Decls: XHsDerivingClause :: !XXHsDerivingClause pass -> HsDerivingClause pass
+ Language.Haskell.Syntax.Decls: XHsDerivingClause :: XXHsDerivingClause pass -> HsDerivingClause pass
- Language.Haskell.Syntax.Decls: XHsGroup :: !XXHsGroup p -> HsGroup p
+ Language.Haskell.Syntax.Decls: XHsGroup :: XXHsGroup p -> HsGroup p
- Language.Haskell.Syntax.Decls: XInjectivityAnn :: !XXInjectivityAnn pass -> InjectivityAnn pass
+ Language.Haskell.Syntax.Decls: XInjectivityAnn :: XXInjectivityAnn pass -> InjectivityAnn pass
- Language.Haskell.Syntax.Decls: XInstDecl :: !XXInstDecl pass -> InstDecl pass
+ Language.Haskell.Syntax.Decls: XInstDecl :: XXInstDecl pass -> InstDecl pass
- Language.Haskell.Syntax.Decls: XRoleAnnotDecl :: !XXRoleAnnotDecl pass -> RoleAnnotDecl pass
+ Language.Haskell.Syntax.Decls: XRoleAnnotDecl :: XXRoleAnnotDecl pass -> RoleAnnotDecl pass
- Language.Haskell.Syntax.Decls: XRuleBndr :: !XXRuleBndr pass -> RuleBndr pass
+ Language.Haskell.Syntax.Decls: XRuleBndr :: XXRuleBndr pass -> RuleBndr pass
- Language.Haskell.Syntax.Decls: XRuleDecl :: !XXRuleDecl pass -> RuleDecl pass
+ Language.Haskell.Syntax.Decls: XRuleDecl :: XXRuleDecl pass -> RuleDecl pass
- Language.Haskell.Syntax.Decls: XRuleDecls :: !XXRuleDecls pass -> RuleDecls pass
+ Language.Haskell.Syntax.Decls: XRuleDecls :: XXRuleDecls pass -> RuleDecls pass
- Language.Haskell.Syntax.Decls: XSpliceDecl :: !XXSpliceDecl p -> SpliceDecl p
+ Language.Haskell.Syntax.Decls: XSpliceDecl :: XXSpliceDecl p -> SpliceDecl p
- Language.Haskell.Syntax.Decls: XStandaloneKindSig :: !XXStandaloneKindSig pass -> StandaloneKindSig pass
+ Language.Haskell.Syntax.Decls: XStandaloneKindSig :: XXStandaloneKindSig pass -> StandaloneKindSig pass
- Language.Haskell.Syntax.Decls: XTyClDecl :: !XXTyClDecl pass -> TyClDecl pass
+ Language.Haskell.Syntax.Decls: XTyClDecl :: XXTyClDecl pass -> TyClDecl pass
- Language.Haskell.Syntax.Decls: XTyClGroup :: !XXTyClGroup pass -> TyClGroup pass
+ Language.Haskell.Syntax.Decls: XTyClGroup :: XXTyClGroup pass -> TyClGroup pass
- Language.Haskell.Syntax.Decls: XTyFamInstDecl :: !XXTyFamInstDecl pass -> TyFamInstDecl pass
+ Language.Haskell.Syntax.Decls: XTyFamInstDecl :: XXTyFamInstDecl pass -> TyFamInstDecl pass
- Language.Haskell.Syntax.Decls: XWarnDecl :: !XXWarnDecl pass -> WarnDecl pass
+ Language.Haskell.Syntax.Decls: XWarnDecl :: XXWarnDecl pass -> WarnDecl pass
- Language.Haskell.Syntax.Decls: XWarnDecls :: !XXWarnDecls pass -> WarnDecls pass
+ Language.Haskell.Syntax.Decls: XWarnDecls :: XXWarnDecls pass -> WarnDecls pass
- Language.Haskell.Syntax.Decls: type HsConDeclH98Details pass = HsConDetails Void HsScaled pass LBangType pass XRec pass [LConDeclField pass]
+ Language.Haskell.Syntax.Decls: type HsConDeclH98Details pass = HsConDetails HsConDeclField pass XRec pass [LHsConDeclRecField pass]
- Language.Haskell.Syntax.Expr: FieldLabelStrings :: [XRec p (DotFieldOcc p)] -> FieldLabelStrings p
+ Language.Haskell.Syntax.Expr: FieldLabelStrings :: NonEmpty (XRec p (DotFieldOcc p)) -> FieldLabelStrings p
- Language.Haskell.Syntax.Expr: GRHSs :: XCGRHSs p body -> [LGRHS p body] -> HsLocalBinds p -> GRHSs p body
+ Language.Haskell.Syntax.Expr: GRHSs :: XCGRHSs p body -> NonEmpty (LGRHS p body) -> HsLocalBinds p -> GRHSs p body
- Language.Haskell.Syntax.Expr: HsFunArr :: XFunArr p -> HsArrowOf (LHsExpr p) p -> LHsExpr p -> LHsExpr p -> HsExpr p
+ Language.Haskell.Syntax.Expr: HsFunArr :: XFunArr p -> HsMultAnnOf (LHsExpr p) p -> LHsExpr p -> LHsExpr p -> HsExpr p
- Language.Haskell.Syntax.Expr: HsMultiIf :: XMultiIf p -> [LGRHS p (LHsExpr p)] -> HsExpr p
+ Language.Haskell.Syntax.Expr: HsMultiIf :: XMultiIf p -> NonEmpty (LGRHS p (LHsExpr p)) -> HsExpr p
- Language.Haskell.Syntax.Expr: HsQuasiQuote :: XQuasiQuote id -> IdP id -> XRec id FastString -> HsUntypedSplice id
+ Language.Haskell.Syntax.Expr: HsQuasiQuote :: XQuasiQuote id -> LIdP id -> XRec id FastString -> HsUntypedSplice id
- Language.Haskell.Syntax.Expr: HsTypedSplice :: XTypedSplice p -> LHsExpr p -> HsExpr p
+ Language.Haskell.Syntax.Expr: HsTypedSplice :: XTypedSplice p -> HsTypedSplice p -> HsExpr p
- Language.Haskell.Syntax.Expr: HsVar :: XVar p -> LIdP p -> HsExpr p
+ Language.Haskell.Syntax.Expr: HsVar :: XVar p -> LIdOccP p -> HsExpr p
- Language.Haskell.Syntax.Expr: ParStmt :: XParStmt idL idR body -> [ParStmtBlock idL idR] -> HsExpr idR -> SyntaxExpr idR -> StmtLR idL idR body
+ Language.Haskell.Syntax.Expr: ParStmt :: XParStmt idL idR body -> NonEmpty (ParStmtBlock idL idR) -> HsExpr idR -> SyntaxExpr idR -> StmtLR idL idR body
- Language.Haskell.Syntax.Expr: XCmd :: !XXCmd id -> HsCmd id
+ Language.Haskell.Syntax.Expr: XCmd :: XXCmd id -> HsCmd id
- Language.Haskell.Syntax.Expr: XCmdTop :: !XXCmdTop p -> HsCmdTop p
+ Language.Haskell.Syntax.Expr: XCmdTop :: XXCmdTop p -> HsCmdTop p
- Language.Haskell.Syntax.Expr: XDotFieldOcc :: !XXDotFieldOcc p -> DotFieldOcc p
+ Language.Haskell.Syntax.Expr: XDotFieldOcc :: XXDotFieldOcc p -> DotFieldOcc p
- Language.Haskell.Syntax.Expr: XExpr :: !XXExpr p -> HsExpr p
+ Language.Haskell.Syntax.Expr: XExpr :: XXExpr p -> HsExpr p
- Language.Haskell.Syntax.Expr: XGRHS :: !XXGRHS p body -> GRHS p body
+ Language.Haskell.Syntax.Expr: XGRHS :: XXGRHS p body -> GRHS p body
- Language.Haskell.Syntax.Expr: XGRHSs :: !XXGRHSs p body -> GRHSs p body
+ Language.Haskell.Syntax.Expr: XGRHSs :: XXGRHSs p body -> GRHSs p body
- Language.Haskell.Syntax.Expr: XHsPragE :: !XXPragE p -> HsPragE p
+ Language.Haskell.Syntax.Expr: XHsPragE :: XXPragE p -> HsPragE p
- Language.Haskell.Syntax.Expr: XMatch :: !XXMatch p body -> Match p body
+ Language.Haskell.Syntax.Expr: XMatch :: XXMatch p body -> Match p body
- Language.Haskell.Syntax.Expr: XMatchGroup :: !XXMatchGroup p body -> MatchGroup p body
+ Language.Haskell.Syntax.Expr: XMatchGroup :: XXMatchGroup p body -> MatchGroup p body
- Language.Haskell.Syntax.Expr: XParStmtBlock :: !XXParStmtBlock idL idR -> ParStmtBlock idL idR
+ Language.Haskell.Syntax.Expr: XParStmtBlock :: XXParStmtBlock idL idR -> ParStmtBlock idL idR
- Language.Haskell.Syntax.Expr: XQuote :: !XXQuote p -> HsQuote p
+ Language.Haskell.Syntax.Expr: XQuote :: XXQuote p -> HsQuote p
- Language.Haskell.Syntax.Expr: XStmtLR :: !XXStmtLR idL idR body -> StmtLR idL idR body
+ Language.Haskell.Syntax.Expr: XStmtLR :: XXStmtLR idL idR body -> StmtLR idL idR body
- Language.Haskell.Syntax.Expr: XTupArg :: !XXTupArg id -> HsTupArg id
+ Language.Haskell.Syntax.Expr: XTupArg :: XXTupArg id -> HsTupArg id
- Language.Haskell.Syntax.Expr: XUntypedSplice :: !XXUntypedSplice id -> HsUntypedSplice id
+ Language.Haskell.Syntax.Expr: XUntypedSplice :: XXUntypedSplice id -> HsUntypedSplice id
- Language.Haskell.Syntax.Expr: [grhssGRHSs] :: GRHSs p body -> [LGRHS p body]
+ Language.Haskell.Syntax.Expr: [grhssGRHSs] :: GRHSs p body -> NonEmpty (LGRHS p body)
- Language.Haskell.Syntax.ImpExp: ImportDecl :: XCImportDecl pass -> XRec pass ModuleName -> ImportDeclPkgQual pass -> IsBootInterface -> Bool -> ImportDeclQualifiedStyle -> Maybe (XRec pass ModuleName) -> Maybe (ImportListInterpretation, XRec pass [LIE pass]) -> ImportDecl pass
+ Language.Haskell.Syntax.ImpExp: ImportDecl :: XCImportDecl pass -> XRec pass ModuleName -> ImportDeclPkgQual pass -> IsBootInterface -> ImportDeclLevelStyle -> Bool -> ImportDeclQualifiedStyle -> Maybe (XRec pass ModuleName) -> Maybe (ImportListInterpretation, XRec pass [LIE pass]) -> ImportDecl pass
- Language.Haskell.Syntax.ImpExp: XIE :: !XXIE pass -> IE pass
+ Language.Haskell.Syntax.ImpExp: XIE :: XXIE pass -> IE pass
- Language.Haskell.Syntax.ImpExp: XIEWrappedName :: !XXIEWrappedName p -> IEWrappedName p
+ Language.Haskell.Syntax.ImpExp: XIEWrappedName :: XXIEWrappedName p -> IEWrappedName p
- Language.Haskell.Syntax.ImpExp: XImportDecl :: !XXImportDecl pass -> ImportDecl pass
+ Language.Haskell.Syntax.ImpExp: XImportDecl :: XXImportDecl pass -> ImportDecl pass
- Language.Haskell.Syntax.Lit: HsFractional :: !FractionalLit -> OverLitVal
+ Language.Haskell.Syntax.Lit: HsFractional :: FractionalLit -> OverLitVal
- Language.Haskell.Syntax.Lit: HsIntegral :: !IntegralLit -> OverLitVal
+ Language.Haskell.Syntax.Lit: HsIntegral :: IntegralLit -> OverLitVal
- Language.Haskell.Syntax.Lit: HsIsString :: !SourceText -> !FastString -> OverLitVal
+ Language.Haskell.Syntax.Lit: HsIsString :: SourceText -> FastString -> OverLitVal
- Language.Haskell.Syntax.Lit: HsStringPrim :: XHsStringPrim x -> !ByteString -> HsLit x
+ Language.Haskell.Syntax.Lit: HsStringPrim :: XHsStringPrim x -> ByteString -> HsLit x
- Language.Haskell.Syntax.Lit: XLit :: !XXLit x -> HsLit x
+ Language.Haskell.Syntax.Lit: XLit :: XXLit x -> HsLit x
- Language.Haskell.Syntax.Lit: XOverLit :: !XXOverLit p -> HsOverLit p
+ Language.Haskell.Syntax.Lit: XOverLit :: XXOverLit p -> HsOverLit p
- Language.Haskell.Syntax.Pat: HsRecFields :: !XHsRecFields p -> [LHsRecField p arg] -> Maybe (XRec p RecFieldsDotDot) -> HsRecFields p arg
+ Language.Haskell.Syntax.Pat: HsRecFields :: XHsRecFields p -> [LHsRecField p arg] -> Maybe (XRec p RecFieldsDotDot) -> HsRecFields p arg
- Language.Haskell.Syntax.Pat: XPat :: !XXPat p -> Pat p
+ Language.Haskell.Syntax.Pat: XPat :: XXPat p -> Pat p
- Language.Haskell.Syntax.Pat: [rec_ext] :: HsRecFields p arg -> !XHsRecFields p
+ Language.Haskell.Syntax.Pat: [rec_ext] :: HsRecFields p arg -> XHsRecFields p
- Language.Haskell.Syntax.Pat: type HsConPatDetails p = HsConDetails HsConPatTyArg NoGhcTc p LPat p HsRecFields p LPat p
+ Language.Haskell.Syntax.Pat: type HsConPatDetails p = HsConDetails LPat p HsRecFields p LPat p
- Language.Haskell.Syntax.Specificity: Invisible :: !Specificity -> ForAllTyFlag
+ Language.Haskell.Syntax.Specificity: Invisible :: Specificity -> ForAllTyFlag
- Language.Haskell.Syntax.Type: HsArgPar :: !XArgPar p -> HsArg p tm ty
+ Language.Haskell.Syntax.Type: HsArgPar :: XArgPar p -> HsArg p tm ty
- Language.Haskell.Syntax.Type: HsBndrInvisible :: !XBndrInvisible pass -> HsBndrVis pass
+ Language.Haskell.Syntax.Type: HsBndrInvisible :: XBndrInvisible pass -> HsBndrVis pass
- Language.Haskell.Syntax.Type: HsBndrKind :: !XBndrKind pass -> LHsKind pass -> HsBndrKind pass
+ Language.Haskell.Syntax.Type: HsBndrKind :: XBndrKind pass -> LHsKind pass -> HsBndrKind pass
- Language.Haskell.Syntax.Type: HsBndrNoKind :: !XBndrNoKind pass -> HsBndrKind pass
+ Language.Haskell.Syntax.Type: HsBndrNoKind :: XBndrNoKind pass -> HsBndrKind pass
- Language.Haskell.Syntax.Type: HsBndrRequired :: !XBndrRequired pass -> HsBndrVis pass
+ Language.Haskell.Syntax.Type: HsBndrRequired :: XBndrRequired pass -> HsBndrVis pass
- Language.Haskell.Syntax.Type: HsBndrVar :: !XBndrVar pass -> !LIdP pass -> HsBndrVar pass
+ Language.Haskell.Syntax.Type: HsBndrVar :: XBndrVar pass -> LIdP pass -> HsBndrVar pass
- Language.Haskell.Syntax.Type: HsBndrWildCard :: !XBndrWildCard pass -> HsBndrVar pass
+ Language.Haskell.Syntax.Type: HsBndrWildCard :: XBndrWildCard pass -> HsBndrVar pass
- Language.Haskell.Syntax.Type: HsExplicitMult :: !XExplicitMult mult pass -> !mult -> HsArrowOf mult pass
+ Language.Haskell.Syntax.Type: HsExplicitMult :: XExplicitMult mult pass -> mult -> HsMultAnnOf mult pass
- Language.Haskell.Syntax.Type: HsFunTy :: XFunTy pass -> HsArrow pass -> LHsType pass -> LHsType pass -> HsType pass
+ Language.Haskell.Syntax.Type: HsFunTy :: XFunTy pass -> HsMultAnn pass -> LHsType pass -> LHsType pass -> HsType pass
- Language.Haskell.Syntax.Type: HsOpTy :: XOpTy pass -> PromotionFlag -> LHsType pass -> LIdP pass -> LHsType pass -> HsType pass
+ Language.Haskell.Syntax.Type: HsOpTy :: XOpTy pass -> PromotionFlag -> LHsType pass -> LIdOccP pass -> LHsType pass -> HsType pass
- Language.Haskell.Syntax.Type: HsTyVar :: XTyVar pass -> PromotionFlag -> LIdP pass -> HsType pass
+ Language.Haskell.Syntax.Type: HsTyVar :: XTyVar pass -> PromotionFlag -> LIdOccP pass -> HsType pass
- Language.Haskell.Syntax.Type: HsTypeArg :: !XTypeArg p -> ty -> HsArg p tm ty
+ Language.Haskell.Syntax.Type: HsTypeArg :: XTypeArg p -> ty -> HsArg p tm ty
- Language.Haskell.Syntax.Type: HsValArg :: !XValArg p -> tm -> HsArg p tm ty
+ Language.Haskell.Syntax.Type: HsValArg :: XValArg p -> tm -> HsArg p tm ty
- Language.Haskell.Syntax.Type: InfixCon :: arg -> arg -> HsConDetails tyarg arg rec
+ Language.Haskell.Syntax.Type: InfixCon :: arg -> arg -> HsConDetails arg rec
- Language.Haskell.Syntax.Type: PrefixCon :: [tyarg] -> [arg] -> HsConDetails tyarg arg rec
+ Language.Haskell.Syntax.Type: PrefixCon :: [arg] -> HsConDetails arg rec
- Language.Haskell.Syntax.Type: RecCon :: rec -> HsConDetails tyarg arg rec
+ Language.Haskell.Syntax.Type: RecCon :: rec -> HsConDetails arg rec
- Language.Haskell.Syntax.Type: XArg :: !XXArg p -> HsArg p tm ty
+ Language.Haskell.Syntax.Type: XArg :: XXArg p -> HsArg p tm ty
- Language.Haskell.Syntax.Type: XBndrKind :: !XXBndrKind pass -> HsBndrKind pass
+ Language.Haskell.Syntax.Type: XBndrKind :: XXBndrKind pass -> HsBndrKind pass
- Language.Haskell.Syntax.Type: XBndrVar :: !XXBndrVar pass -> HsBndrVar pass
+ Language.Haskell.Syntax.Type: XBndrVar :: XXBndrVar pass -> HsBndrVar pass
- Language.Haskell.Syntax.Type: XBndrVis :: !XXBndrVis pass -> HsBndrVis pass
+ Language.Haskell.Syntax.Type: XBndrVis :: XXBndrVis pass -> HsBndrVis pass
- Language.Haskell.Syntax.Type: XFieldOcc :: !XXFieldOcc pass -> FieldOcc pass
+ Language.Haskell.Syntax.Type: XFieldOcc :: XXFieldOcc pass -> FieldOcc pass
- Language.Haskell.Syntax.Type: XHsForAllTelescope :: !XXHsForAllTelescope pass -> HsForAllTelescope pass
+ Language.Haskell.Syntax.Type: XHsForAllTelescope :: XXHsForAllTelescope pass -> HsForAllTelescope pass
- Language.Haskell.Syntax.Type: XHsOuterTyVarBndrs :: !XXHsOuterTyVarBndrs pass -> HsOuterTyVarBndrs flag pass
+ Language.Haskell.Syntax.Type: XHsOuterTyVarBndrs :: XXHsOuterTyVarBndrs pass -> HsOuterTyVarBndrs flag pass
- Language.Haskell.Syntax.Type: XHsPatSigType :: !XXHsPatSigType pass -> HsPatSigType pass
+ Language.Haskell.Syntax.Type: XHsPatSigType :: XXHsPatSigType pass -> HsPatSigType pass
- Language.Haskell.Syntax.Type: XHsSigType :: !XXHsSigType pass -> HsSigType pass
+ Language.Haskell.Syntax.Type: XHsSigType :: XXHsSigType pass -> HsSigType pass
- Language.Haskell.Syntax.Type: XHsTyPat :: !XXHsTyPat pass -> HsTyPat pass
+ Language.Haskell.Syntax.Type: XHsTyPat :: XXHsTyPat pass -> HsTyPat pass
- Language.Haskell.Syntax.Type: XHsType :: !XXType pass -> HsType pass
+ Language.Haskell.Syntax.Type: XHsType :: XXType pass -> HsType pass
- Language.Haskell.Syntax.Type: XHsWildCardBndrs :: !XXHsWildCardBndrs pass thing -> HsWildCardBndrs pass thing
+ Language.Haskell.Syntax.Type: XHsWildCardBndrs :: XXHsWildCardBndrs pass thing -> HsWildCardBndrs pass thing
- Language.Haskell.Syntax.Type: XLHsQTyVars :: !XXLHsQTyVars pass -> LHsQTyVars pass
+ Language.Haskell.Syntax.Type: XLHsQTyVars :: XXLHsQTyVars pass -> LHsQTyVars pass
- Language.Haskell.Syntax.Type: XTyLit :: !XXTyLit pass -> HsTyLit pass
+ Language.Haskell.Syntax.Type: XTyLit :: XXTyLit pass -> HsTyLit pass
- Language.Haskell.Syntax.Type: XTyVarBndr :: !XXTyVarBndr pass -> HsTyVarBndr flag pass
+ Language.Haskell.Syntax.Type: XTyVarBndr :: XXTyVarBndr pass -> HsTyVarBndr flag pass
- Language.Haskell.Syntax.Type: data HsConDetails tyarg arg rec
+ Language.Haskell.Syntax.Type: data HsConDetails arg rec

This diff is very large; some files are shown as “too large to diff”. Download the raw patch for the complete diff.

Files

ClosureTypes.h view
@@ -89,4 +89,5 @@ #define SMALL_MUT_ARR_PTRS_FROZEN_CLEAN 62 #define COMPACT_NFDATA                63 #define CONTINUATION                  64-#define N_CLOSURE_TYPES               65+#define ANN_FRAME                     65+#define N_CLOSURE_TYPES               66
CodeGen.Platform.h view
@@ -2,7 +2,7 @@ import GHC.Cmm.Expr #if !(defined(MACHREGS_i386) || defined(MACHREGS_x86_64) \     || defined(MACHREGS_powerpc) || defined(MACHREGS_aarch64) \-    || defined(MACHREGS_riscv64))+    || defined(MACHREGS_riscv64) || defined(MACHREGS_loongarch64)) import GHC.Utils.Panic.Plain #endif import GHC.Platform.Reg@@ -1032,11 +1032,15 @@ -- ip0 -- used for spill offset computations freeReg 16 = False -#if defined(darwin_HOST_OS) || defined(ios_HOST_OS)+-- Note [Aarch64 Register x18 at Darwin and Windows]+-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -- x18 is reserved by the platform on Darwin/iOS, and can not be used -- More about ARM64 ABI that Apple platforms support: -- https://developer.apple.com/documentation/xcode/writing-arm64-code-for-apple-platforms -- https://github.com/Siguza/ios-resources/blob/master/bits/arm64.md+-- It is a reserved at Windows as well. Acts like TEB register in user mode at Windows.+-- https://learn.microsoft.com/en-us/cpp/build/arm64-windows-abi-conventions+#if defined(darwin_HOST_OS) || defined(ios_HOST_OS) || defined(mingw32_HOST_OS) freeReg 18 = False #endif @@ -1138,6 +1142,104 @@ -- made-up inter-procedural (ip) register -- See Note [The made-up RISCV64 TMP (IP) register] freeReg 31 = False++# if defined(REG_Base)+freeReg REG_Base  = False+# endif+# if defined(REG_Sp)+freeReg REG_Sp    = False+# endif+# if defined(REG_SpLim)+freeReg REG_SpLim = False+# endif+# if defined(REG_Hp)+freeReg REG_Hp    = False+# endif+# if defined(REG_HpLim)+freeReg REG_HpLim = False+# endif++# if defined(REG_R1)+freeReg REG_R1    = False+# endif+# if defined(REG_R2)+freeReg REG_R2    = False+# endif+# if defined(REG_R3)+freeReg REG_R3    = False+# endif+# if defined(REG_R4)+freeReg REG_R4    = False+# endif+# if defined(REG_R5)+freeReg REG_R5    = False+# endif+# if defined(REG_R6)+freeReg REG_R6    = False+# endif+# if defined(REG_R7)+freeReg REG_R7    = False+# endif+# if defined(REG_R8)+freeReg REG_R8    = False+# endif++# if defined(REG_F1)+freeReg REG_F1    = False+# endif+# if defined(REG_F2)+freeReg REG_F2    = False+# endif+# if defined(REG_F3)+freeReg REG_F3    = False+# endif+# if defined(REG_F4)+freeReg REG_F4    = False+# endif+# if defined(REG_F5)+freeReg REG_F5    = False+# endif+# if defined(REG_F6)+freeReg REG_F6    = False+# endif++# if defined(REG_D1)+freeReg REG_D1    = False+# endif+# if defined(REG_D2)+freeReg REG_D2    = False+# endif+# if defined(REG_D3)+freeReg REG_D3    = False+# endif+# if defined(REG_D4)+freeReg REG_D4    = False+# endif+# if defined(REG_D5)+freeReg REG_D5    = False+# endif+# if defined(REG_D6)+freeReg REG_D6    = False+# endif++freeReg _ = True++#elif defined(MACHREGS_loongarch64)++-- zero register+freeReg 0 = False+-- linker regster+freeReg 1 = False+-- thread register+freeReg 2 = False+-- stack pointer+freeReg 3 = False+-- made-up inter-procedural (ip) register for spilling offset computations+freeReg 20 = False+-- reserved+freeReg 21 = False+-- frame pointer+freeReg 22 = False  # if defined(REG_Base) freeReg REG_Base  = False
GHC.hs view
@@ -4,6 +4,7 @@ {-# LANGUAGE TupleSections, NamedFieldPuns #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE PatternSynonyms #-}+{-# LANGUAGE LambdaCase #-}  -- ----------------------------------------------------------------------------- --@@ -37,7 +38,9 @@         setSessionDynFlags,         setUnitDynFlags,         getProgramDynFlags, setProgramDynFlags,+        setProgramHUG, setProgramHUG_,         getInteractiveDynFlags, setInteractiveDynFlags,+        normaliseInteractiveDynFlags, initialiseInteractiveDynFlags,         interpretPackageEnv,          -- * Logging@@ -54,6 +57,7 @@         addTarget,         removeTarget,         guessTarget,+        guessTargetId,          -- * Loading\/compiling the program         depanal, depanalE,@@ -82,6 +86,7 @@         getModuleGraph,         isLoaded,         isLoadedModule,+        isLoadedHomeModule,         topSortModuleGraph,          -- * Inspecting modules@@ -99,33 +104,37 @@         findGlobalAnns,         mkNamePprCtxForModule,         ModIface,-        ModIface_(-          mi_module,-          mi_sig_of,-          mi_hsc_src,-          mi_src_hash,-          mi_hi_bytes,-          mi_deps,-          mi_usages,-          mi_exports,-          mi_used_th,-          mi_fixities,-          mi_warns,-          mi_anns,-          mi_insts,-          mi_fam_insts,-          mi_rules,-          mi_decls,-          mi_extra_decls,-          mi_top_env,-          mi_hpc,-          mi_trust,-          mi_trust_pkg,-          mi_complete_matches,-          mi_docs,-          mi_final_exts,-          mi_ext_fields-        ),+        ModIface_( mi_mod_info+                 , mi_module+                 , mi_sig_of+                 , mi_hsc_src+                 , mi_iface_hash+                 , mi_deps+                 , mi_public+                 , mi_exports+                 , mi_fixities+                 , mi_warns+                 , mi_anns+                 , mi_decls+                 , mi_defaults+                 , mi_simplified_core+                 , mi_top_env+                 , mi_insts+                 , mi_fam_insts+                 , mi_rules+                 , mi_trust+                 , mi_trust_pkg+                 , mi_complete_matches+                 , mi_docs+                 , mi_abi_hashes+                 , mi_ext_fields+                 , mi_hi_bytes+                 , mi_self_recomp_info+                 , mi_fix_fn+                 , mi_decl_warn_fn+                 , mi_export_warn_fn+                 , mi_hash_fn+                 ),         pattern ModIface,         SafeHaskellMode(..), @@ -150,6 +159,7 @@         getBindings, getInsts, getNamePprCtx,         findModule, lookupModule,         findQualifiedModule, lookupQualifiedModule,+        lookupLoadedHomeModuleByModuleName, lookupAllQualifiedModuleNames,         renamePkgQualM, renameRawPkgQualM,         isModuleTrusted, moduleTrustReqs,         getNamesInScope,@@ -191,7 +201,7 @@         getResumeContext,         GHC.obtainTermFromId, GHC.obtainTermFromVal, reconstructType,         modInfoModBreaks,-        ModBreaks(..), BreakIndex,+        ModBreaks(..), BreakTickIndex,         BreakpointId(..), InternalBreakpointId(..),         GHC.Runtime.Eval.back,         GHC.Runtime.Eval.forward,@@ -336,6 +346,7 @@ import GHC.Driver.Errors.Types import GHC.Driver.CmdLine import GHC.Driver.Session+import GHC.Driver.Session.Inspect import GHC.Driver.Backend import GHC.Driver.Config.Finder (initFinderOpts) import GHC.Driver.Config.Parser (initParserOpts)@@ -368,7 +379,7 @@ import GHC.Data.StringBuffer import GHC.Data.FastString import qualified GHC.LanguageExtensions as LangExt-import GHC.Rename.Names (renamePkgQual, renameRawPkgQual, gresFromAvails)+import GHC.Rename.Names (renamePkgQual, renameRawPkgQual)  import GHC.Tc.Utils.Monad    ( finalSafeMode, fixSafeInstances, initIfaceTcRn ) import GHC.Tc.Types@@ -415,15 +426,11 @@ import GHC.Types.Basic import GHC.Types.TyThing import GHC.Types.Name.Env-import GHC.Types.Name.Ppr import GHC.Types.TypeEnv-import GHC.Types.Breakpoint import GHC.Types.PkgQual-import GHC.Types.Unique.FM  import GHC.Unit-import GHC.Unit.Env-import GHC.Unit.External+import GHC.Unit.Env as UnitEnv import GHC.Unit.Finder import GHC.Unit.Module.ModIface import GHC.Unit.Module.ModGuts@@ -431,6 +438,7 @@ import GHC.Unit.Module.ModSummary import GHC.Unit.Module.Graph import GHC.Unit.Home.ModInfo+import qualified GHC.Unit.Home.Graph as HUG import GHC.Settings  import Control.Applicative ((<|>))@@ -438,6 +446,7 @@ import Control.Monad import Control.Monad.Catch as MC import Data.Foldable+import Data.Function ((&)) import Data.IORef import Data.List (isPrefixOf) import Data.Typeable    ( Typeable )@@ -454,6 +463,7 @@ import System.FilePath import System.IO.Error  ( isDoesNotExistError ) + -- %************************************************************************ -- %*                                                                      * --             Initialisation: exception handlers@@ -482,6 +492,8 @@                          liftIO $ throwIO UserInterrupt                      Just StackOverflow ->                          fm "stack overflow: use +RTS -K<size> to increase it"+                     Just HeapOverflow ->+                         fm "heap overflow: use +RTS -M<size> to increase maximum heap size"                      _ -> case fromException exception of                           Just (ex :: ExitCode) -> liftIO $ throwIO ex                           _ ->@@ -664,7 +676,7 @@           , homeUnitEnv_home_unit = Just home_unit           } -  let unit_env = ue_updateHomeUnitEnv upd uid (hsc_unit_env hsc_env)+  let unit_env = UnitEnv.ue_updateHomeUnitEnv upd uid (hsc_unit_env hsc_env)    let dflags = updated_dflags @@ -682,7 +694,7 @@   let !unit_env1 =         if homeUnitId_ dflags /= uid           then-            ue_renameUnitId+            UnitEnv.renameUnitId                   uid                   (homeUnitId_ dflags)                   unit_env0@@ -700,9 +712,9 @@ setTopSessionDynFlags dflags = do   hsc_env <- getSession   logger  <- getLogger-  lookup_cache  <- liftIO $ newMVar emptyUFM+  lookup_cache  <- liftIO $ mkInterpSymbolCache -  -- Interpreter+  -- see Note [Target code interpreter]   interp <- if     -- Wasm dynamic linker     | ArchWasm32 <- platformArch $ targetPlatform dflags@@ -722,10 +734,17 @@                 { wasmInterpDyLD = dyld,                   wasmInterpLibDir = libdir,                   wasmInterpOpts = getOpts dflags opt_i,+                  wasmInterpBrowser = gopt Opt_GhciBrowser dflags,+                  wasmInterpBrowserHost = ghciBrowserHost dflags,+                  wasmInterpBrowserPort = ghciBrowserPort dflags,+                  wasmInterpBrowserRedirectWasiConsole = gopt Opt_GhciBrowserRedirectWasiConsole dflags,+                  wasmInterpBrowserPuppeteerLaunchOpts = ghciBrowserPuppeteerLaunchOpts dflags,+                  wasmInterpBrowserPlaywrightBrowserType = ghciBrowserPlaywrightBrowserType dflags,+                  wasmInterpBrowserPlaywrightLaunchOpts = ghciBrowserPlaywrightLaunchOpts dflags,                   wasmInterpTargetPlatform = targetPlatform dflags,                   wasmInterpProfiled = profiled,                   wasmInterpHsSoSuffix = way_tag ++ dynLibSuffix (ghcNameVersion dflags),-                  wasmInterpUnitState = ue_units $ hsc_unit_env hsc_env+                  wasmInterpUnitState = ue_homeUnitState $ hsc_unit_env hsc_env                 }         pure $ Just $ Interp (ExternalInterp $ ExtWasm $ ExtInterpState cfg s) loader lookup_cache @@ -819,7 +838,7 @@           let cached_unit_dbs = homeUnitEnv_unit_dbs homeUnitEnv               dflags = homeUnitEnv_dflags homeUnitEnv               old_hpt = homeUnitEnv_hpt homeUnitEnv-              home_units = unitEnv_keys (ue_home_unit_graph old_unit_env)+              home_units = HUG.allUnits (ue_home_unit_graph old_unit_env)            (dbs,unit_state,home_unit,mconstants) <- liftIO $ initUnits logger dflags cached_unit_dbs home_units @@ -832,12 +851,13 @@             , homeUnitEnv_home_unit = Just home_unit             } -        let dflags1 = homeUnitEnv_dflags $ unitEnv_lookup (ue_currentUnit old_unit_env) home_unit_graph+        let dflags1 = homeUnitEnv_dflags $ HUG.unitEnv_lookup (ue_currentUnit old_unit_env) home_unit_graph         let unit_env = UnitEnv               { ue_platform        = targetPlatform dflags1               , ue_namever         = ghcNameVersion dflags1               , ue_home_unit_graph = home_unit_graph               , ue_current_unit    = ue_currentUnit old_unit_env+              , ue_module_graph    = ue_module_graph old_unit_env               , ue_eps             = ue_eps old_unit_env               }         modifySession $ \h -> hscSetFlags dflags1 h{ hsc_unit_env = unit_env }@@ -846,7 +866,115 @@   when invalidate_needed $ invalidateModSummaryCache   return changed +-- | Sets the program 'HomeUnitGraph'.+--+-- Sets the given 'HomeUnitGraph' as the 'HomeUnitGraph' of the current+-- session. If the package flags change, we reinitialise the 'UnitState'+-- of all 'HomeUnitEnv's in the current session.+--+-- This function unconditionally invalidates the module graph cache.+--+-- Precondition: the given 'HomeUnitGraph' must have the same keys as the 'HomeUnitGraph'+-- of the current session. I.e., assuming the new 'HomeUnitGraph' is called+-- 'new_hug', then:+--+-- @+--  do+--    hug <- hsc_HUG \<$\> getSession+--    pure $ unitEnv_keys new_hug == unitEnv_keys hug+-- @+--+-- If this precondition is violated, the function will crash.+--+-- Conceptually, similar to 'setProgramDynFlags', but performs the same check+-- for all 'HomeUnitEnv's.+setProgramHUG :: GhcMonad m => HomeUnitGraph -> m Bool+setProgramHUG =+  setProgramHUG_ True +-- | Same as 'setProgramHUG', but gives you control over whether you want to+-- invalidate the module graph cache.+setProgramHUG_ :: GhcMonad m => Bool -> HomeUnitGraph -> m Bool+setProgramHUG_ invalidate_needed new_hug0 = do+  logger <- getLogger++  hug0 <- hsc_HUG <$> getSession+  (changed, new_hug1) <- checkNewHugDynFlags logger hug0 new_hug0++  if changed+    then do+      unit_env0 <- hsc_unit_env <$> getSession+      home_unit_graph <- HUG.unitEnv_traverseWithKey+        (updateHomeUnit logger unit_env0 new_hug1)+        (ue_home_unit_graph unit_env0)++      let dflags1 = homeUnitEnv_dflags $ HUG.unitEnv_lookup (ue_currentUnit unit_env0) home_unit_graph+      let unit_env = UnitEnv+            { ue_platform        = targetPlatform dflags1+            , ue_namever         = ghcNameVersion dflags1+            , ue_home_unit_graph = home_unit_graph+            , ue_current_unit    = ue_currentUnit unit_env0+            , ue_eps             = ue_eps unit_env0+            , ue_module_graph    = ue_module_graph unit_env0+            }+      modifySession $ \h ->+        -- hscSetFlags takes care of updating the logger as well.+        hscSetFlags dflags1 h{ hsc_unit_env = unit_env }+    else do+      modifySession (\env ->+        env+          -- Set the new 'HomeUnitGraph'.+          & hscUpdateHUG (const new_hug1)+          -- hscSetActiveUnitId makes sure that the 'hsc_dflags'+          -- are up-to-date.+          & hscSetActiveUnitId (hscActiveUnitId env)+          -- Make sure the logger is also updated.+          & hscUpdateLoggerFlags)++  when invalidate_needed $ invalidateModSummaryCache+  pure changed+  where+    checkNewHugDynFlags :: GhcMonad m => Logger -> HomeUnitGraph -> HomeUnitGraph -> m (Bool, HomeUnitGraph)+    checkNewHugDynFlags logger old_hug new_hug = do+      -- Traverse the new HUG and check its 'DynFlags'.+      -- The old 'HUG' is used to check whether package flags have changed.+      hugWithCheck <- HUG.unitEnv_traverseWithKey+        (\unitId homeUnit -> do+          let newFlags = homeUnitEnv_dflags homeUnit+              oldFlags = homeUnitEnv_dflags (HUG.unitEnv_lookup unitId old_hug)+          checkedFlags <- checkNewDynFlags logger newFlags+          pure+            ( packageFlagsChanged oldFlags checkedFlags+            , homeUnit { homeUnitEnv_dflags = checkedFlags }+            )+        )+        new_hug+      let+        -- Did any of the package flags change?+        changed = or $ fmap fst hugWithCheck+        hug = fmap snd hugWithCheck+      pure (changed, hug)++    updateHomeUnit :: GhcMonad m => Logger -> UnitEnv -> HomeUnitGraph -> (UnitId -> HomeUnitEnv -> m HomeUnitEnv)+    updateHomeUnit logger unit_env updates = \uid homeUnitEnv -> do+      let cached_unit_dbs = homeUnitEnv_unit_dbs homeUnitEnv+          dflags = case HUG.unitEnv_lookup_maybe uid updates of+            Nothing -> homeUnitEnv_dflags homeUnitEnv+            Just env -> homeUnitEnv_dflags env+          old_hpt = homeUnitEnv_hpt homeUnitEnv+          home_units = HUG.allUnits (ue_home_unit_graph unit_env)++      (dbs,unit_state,home_unit,mconstants) <- liftIO $ initUnits logger dflags cached_unit_dbs home_units++      updated_dflags <- liftIO $ updatePlatformConstants dflags mconstants+      pure HomeUnitEnv+        { homeUnitEnv_units = unit_state+        , homeUnitEnv_unit_dbs = Just dbs+        , homeUnitEnv_dflags = updated_dflags+        , homeUnitEnv_hpt = old_hpt+        , homeUnitEnv_home_unit = Just home_unit+        }+ -- When changing the DynFlags, we want the changes to apply to future -- loads, but without completely discarding the program.  But the -- DynFlags are cached in each ModSummary in the hsc_mod_graph, so@@ -868,7 +996,7 @@ -- invalidateModSummaryCache :: GhcMonad m => m () invalidateModSummaryCache =-  modifySession $ \h -> h { hsc_mod_graph = mapMG inval (hsc_mod_graph h) }+  modifySession $ \hsc_env -> setModuleGraph (mapMG inval (hsc_mod_graph hsc_env)) hsc_env  where   inval ms = ms { ms_hs_hash = fingerprint0 } @@ -885,24 +1013,8 @@ setInteractiveDynFlags :: GhcMonad m => DynFlags -> m () setInteractiveDynFlags dflags = do   logger <- getLogger-  dflags' <- checkNewDynFlags logger dflags-  dflags'' <- checkNewInteractiveDynFlags logger dflags'-  modifySessionM $ \hsc_env0 -> do-    let ic0 = hsc_IC hsc_env0--    -- Initialise (load) plugins in the interactive environment with the new-    -- DynFlags-    plugin_env <- liftIO $ initializePlugins $ mkInteractiveHscEnv $-                    hsc_env0 { hsc_IC = ic0 { ic_dflags = dflags'' }}--    -- Update both plugins cache and DynFlags in the interactive context.-    return $ hsc_env0-                { hsc_IC = ic0-                    { ic_plugins = hsc_plugins plugin_env-                    , ic_dflags  = hsc_dflags  plugin_env-                    }-                }-+  icdflags <- normaliseInteractiveDynFlags logger dflags+  modifySessionM (initialiseInteractiveDynFlags icdflags)  -- | Get the 'DynFlags' used to evaluate interactive expressions. getInteractiveDynFlags :: GhcMonad m => m DynFlags@@ -916,7 +1028,7 @@     -> [Located String]     -> m (DynFlags, [Located String], Messages DriverMessage) parseDynamicFlags logger dflags cmdline = do-  (dflags1, leftovers, warns) <- parseDynamicFlagsCmdLine dflags cmdline+  (dflags1, leftovers, warns) <- parseDynamicFlagsCmdLine logger dflags cmdline   -- flags that have just been read are used by the logger when loading package   -- env (this is checked by T16318)   let logger1 = setLogFlags logger (initLogFlags dflags1)@@ -1007,17 +1119,49 @@  ----------------------------------------------------------------------------- +-- | Normalise the 'DynFlags' for us in an interactive context.+--+-- Makes sure unsupported Flags and other incosistencies are reported and removed.+normaliseInteractiveDynFlags :: MonadIO m => Logger -> DynFlags -> m DynFlags+normaliseInteractiveDynFlags logger dflags = do+  dflags' <- checkNewDynFlags logger dflags+  checkNewInteractiveDynFlags logger dflags'++-- | Given a set of normalised 'DynFlags' (see 'normaliseInteractiveDynFlags')+-- for the interactive context, initialize the 'InteractiveContext'.+--+-- Initialized plugins and sets the 'DynFlags' as the 'ic_dflags' of the+-- 'InteractiveContext'.+initialiseInteractiveDynFlags :: GhcMonad m => DynFlags -> HscEnv -> m HscEnv+initialiseInteractiveDynFlags dflags hsc_env0 = do+  let ic0 = hsc_IC hsc_env0++  -- Initialise (load) plugins in the interactive environment with the new+  -- DynFlags+  plugin_env <- liftIO $ initializePlugins $ mkInteractiveHscEnv $+                  hsc_env0 { hsc_IC = ic0 { ic_dflags = dflags }}++  -- Update both plugins cache and DynFlags in the interactive context.+  return $ hsc_env0+              { hsc_IC = ic0+                  { ic_plugins = hsc_plugins plugin_env+                  , ic_dflags  = hsc_dflags  plugin_env+                  }+              }+ -- | Checks the set of new DynFlags for possibly erroneous option -- combinations when invoking 'setSessionDynFlags' and friends, and if -- found, returns a fixed copy (if possible). checkNewDynFlags :: MonadIO m => Logger -> DynFlags -> m DynFlags checkNewDynFlags logger dflags = do   -- See Note [DynFlags consistency]-  let (dflags', warnings) = makeDynFlagsConsistent dflags+  let (dflags', warnings, infoverb) = makeDynFlagsConsistent dflags   let diag_opts = initDiagOpts dflags       print_config = initPrintConfig dflags   liftIO $ printOrThrowDiagnostics logger print_config diag_opts     $ fmap GhcDriverMessage $ warnsToMessages diag_opts warnings+  when (logVerbAtLeast logger 3) $+    mapM_ (\(L _loc m) -> liftIO $ logInfo logger m) infoverb   return dflags'  checkNewInteractiveDynFlags :: MonadIO m => Logger -> DynFlags -> m DynFlags@@ -1067,7 +1211,7 @@   where    filter targets = [ t | t@Target { targetId = id } <- targets, id /= target_id ] --- | Attempts to guess what Target a string refers to.  This function+-- | Attempts to guess what 'Target' a string refers to.  This function -- implements the @--make@/GHCi command-line syntax for filenames: -- --   - if the string looks like a Haskell source filename, then interpret it@@ -1076,27 +1220,52 @@ --   - if adding a .hs or .lhs suffix yields the name of an existing file, --     then use that -----   - otherwise interpret the string as a module name+--   - If it looks like a module name, interpret it as such --+--   - otherwise, this function throws a 'GhcException'. guessTarget :: GhcMonad m => String -> Maybe UnitId -> Maybe Phase -> m Target guessTarget str mUnitId (Just phase)    = do      tuid <- unitIdOrHomeUnit mUnitId      return (Target (TargetFile str (Just phase)) True tuid Nothing)-guessTarget str mUnitId Nothing+guessTarget str mUnitId Nothing = do+  targetId <- guessTargetId str+  toTarget targetId+     where+         obj_allowed+                | '*':_ <- str = False+                | otherwise    = True+         toTarget tid = do+           tuid <- unitIdOrHomeUnit mUnitId+           pure $ Target tid obj_allowed tuid Nothing++-- | Attempts to guess what 'TargetId' a string refers to.  This function+-- implements the @--make@/GHCi command-line syntax for filenames:+--+--   - if the string looks like a Haskell source filename, then interpret it+--     as such+--+--   - if adding a .hs or .lhs suffix yields the name of an existing file,+--     then use that+--+--   - If it looks like a module name, interpret it as such+--+--   - otherwise, this function throws a 'GhcException'.+guessTargetId :: GhcMonad m => String -> m TargetId+guessTargetId str    | isHaskellSrcFilename file-   = target (TargetFile file Nothing)+   = pure (TargetFile file Nothing)    | otherwise    = do exists <- liftIO $ doesFileExist hs_file         if exists-           then target (TargetFile hs_file Nothing)+           then pure (TargetFile hs_file Nothing)            else do         exists <- liftIO $ doesFileExist lhs_file         if exists-           then target (TargetFile lhs_file Nothing)+           then pure (TargetFile lhs_file Nothing)            else do         if looksLikeModuleName file-           then target (TargetModule (mkModuleName file))+           then pure (TargetModule (mkModuleName file))            else do         dflags <- getDynFlags         liftIO $ throwGhcExceptionIO@@ -1104,16 +1273,12 @@                  text "target" <+> quotes (text file) <+>                  text "is not a module name or a source file"))      where-         (file,obj_allowed)-                | '*':rest <- str = (rest, False)-                | otherwise       = (str,  True)--         hs_file  = file <.> "hs"-         lhs_file = file <.> "lhs"+        file+          | '*':rest <- str = rest+          | otherwise       = str -         target tid = do-           tuid <- unitIdOrHomeUnit mUnitId-           pure $ Target tid obj_allowed tuid Nothing+        hs_file  = file <.> "hs"+        lhs_file = file <.> "lhs"  -- | Unwrap 'UnitId' or retrieve the 'UnitId' -- of the current 'HomeUnit'.@@ -1234,11 +1399,11 @@ -- -- This function ignores boot modules and requires that there is only one -- non-boot module with the given name.-getModSummary :: GhcMonad m => ModuleName -> m ModSummary+getModSummary :: GhcMonad m => Module -> m ModSummary getModSummary mod = do    mg <- liftM hsc_mod_graph getSession    let mods_by_name = [ ms | ms <- mgModSummaries mg-                      , ms_mod_name ms == mod+                      , ms_mod ms == mod                       , isBootSummary ms == NotBoot ]    case mods_by_name of      [] -> do dflags <- getDynFlags@@ -1269,7 +1434,9 @@  liftIO $ do    let ms          = modSummary pmod    let lcl_dflags  = ms_hspp_opts ms -- take into account pragmas (OPTIONS_GHC, etc.)-   let lcl_hsc_env = hscSetFlags lcl_dflags hsc_env+   let lcl_hsc_env =+          hscSetFlags lcl_dflags $+          hscSetActiveUnitId (toUnitId $ moduleUnit $ ms_mod ms) hsc_env    let lcl_logger  = hsc_logger lcl_hsc_env    (tc_gbl_env, rn_info) <- hscTypecheckRename lcl_hsc_env ms $                         HsParsedModule { hpm_module = parsedSource pmod,@@ -1290,7 +1457,7 @@            minf_instances = fixSafeInstances safe $ instEnvElts $ md_insts details,            minf_iface     = Nothing,            minf_safe      = safe,-           minf_modBreaks = emptyModBreaks+           minf_modBreaks = Nothing          }}  -- | Desugar a typechecked module.@@ -1401,155 +1568,6 @@           cm_safe    = safe_mode          } --- %************************************************************************--- %*                                                                      *---             Inspecting the session--- %*                                                                      *--- %************************************************************************---- | Get the module dependency graph.-getModuleGraph :: GhcMonad m => m ModuleGraph -- ToDo: DiGraph ModSummary-getModuleGraph = liftM hsc_mod_graph getSession---- | Return @True@ \<==> module is loaded.-isLoaded :: GhcMonad m => ModuleName -> m Bool-isLoaded m = withSession $ \hsc_env ->-  return $! isJust (lookupHpt (hsc_HPT hsc_env) m)--isLoadedModule :: GhcMonad m => UnitId -> ModuleName -> m Bool-isLoadedModule uid m = withSession $ \hsc_env ->-  return $! isJust (lookupHug (hsc_HUG hsc_env) uid m)---- | Return the bindings for the current interactive session.-getBindings :: GhcMonad m => m [TyThing]-getBindings = withSession $ \hsc_env ->-    return $ icInScopeTTs $ hsc_IC hsc_env---- | Return the instances for the current interactive session.-getInsts :: GhcMonad m => m ([ClsInst], [FamInst])-getInsts = withSession $ \hsc_env ->-    let (inst_env, fam_env) = ic_instances (hsc_IC hsc_env)-    in return (instEnvElts inst_env, fam_env)--getNamePprCtx :: GhcMonad m => m NamePprCtx-getNamePprCtx = withSession $ \hsc_env -> do-  return $ icNamePprCtx (hsc_unit_env hsc_env) (hsc_IC hsc_env)---- | Container for information about a 'Module'.-data ModuleInfo = ModuleInfo {-        minf_type_env  :: TypeEnv,-        minf_exports   :: [AvailInfo],-        minf_instances :: [ClsInst],-        minf_iface     :: Maybe ModIface,-        minf_safe      :: SafeHaskellMode,-        minf_modBreaks :: ModBreaks-  }-        -- We don't want HomeModInfo here, because a ModuleInfo applies-        -- to package modules too.----- | Request information about a loaded 'Module'-getModuleInfo :: GhcMonad m => Module -> m (Maybe ModuleInfo)  -- XXX: Maybe X-getModuleInfo mdl = withSession $ \hsc_env -> do-  if moduleUnitId mdl `S.member` hsc_all_home_unit_ids hsc_env-        then liftIO $ getHomeModuleInfo hsc_env mdl-        else liftIO $ getPackageModuleInfo hsc_env mdl--getPackageModuleInfo :: HscEnv -> Module -> IO (Maybe ModuleInfo)-getPackageModuleInfo hsc_env mdl-  = do  eps <- hscEPS hsc_env-        iface <- hscGetModuleInterface hsc_env mdl-        let-            avails = mi_exports iface-            pte    = eps_PTE eps-            tys    = [ ty | name <- concatMap availNames avails,-                            Just ty <- [lookupTypeEnv pte name] ]--        return (Just (ModuleInfo {-                        minf_type_env  = mkTypeEnv tys,-                        minf_exports   = avails,-                        minf_instances = error "getModuleInfo: instances for package module unimplemented",-                        minf_iface     = Just iface,-                        minf_safe      = getSafeMode $ mi_trust iface,-                        minf_modBreaks = emptyModBreaks-                }))--availsToGlobalRdrEnv :: HasDebugCallStack => HscEnv -> Module -> [AvailInfo] -> IfGlobalRdrEnv-availsToGlobalRdrEnv hsc_env mod avails-  = forceGlobalRdrEnv rdr_env-    -- See Note [Forcing GREInfo] in GHC.Types.GREInfo.-  where-    rdr_env = mkGlobalRdrEnv (gresFromAvails hsc_env (Just imp_spec) avails)-      -- We're building a GlobalRdrEnv as if the user imported-      -- all the specified modules into the global interactive module-    imp_spec = ImpSpec { is_decl = decl, is_item = ImpAll}-    decl = ImpDeclSpec { is_mod = mod, is_as = moduleName mod,-                         is_qual = False, is_isboot = NotBoot, is_pkg_qual = NoPkgQual,-                         is_dloc = srcLocSpan interactiveSrcLoc }--getHomeModuleInfo :: HscEnv -> Module -> IO (Maybe ModuleInfo)-getHomeModuleInfo hsc_env mdl =-  case lookupHugByModule mdl (hsc_HUG hsc_env) of-    Nothing  -> return Nothing-    Just hmi -> do-      let details  = hm_details hmi-          iface    = hm_iface hmi-      return (Just (ModuleInfo {-                        minf_type_env  = md_types details,-                        minf_exports   = md_exports details,-                         -- NB: already forced. See Note [Forcing GREInfo] in GHC.Types.GREInfo.-                        minf_instances = instEnvElts $ md_insts details,-                        minf_iface     = Just iface,-                        minf_safe      = getSafeMode $ mi_trust iface-                       ,minf_modBreaks = getModBreaks hmi-                        }))---- | The list of top-level entities defined in a module-modInfoTyThings :: ModuleInfo -> [TyThing]-modInfoTyThings minf = typeEnvElts (minf_type_env minf)--modInfoExports :: ModuleInfo -> [Name]-modInfoExports minf = concatMap availNames $! minf_exports minf--modInfoExportsWithSelectors :: ModuleInfo -> [Name]-modInfoExportsWithSelectors minf = concatMap availNames $! minf_exports minf---- | Returns the instances defined by the specified module.--- Warning: currently unimplemented for package modules.-modInfoInstances :: ModuleInfo -> [ClsInst]-modInfoInstances = minf_instances--modInfoIsExportedName :: ModuleInfo -> Name -> Bool-modInfoIsExportedName minf name = elemNameSet name (availsToNameSet (minf_exports minf))--mkNamePprCtxForModule ::-  GhcMonad m =>-  Module     ->-  ModuleInfo ->-  m NamePprCtx-mkNamePprCtxForModule mod minf = withSession $ \hsc_env -> do-  let name_ppr_ctx = mkNamePprCtx ptc (hsc_unit_env hsc_env) (availsToGlobalRdrEnv hsc_env mod (minf_exports minf))-      ptc = initPromotionTickContext (hsc_dflags hsc_env)-  return name_ppr_ctx--modInfoLookupName :: GhcMonad m =>-                     ModuleInfo -> Name-                  -> m (Maybe TyThing) -- XXX: returns a Maybe X-modInfoLookupName minf name = withSession $ \hsc_env -> do-   case lookupTypeEnv (minf_type_env minf) name of-     Just tyThing -> return (Just tyThing)-     Nothing      -> liftIO (lookupType hsc_env name)--modInfoIface :: ModuleInfo -> Maybe ModIface-modInfoIface = minf_iface---- | Retrieve module safe haskell mode-modInfoSafe :: ModuleInfo -> SafeHaskellMode-modInfoSafe = minf_safe--modInfoModBreaks :: ModuleInfo -> ModBreaks-modInfoModBreaks = minf_modBreaks- isDictonaryId :: Id -> Bool isDictonaryId id = isDictTy (idType id) @@ -1763,7 +1781,7 @@ modNotLoadedError dflags m loc = throwGhcExceptionIO $ CmdLineError $ showSDoc dflags $    text "module is not loaded:" <+>    quotes (ppr (moduleName m)) <+>-   parens (text (expectJust "modNotLoadedError" (ml_hs_file loc)))+   parens (text (expectJust (ml_hs_file loc)))  renamePkgQualM :: GhcMonad m => ModuleName -> Maybe FastString -> m PkgQual renamePkgQualM mn p = withSession $ \hsc_env -> pure (renamePkgQual (hsc_unit_env hsc_env) mn p)@@ -1800,12 +1818,56 @@ lookupQualifiedModule pkgqual mod_name = findQualifiedModule pkgqual mod_name  lookupLoadedHomeModule :: GhcMonad m => UnitId -> ModuleName -> m (Maybe Module)-lookupLoadedHomeModule uid mod_name = withSession $ \hsc_env -> do-  liftIO $ trace_if (hsc_logger hsc_env) (text "lookupLoadedHomeModule" <+> ppr mod_name <+> ppr uid)-  case lookupHug  (hsc_HUG hsc_env) uid mod_name  of+lookupLoadedHomeModule uid mod_name = withSession $ \hsc_env -> liftIO $ do+  trace_if (hsc_logger hsc_env) (text "lookupLoadedHomeModule" <+> ppr mod_name <+> ppr uid)+  HUG.lookupHug (hsc_HUG hsc_env) uid mod_name >>= \case     Just mod_info      -> return (Just (mi_module (hm_iface mod_info)))     _not_a_home_module -> return Nothing +-- | Lookup the given 'ModuleName' in the 'HomeUnitGraph'.+--+-- Returns 'Nothing' if no 'Module' has the given 'ModuleName'.+-- Otherwise, returns all 'Module's that have the given 'ModuleName'.+--+-- A 'ModuleName' is generally not enough to uniquely identify a 'Module', since+-- there can be multiple units exposing the same 'ModuleName' in the case of+-- multiple home units.+-- Thus, this function may return more than one possible 'Module'.+-- We leave it up to the caller to decide how to handle the ambiguity.+-- For example, GHCi may prompt the user to clarify which 'Module' is the correct one.+--+lookupLoadedHomeModuleByModuleName :: GhcMonad m => ModuleName -> m (Maybe [Module])+lookupLoadedHomeModuleByModuleName mod_name = withSession $ \hsc_env -> liftIO $ do+  trace_if (hsc_logger hsc_env) (text "lookupLoadedHomeModuleByModuleName" <+> ppr mod_name)+  HUG.lookupAllHug (hsc_HUG hsc_env) mod_name >>= \case+    []        -> return Nothing+    mod_infos -> return (Just (mi_module . hm_iface <$> mod_infos))++-- | Given a 'ModuleName' and 'PkgQual', lookup all 'Module's that may fit the criteria.+--+-- Identically to 'lookupLoadedHomeModuleByModuleName', there may be more than one+-- 'Module' in the 'HomeUnitGraph' that has the given 'ModuleName'.+--+-- The result is guaranteed to be non-empty, if no 'Module' can be found,+-- this function throws an error.+lookupAllQualifiedModuleNames :: GhcMonad m => PkgQual -> ModuleName -> m [Module]+lookupAllQualifiedModuleNames NoPkgQual mod_name = withSession $ \hsc_env -> do+  home <- lookupLoadedHomeModuleByModuleName mod_name+  case home of+    Just m  -> return m+    Nothing -> liftIO $ do+      let fc     = hsc_FC hsc_env+      let units  = hsc_units hsc_env+      let dflags = hsc_dflags hsc_env+      let fopts  = initFinderOpts dflags+      res <- findExposedPackageModule fc fopts units mod_name NoPkgQual+      case res of+        Found _ m -> return [m]+        err       -> throwOneError $ noModError hsc_env noSrcSpan mod_name err+lookupAllQualifiedModuleNames pkgqual mod_name = do+  m <- findQualifiedModule pkgqual mod_name+  pure [m]+ -- | Check that a module is safe to import (according to Safe Haskell). -- -- We return True to indicate the import is safe and False otherwise@@ -1836,14 +1898,17 @@ getGHCiMonad = fmap (ic_monad . hsc_IC) getSession  getHistorySpan :: GhcMonad m => History -> m SrcSpan-getHistorySpan h = withSession $ \hsc_env ->-    return $ GHC.Runtime.Eval.getHistorySpan hsc_env h+getHistorySpan h = withSession $ \hsc_env -> liftIO $ GHC.Runtime.Eval.getHistorySpan (hsc_HUG hsc_env) h  obtainTermFromVal :: GhcMonad m => Int ->  Bool -> Type -> a -> m Term obtainTermFromVal bound force ty a = withSession $ \hsc_env ->     liftIO $ GHC.Runtime.Eval.obtainTermFromVal hsc_env bound force ty a -obtainTermFromId :: GhcMonad m => Int -> Bool -> Id -> m Term+obtainTermFromId :: GhcMonad m+                 => Int -- ^ How many times to recurse for subterms+                 -> Bool -- ^ Whether to force the expression+                 -> Id+                 -> m Term obtainTermFromId bound force id = withSession $ \hsc_env ->     liftIO $ GHC.Runtime.Eval.obtainTermFromId hsc_env bound force id 
GHC/Builtin/Names.hs view
@@ -54,14 +54,13 @@   1. When parsing source code, the RdrName-decorated AST has some      RdrNames which are Exact. These are wired-in RdrNames where      we could directly tell from the parsed syntax what Name to-     use. For example, when we parse a [] in a type we can just insert-     an Exact RdrName Name with the listTyConKey.+     use. For example, when we parse a [] in a type and ListTuplePuns+     are enabled, we can just insert (Exact listTyConName :: RdrName). -     Currently, I believe this is just an optimisation: it would be-     equally valid to just output Orig RdrNames that correctly record-     the module etc we expect the final Name to come from. However,-     were we to eliminate isBuiltInOcc_maybe it would become essential-     (see point 3).+     This is just an optimisation: it would be equally valid to output+     Orig RdrNames that correctly record the module (and package) that+     we expect the final Name to come from. The name would be looked up+     in the OrigNameCache (see point 3).    2. The knownKeyNames (which consist of the basicKnownKeyNames from      the module, and those names reachable via the wired-in stuff from@@ -78,9 +77,10 @@   3. For "infinite families" of known-key names (i.e. tuples and sums), we      have to be extra careful. Because there are an infinite number of      these things, we cannot add them to the list of known-key names-     used to initialise the OrigNameCache. Instead, we have to-     rely on never having to look them up in that cache. See-     Note [Infinite families of known-key names] for details.+     used to initialise the OrigNameCache. Instead, lookupOrigNameCache pretends+     that these names are in the cache by using isInfiniteFamilyOrigName_maybe+     before the actual lookup.+     See Note [Infinite families of known-key names] for details.   Note [Infinite families of known-key names]@@ -98,26 +98,15 @@    b) The known infinite families of names are specially serialised by      GHC.Iface.Binary.putName, with that special treatment detected when we read-     back to ensure that we get back to the correct uniques. See Note [Symbol-     table representation of names] in GHC.Iface.Binary and Note [How tuples-     work] in GHC.Builtin.Types.--Most of the infinite families cannot occur in source code, so mechanisms (a) and (b)-suffice to ensure that they always have the right Unique. In particular,-implicit param TyCon names, constraint tuples and Any TyCons cannot be mentioned-by the user. For those things that *can* appear in source programs,--  c) GHC.Iface.Env.lookupOrigNameCache uses isBuiltInOcc_maybe to map built-in syntax-     directly onto the corresponding name, rather than trying to find it in the-     original-name cache.+     back to ensure that we get back to the correct uniques.+     See Note [Symbol table representation of names] in GHC.Iface.Binary and+     Note [How tuples work] in GHC.Builtin.Types. +  c) GHC.Iface.Env.lookupOrigNameCache uses isInfiniteFamilyOrigName_maybe to+     map tuples and sums onto their exact names, rather than trying to find them+     in the original-name cache.      See also Note [Built-in syntax and the OrigNameCache] -Note that one-tuples are an exception to the rule, as they do get assigned-known keys. See-Note [One-tuples] (Wrinkle: Make boxed one-tuple names have known keys)-in GHC.Builtin.Types.- -}  {-# LANGUAGE CPP #-}@@ -522,6 +511,8 @@         , unsafeEqualityTyConName         , unsafeReflDataConName         , unsafeCoercePrimName++        , unsafeUnpackJSStringUtf8ShShName     ]  genericTyConNames :: [Name]@@ -557,24 +548,23 @@ gHC_PRIM, gHC_PRIM_PANIC,     gHC_TYPES, gHC_INTERNAL_DATA_DATA, gHC_MAGIC, gHC_MAGIC_DICT,     gHC_CLASSES, gHC_PRIMOPWRAPPERS :: Module-gHC_PRIM           = mkPrimModule (fsLit "GHC.Prim")   -- Primitive types and values-gHC_PRIM_PANIC     = mkPrimModule (fsLit "GHC.Prim.Panic")-gHC_TYPES          = mkPrimModule (fsLit "GHC.Types")-gHC_MAGIC          = mkPrimModule (fsLit "GHC.Magic")-gHC_MAGIC_DICT     = mkPrimModule (fsLit "GHC.Magic.Dict")-gHC_CSTRING        = mkPrimModule (fsLit "GHC.CString")-gHC_CLASSES        = mkPrimModule (fsLit "GHC.Classes")-gHC_PRIMOPWRAPPERS = mkPrimModule (fsLit "GHC.PrimopWrappers")--gHC_INTERNAL_TUPLE                  = mkPrimModule (fsLit "GHC.Tuple")+gHC_PRIM           = mkGhcInternalModule (fsLit "GHC.Internal.Prim")   -- Primitive types and values+gHC_PRIM_PANIC     = mkGhcInternalModule (fsLit "GHC.Internal.Prim.Panic")+gHC_TYPES          = mkGhcInternalModule (fsLit "GHC.Internal.Types")+gHC_MAGIC          = mkGhcInternalModule (fsLit "GHC.Internal.Magic")+gHC_MAGIC_DICT     = mkGhcInternalModule (fsLit "GHC.Internal.Magic.Dict")+gHC_CSTRING        = mkGhcInternalModule (fsLit "GHC.Internal.CString")+gHC_CLASSES        = mkGhcInternalModule (fsLit "GHC.Internal.Classes")+gHC_PRIMOPWRAPPERS = mkGhcInternalModule (fsLit "GHC.Internal.PrimopWrappers")+gHC_INTERNAL_TUPLE = mkGhcInternalModule (fsLit "GHC.Internal.Tuple")  gHC_INTERNAL_CONTROL_MONAD_ZIP :: Module gHC_INTERNAL_CONTROL_MONAD_ZIP  = mkGhcInternalModule (fsLit "GHC.Internal.Control.Monad.Zip")  gHC_INTERNAL_NUM_INTEGER, gHC_INTERNAL_NUM_NATURAL, gHC_INTERNAL_NUM_BIGNAT :: Module-gHC_INTERNAL_NUM_INTEGER            = mkBignumModule (fsLit "GHC.Num.Integer")-gHC_INTERNAL_NUM_NATURAL            = mkBignumModule (fsLit "GHC.Num.Natural")-gHC_INTERNAL_NUM_BIGNAT             = mkBignumModule (fsLit "GHC.Num.BigNat")+gHC_INTERNAL_NUM_INTEGER            = mkGhcInternalModule (fsLit "GHC.Internal.Bignum.Integer")+gHC_INTERNAL_NUM_NATURAL            = mkGhcInternalModule (fsLit "GHC.Internal.Bignum.Natural")+gHC_INTERNAL_NUM_BIGNAT             = mkGhcInternalModule (fsLit "GHC.Internal.Bignum.BigNat")  gHC_INTERNAL_BASE, gHC_INTERNAL_ENUM,     gHC_INTERNAL_GHCI, gHC_INTERNAL_GHCI_HELPERS, gHC_CSTRING, gHC_INTERNAL_DATA_STRING,@@ -590,7 +580,8 @@     gHC_INTERNAL_ARROW, gHC_INTERNAL_DESUGAR, gHC_INTERNAL_RANDOM, gHC_INTERNAL_EXTS, gHC_INTERNAL_IS_LIST,     gHC_INTERNAL_CONTROL_EXCEPTION_BASE, gHC_INTERNAL_TYPEERROR, gHC_INTERNAL_TYPELITS, gHC_INTERNAL_TYPELITS_INTERNAL,     gHC_INTERNAL_TYPENATS, gHC_INTERNAL_TYPENATS_INTERNAL,-    gHC_INTERNAL_DATA_COERCE, gHC_INTERNAL_DEBUG_TRACE, gHC_INTERNAL_UNSAFE_COERCE, gHC_INTERNAL_FOREIGN_C_CONSTPTR :: Module+    gHC_INTERNAL_DATA_COERCE, gHC_INTERNAL_DEBUG_TRACE, gHC_INTERNAL_UNSAFE_COERCE, gHC_INTERNAL_FOREIGN_C_CONSTPTR,+    gHC_INTERNAL_JS_PRIM, gHC_INTERNAL_WASM_PRIM_TYPES :: Module gHC_INTERNAL_BASE                   = mkGhcInternalModule (fsLit "GHC.Internal.Base") gHC_INTERNAL_ENUM                   = mkGhcInternalModule (fsLit "GHC.Internal.Enum") gHC_INTERNAL_GHCI                   = mkGhcInternalModule (fsLit "GHC.Internal.GHCi")@@ -633,7 +624,7 @@ gHC_INTERNAL_EXTS                   = mkGhcInternalModule (fsLit "GHC.Internal.Exts") gHC_INTERNAL_IS_LIST                = mkGhcInternalModule (fsLit "GHC.Internal.IsList") gHC_INTERNAL_CONTROL_EXCEPTION_BASE = mkGhcInternalModule (fsLit "GHC.Internal.Control.Exception.Base")-gHC_INTERNAL_EXCEPTION_CONTEXT = mkGhcInternalModule (fsLit "GHC.Internal.Exception.Context")+gHC_INTERNAL_EXCEPTION_CONTEXT      = mkGhcInternalModule (fsLit "GHC.Internal.Exception.Context") gHC_INTERNAL_GENERICS               = mkGhcInternalModule (fsLit "GHC.Internal.Generics") gHC_INTERNAL_TYPEERROR              = mkGhcInternalModule (fsLit "GHC.Internal.TypeError") gHC_INTERNAL_TYPELITS               = mkGhcInternalModule (fsLit "GHC.Internal.TypeLits")@@ -644,6 +635,8 @@ gHC_INTERNAL_DEBUG_TRACE            = mkGhcInternalModule (fsLit "GHC.Internal.Debug.Trace") gHC_INTERNAL_UNSAFE_COERCE          = mkGhcInternalModule (fsLit "GHC.Internal.Unsafe.Coerce") gHC_INTERNAL_FOREIGN_C_CONSTPTR     = mkGhcInternalModule (fsLit "GHC.Internal.Foreign.C.ConstPtr")+gHC_INTERNAL_JS_PRIM                = mkGhcInternalModule (fsLit "GHC.Internal.JS.Prim")+gHC_INTERNAL_WASM_PRIM_TYPES        = mkGhcInternalModule (fsLit "GHC.Internal.Wasm.Prim.Types")  gHC_INTERNAL_SRCLOC :: Module gHC_INTERNAL_SRCLOC = mkGhcInternalModule (fsLit "GHC.Internal.SrcLoc")@@ -678,12 +671,6 @@ pRELUDE_NAME   = mkModuleNameFS (fsLit "Prelude") mAIN_NAME      = mkModuleNameFS (fsLit "Main") -mkPrimModule :: FastString -> Module-mkPrimModule m = mkModule primUnit (mkModuleNameFS m)--mkBignumModule :: FastString -> Module-mkBignumModule m = mkModule bignumUnit (mkModuleNameFS m)- mkGhcInternalModule :: FastString -> Module mkGhcInternalModule m = mkGhcInternalModule_ (mkModuleNameFS m) @@ -1676,8 +1663,11 @@     tcQual gHC_INTERNAL_FOREIGN_C_CONSTPTR (fsLit "ConstPtr") constPtrTyConKey  jsvalTyConName :: Name-jsvalTyConName = tcQual (mkGhcInternalModule (fsLit "GHC.Internal.Wasm.Prim.Types")) (fsLit "JSVal") jsvalTyConKey+jsvalTyConName = tcQual gHC_INTERNAL_WASM_PRIM_TYPES (fsLit "JSVal") jsvalTyConKey +unsafeUnpackJSStringUtf8ShShName :: Name+unsafeUnpackJSStringUtf8ShShName = varQual gHC_INTERNAL_JS_PRIM (fsLit "unsafeUnpackJSStringUtf8##") unsafeUnpackJSStringUtf8ShShKey+ {- ************************************************************************ *                                                                      *@@ -1822,7 +1812,7 @@     weakPrimTyConKey, mutableArrayPrimTyConKey,     mutableByteArrayPrimTyConKey, orderingTyConKey, mVarPrimTyConKey,     ratioTyConKey, rationalTyConKey, realWorldTyConKey, stablePtrPrimTyConKey,-    stablePtrTyConKey, eqTyConKey, heqTyConKey, ioPortPrimTyConKey,+    stablePtrTyConKey, eqTyConKey, heqTyConKey,     smallArrayPrimTyConKey, smallMutableArrayPrimTyConKey,     stringTyConKey,     ccArrowTyConKey, ctArrowTyConKey, tcArrowTyConKey :: Unique@@ -1859,7 +1849,7 @@ mutableByteArrayPrimTyConKey            = mkPreludeTyConUnique 31 orderingTyConKey                        = mkPreludeTyConUnique 32 mVarPrimTyConKey                        = mkPreludeTyConUnique 33-ioPortPrimTyConKey                      = mkPreludeTyConUnique 34+-- ioPortPrimTyConKey (34) was killed ratioTyConKey                           = mkPreludeTyConUnique 35 rationalTyConKey                        = mkPreludeTyConUnique 36 realWorldTyConKey                       = mkPreludeTyConUnique 37@@ -2082,6 +2072,7 @@   , typeNatLogTyFamNameKey   , typeConsSymbolTyFamNameKey, typeUnconsSymbolTyFamNameKey   , typeCharToNatTyFamNameKey, typeNatToCharTyFamNameKey+  , exceptionContextTyConKey, unsafeUnpackJSStringUtf8ShShKey   :: Unique typeSymbolKindConNameKey  = mkPreludeTyConUnique 400 typeCharKindConNameKey    = mkPreludeTyConUnique 401@@ -2104,8 +2095,9 @@  jsvalTyConKey = mkPreludeTyConUnique 418 -exceptionContextTyConKey :: Unique exceptionContextTyConKey = mkPreludeTyConUnique 420++unsafeUnpackJSStringUtf8ShShKey  = mkPreludeMiscIdUnique 805  {- ************************************************************************
GHC/Builtin/Names/TH.hs view
@@ -75,7 +75,9 @@     funDName, valDName, dataDName, newtypeDName, typeDataDName, tySynDName,     classDName, instanceWithOverlapDName,     standaloneDerivWithStrategyDName, sigDName, kiSigDName, forImpDName,-    pragInlDName, pragOpaqueDName, pragSpecDName, pragSpecInlDName, pragSpecInstDName,+    pragInlDName, pragOpaqueDName,+    pragSpecDName, pragSpecInlDName, pragSpecEDName, pragSpecInlEDName,+    pragSpecInstDName,     pragRuleDName, pragCompleteDName, pragAnnDName, pragSCCFunDName, pragSCCFunNamedDName,     defaultSigDName, defaultDName,     dataFamilyDName, openTypeFamilyDName, closedTypeFamilyDName,@@ -177,7 +179,7 @@     modNameTyConName,      -- Quasiquoting-    quoteDecName, quoteTypeName, quoteExpName, quotePatName]+    quasiQuoterTyConName, quoteDecName, quoteTypeName, quoteExpName, quotePatName]  thSyn, thLib, qqLib, liftLib :: Module thSyn = mkTHModule (fsLit "GHC.Internal.TH.Syntax")@@ -214,7 +216,7 @@     fieldPatTyConName, expTyConName, decTyConName, typeTyConName,     matchTyConName, clauseTyConName, funDepTyConName, predTyConName,     codeTyConName, injAnnTyConName, overlapTyConName, decsTyConName,-    modNameTyConName :: Name+    modNameTyConName, quasiQuoterTyConName :: Name qTyConName             = thTc (fsLit "Q")              qTyConKey nameTyConName          = thTc (fsLit "Name")           nameTyConKey fieldExpTyConName      = thTc (fsLit "FieldExp")       fieldExpTyConKey@@ -232,6 +234,7 @@ injAnnTyConName        = thTc (fsLit "InjectivityAnn") injAnnTyConKey overlapTyConName       = thTc (fsLit "Overlap")        overlapTyConKey modNameTyConName       = thTc (fsLit "ModName")        modNameTyConKey+quasiQuoterTyConName   = mk_known_key_name tcName qqLib (fsLit "QuasiQuoter") quasiQuoterTyConKey  returnQName, bindQName, sequenceQName, newNameName, liftName,     mkNameName, mkNameG_vName, mkNameG_fldName, mkNameG_dName, mkNameG_tcName,@@ -386,7 +389,8 @@ -- data Dec = ... funDName, valDName, dataDName, newtypeDName, typeDataDName, tySynDName, classDName,     instanceWithOverlapDName, sigDName, kiSigDName, forImpDName, pragInlDName,-    pragSpecDName, pragSpecInlDName, pragSpecInstDName, pragRuleDName,+    pragSpecDName, pragSpecInlDName, pragSpecEDName, pragSpecInlEDName,+    pragSpecInstDName, pragRuleDName,     pragAnnDName, pragSCCFunDName, pragSCCFunNamedDName,     standaloneDerivWithStrategyDName, defaultSigDName, defaultDName,     dataInstDName, newtypeInstDName, tySynInstDName, dataFamilyDName,@@ -411,6 +415,8 @@ pragOpaqueDName                  = libFun (fsLit "pragOpaqueD")                  pragOpaqueDIdKey pragSpecDName                    = libFun (fsLit "pragSpecD")                    pragSpecDIdKey pragSpecInlDName                 = libFun (fsLit "pragSpecInlD")                 pragSpecInlDIdKey+pragSpecEDName                   = libFun (fsLit "pragSpecED")                   pragSpecEDIdKey+pragSpecInlEDName                = libFun (fsLit "pragSpecInlED")                pragSpecInlEDIdKey pragSpecInstDName                = libFun (fsLit "pragSpecInstD")                pragSpecInstDIdKey pragRuleDName                    = libFun (fsLit "pragRuleD")                    pragRuleDIdKey pragCompleteDName                = libFun (fsLit "pragCompleteD")                pragCompleteDIdKey@@ -712,7 +718,7 @@     predQTyConKey, decsQTyConKey, ruleBndrTyConKey, tySynEqnTyConKey,     roleTyConKey, codeTyConKey, injAnnTyConKey, kindTyConKey,     overlapTyConKey, derivClauseTyConKey, derivStrategyTyConKey, decsTyConKey,-    modNameTyConKey  :: Unique+    modNameTyConKey, quasiQuoterTyConKey :: Unique expTyConKey             = mkPreludeTyConUnique 200 matchTyConKey           = mkPreludeTyConUnique 201 clauseTyConKey          = mkPreludeTyConUnique 202@@ -748,6 +754,7 @@ codeTyConKey            = mkPreludeTyConUnique 238 modNameTyConKey         = mkPreludeTyConUnique 239 tyVarBndrVisTyConKey    = mkPreludeTyConUnique 240+quasiQuoterTyConKey     = mkPreludeTyConUnique 241  {- ********************************************************************* *                                                                      *@@ -962,7 +969,8 @@     infixLWithSpecDIdKey, infixRWithSpecDIdKey, infixNWithSpecDIdKey,     roleAnnotDIdKey, patSynDIdKey, patSynSigDIdKey, pragCompleteDIdKey,     implicitParamBindDIdKey, kiSigDIdKey, defaultDIdKey, pragOpaqueDIdKey,-    typeDataDIdKey, pragSCCFunDKey, pragSCCFunNamedDKey :: Unique+    typeDataDIdKey, pragSCCFunDKey, pragSCCFunNamedDKey,+    pragSpecEDIdKey, pragSpecInlEDIdKey :: Unique funDIdKey                         = mkPreludeMiscIdUnique 320 valDIdKey                         = mkPreludeMiscIdUnique 321 dataDIdKey                        = mkPreludeMiscIdUnique 322@@ -1001,6 +1009,8 @@ typeDataDIdKey                    = mkPreludeMiscIdUnique 355 pragSCCFunDKey                    = mkPreludeMiscIdUnique 356 pragSCCFunNamedDKey               = mkPreludeMiscIdUnique 357+pragSpecEDIdKey                   = mkPreludeMiscIdUnique 358+pragSpecInlEDIdKey                = mkPreludeMiscIdUnique 359  -- type Cxt = ... cxtIdKey :: Unique
GHC/Builtin/PrimOps/Ids.hs view
@@ -16,6 +16,7 @@ import {-# SOURCE #-} GHC.Core.Opt.ConstantFold (primOpRules) import GHC.Core.TyCo.Rep ( scaledThing ) import GHC.Core.Type+import GHC.Core.Predicate( tyCoVarsOfTypeWellScoped ) import GHC.Core.FVs (mkRuleInfo)  import GHC.Builtin.PrimOps@@ -98,7 +99,7 @@       | tv `elem` [ runtimeRep1TyVar, runtimeRep2TyVar, runtimeRep3TyVar                   , levity1TyVar, levity2TyVar ]       = listToMaybe $-          mapMaybe (\ (i,arg) -> Argument i <$> positiveKindPos_maybe tv arg)+          mapMaybe (\ (i,arg) -> mkArgPos i <$> positiveKindPos_maybe tv arg)             (zip [1..] arg_tys)       | otherwise       = Nothing@@ -123,7 +124,7 @@       )   where     recur (pos, scaled_ty)-      = Argument pos <$> positiveKindPos_maybe tv (scaledThing scaled_ty)+      = mkArgPos pos <$> positiveKindPos_maybe tv (scaledThing scaled_ty)     -- (assumes we don't have any function types nested inside other types)  -- | Does this type variable appear in a kind in a positive position in the@@ -144,7 +145,7 @@       )   where     recur (pos, scaled_ty)-      = Argument pos <$> negativeKindPos_maybe tv (scaledThing scaled_ty)+      = mkArgPos pos <$> negativeKindPos_maybe tv (scaledThing scaled_ty)     -- (assumes we don't have any function types nested inside other types)     finish ty       | tv `elemVarSet` tyCoVarsOfType (typeKind ty)
GHC/Builtin/Types.hs view
@@ -20,8 +20,9 @@         mkWiredInIdName,    -- used in GHC.Types.Id.Make          -- * All wired in things-        wiredInTyCons, isBuiltInOcc_maybe, isTupleTyOcc_maybe, isSumTyOcc_maybe,-        isPunOcc_maybe,+        wiredInTyCons, isBuiltInOcc, isBuiltInOcc_maybe,+        isTupleTyOrigName_maybe, isSumTyOrigName_maybe,+        isInfiniteFamilyOrigName_maybe,          -- * Bool         boolTy, boolTyCon, boolTyCon_RDR, boolTyConName,@@ -82,12 +83,12 @@         pairTyCon, mkPromotedPairTy, isPromotedPairType,         unboxedUnitTy,         unboxedUnitTyCon, unboxedUnitDataCon,+        unboxedSoloTyCon, unboxedSoloTyConName, unboxedSoloDataConName,         unboxedTupleKind, unboxedSumKind,-        filterCTuple, mkConstraintTupleTy,+        mkConstraintTupleTy,          -- ** Constraint tuples         cTupleTyCon, cTupleTyConName, cTupleTyConNames, isCTupleTyConName,-        cTupleTyConNameArity_maybe,         cTupleDataCon, cTupleDataConName, cTupleDataConNames,         cTupleSelId, cTupleSelIdName, @@ -99,6 +100,7 @@          -- * Sums         mkSumTy, sumTyCon, sumDataCon,+        unboxedSumTyConName, unboxedSumDataConName,          -- * Kinds         typeSymbolKindCon, typeSymbolKind,@@ -206,6 +208,7 @@ import GHC.Settings.Constants ( mAX_TUPLE_SIZE, mAX_CTUPLE_SIZE, mAX_SUM_SIZE ) import GHC.Unit.Module        ( Module ) +import Data.Maybe import Data.Array import GHC.Data.FastString import GHC.Data.BooleanFormula ( mkAnd )@@ -214,13 +217,14 @@ import GHC.Utils.Misc import GHC.Utils.Panic -import qualified Data.ByteString.Char8 as BS+import qualified Data.ByteString.Short as SBS+import qualified Data.ByteString.Short.Internal as SBS (unsafeIndex)  import Data.Foldable-import Data.List        ( elemIndex, intersperse )+import Data.List        ( intersperse ) import Numeric          ( showInt ) -import Data.Char (ord, isDigit)+import Data.Word (Word8) import Control.Applicative ((<|>))  alpha_tyvar :: [TyVar]@@ -278,38 +282,22 @@ -}  --- This list is used only to define GHC.Builtin.Utils.wiredInThings. That in turn+-- This list is used only to define GHC.Builtin.Utils.knownKeyNames. That in turn -- is used to initialise the name environment carried around by the renamer. -- This means that if we look up the name of a TyCon (or its implicit binders) -- that occurs in this list that name will be assigned the wired-in key we -- define here. -- -- Because of their infinite nature, this list excludes---   * tuples, including boxed, unboxed and constraint tuples----       (mkTupleTyCon, unitTyCon, pairTyCon)---   * unboxed sums (sumTyCon)+--   * Tuples of all sorts (boxed, unboxed, constraint) (mkTupleTyCon)+--   * Unboxed sums (sumTyCon) -- See Note [Infinite families of known-key names] in GHC.Builtin.Names -- -- See also Note [Known-key names] wiredInTyCons :: [TyCon]  wiredInTyCons = map (dataConTyCon . snd) boxingDataCons-             ++ [ -- Units are not treated like other tuples, because they-                  -- are defined in GHC.Base, and there's only a few of them. We-                  -- put them in wiredInTyCons so that they will pre-populate-                  -- the name cache, so the parser in isBuiltInOcc_maybe doesn't-                  -- need to look out for them.-                  unitTyCon-                , unboxedUnitTyCon--                -- Solo (i.e., the boxed 1-tuple) is also not treated-                -- like other tuples (i.e. we /do/ include it here),-                -- since it does not use special syntax like other tuples-                -- See Note [One-tuples] (Wrinkle: Make boxed one-tuple names-                -- have known keys) in GHC.Builtin.Types.-                , soloTyCon--                , anyTyCon+             ++ [ anyTyCon                 , zonkAnyTyCon                 , boolTyCon                 , charTyCon@@ -332,6 +320,7 @@                 , constraintKindTyCon                 , liftedTypeKindTyCon                 , unliftedTypeKindTyCon+                , unrestrictedFunTyCon                 , multiplicityTyCon                 , naturalTyCon                 , integerTyCon@@ -521,6 +510,17 @@      See examples in ghc-prim:GHC.Types +(Any8) Warning about unused bindings of type `Any` and `ZonkAny` are suppressed,+    following the same rationale of supressing warning about the unit type.++    For example, consider (#25895):++     do { forever (return ()); blah }++    where forever :: forall a b. IO a -> IO b+    Nothing constrains `b`, so it will be instantiates with `Any` or `ZonkAny`.+    But we certainly don't want to complain about a discarded do-binding.+ The Any tycon used to be quite magic, but we have since been able to implement it merely with an empty kind polymorphic type family. See #10886 for a bit of history.@@ -709,10 +709,12 @@     -- See Note [Constructor tag allocation] and #14657     data_con = mkDataCon dc_name declared_infix prom_info                 (map (const no_bang) arg_tys)+                (map (const HsLazy) arg_tys)+                (map (const NotMarkedStrict) arg_tys)                 []      -- No labelled fields                 tyvars ex_tyvars                 conc_tyvars-                (mkTyVarBinders SpecifiedSpec user_tyvars)+                (mkTyVarBinders Specified user_tyvars)                 []      -- No equality spec                 theta                 arg_tys (mkTyConApp tycon (mkTyVarTys tyvars))@@ -723,7 +725,7 @@                 (mkDataConWorkId wrk_name data_con)                 NoDataConRep    -- Wired-in types are too simple to need wrappers -    no_bang = mkHsSrcBang NoSourceText NoSrcUnpack NoSrcStrict+    no_bang = HsSrcBang NoSourceText NoSrcUnpack NoSrcStrict      wrk_name = mkDataConWorkerName data_con wrk_key @@ -806,10 +808,8 @@   E.g. tupleTyCon has a Boxity argument  * When looking up an OccName in the original-name cache-  (GHC.Iface.Env.lookupOrigNameCache), we spot the tuple OccName to make sure-  we get the right wired-in name.  This guy can't tell the difference-  between BoxedTuple and ConstraintTuple (same OccName!), so tuples-  are not serialised into interface files using OccNames at all.+  (GHC.Types.Name.Cache.lookupOrigNameCache), we spot the tuple OccName to make+  sure we get the right wired-in name.  * Serialization to interface files works via the usual mechanism for known-key   things: instead of serializing the OccName we just serialize the key. During@@ -849,181 +849,467 @@ There is nothing special about one-tuples in Core; in particular, they have no custom pretty-printing, just using `Solo`. -Note that there is *not* a unary constraint tuple, unlike for other forms of-tuples. See [Ignore unary constraint tuples] in GHC.Tc.Gen.HsType for more-details.- See also Note [Flattening one-tuples] in GHC.Core.Make and Note [Don't flatten tuples from HsSyn] in GHC.Core.Make. --------- Wrinkle: Make boxed one-tuple names have known keys------+Note [isBuiltInOcc_maybe]+~~~~~~~~~~~~~~~~~~~~~~~~~+`isBuiltInOcc_maybe` matches and resolves names that are occurrences of built-in+syntax, i.e. unqualified names that can be unambiguously resolved even without+knowing what's currently in scope (such names also can't be imported, exported,+or redefined in another module).+More on that in Note [Built-in syntax and the OrigNameCache] in GHC.Types.Name.Cache. -We make boxed one-tuple names have known keys so that `data Solo a = MkSolo a`,-defined in GHC.Tuple, will be used when one-tuples are spliced in through-Template Haskell. This program (from #18097) crucially relies on this:+In GHC, there are two use cases for `isBuiltInOcc_maybe`: -  case $( tupE [ [| "ok" |] ] ) of MkSolo x -> putStrLn x+1. Making TH's `mkName` work with built-in syntax,+   e.g. $(conT (mkName "[]")) is the same as [] -Unless Solo has a known key, the type of `$( tupE [ [| "ok" |] ] )` (an-ExplicitTuple of length 1) will not match the type of Solo (an ordinary-data constructor used in a pattern). Making Solo known-key allows GHC to make-this connection.+2. Detecting bulit-in syntax in `infix` declarations,+   e.g. users can't write `infixl 6 :` (#15233) -Unlike Solo, every other tuple is /not/ known-key-(see Note [Infinite families of known-key names] in GHC.Builtin.Names). The-main reason for this exception is that other tuples are written with special-syntax, and as a result, they are renamed using a special `isBuiltInOcc_maybe`-function (see Note [Built-in syntax and the OrigNameCache] in GHC.Types.Name.Cache).-In contrast, Solo is just an ordinary data type with no special syntax, so it-doesn't really make sense to handle it in `isBuiltInOcc_maybe`. Making Solo-known-key is the next-best way to teach the internals of the compiler about it.+The parser takes a shortcut and produces Exact RdrNames directly,+so it doesn't need to match on an OccName with isBuiltInOcc_maybe.++And here are the properties of `isBuiltInOcc_maybe`:++* The set of names recognized by `isBuiltInOcc_maybe` is essentialy the+  same as the set of names that the parser resolves to Exact RdrNames,+  e.g. "[]", "(,)", or "->".++  We could leave it at that, but we also recognize unboxed sum syntax+  "(#|#)" even though the parser can't handle it. This makes TH's `mkName`+  more permissive than the parser.++* The namespace of the input OccName is treated as a hint, not a+  requirement. For example,++    mkOccName dataName  ":"          maps to  consDataConName+    mkOccName tcClsName ":"   /also/ maps to  consDataConName++  The rationale behind this is that with DataKind or RequiredTypeArguments+  we may get an OccName with the wrong namespace and need to fallback to the+  other one.++* There is a `listTuplePuns :: Bool` parameter to account for the+  ListTuplePuns extension. It has /no/ effect on whether the predicate+  matches (i.e. if the result is Just or Nothing), but it can influence+  which name is returned (TyCon name or DataCon name). For example,++    isBuiltInOcc_maybe False (mkOccName dataName  "[]")  ==  Just nilDataConName+    isBuiltInOcc_maybe False (mkOccName tcClsName "[]")  ==  Just nilDataConName+    isBuiltInOcc_maybe True  (mkOccName dataName  "[]")  ==  Just nilDataConName+    isBuiltInOcc_maybe True  (mkOccName tcClsName "[]")  ==  Just listTyConName++* There is no `Module` parameter because we are matching unqualified+  occurrences of built-in names. It is illegal to qualify built-in syntax,+  e.g. GHC.Types.(,) is a parse error.++* The /input/ to `isBuiltInOcc_maybe` needs to be built-in syntax for the+  predicate to match, but the /output/ is not necessarily built-in syntax.+  For example,++    1) input:   mkTcOcc "[]"          -- built-in syntax+       output:  Just listTyConName    -- user syntax (GHC.Types.List)++    2) input:   mkDataOcc "[]"        -- built-in syntax+       output:  Just nilDataConName   -- built-in syntax []++    3) input:   mkTcOcc "List"        -- user syntax+       output:  Nothing               -- no match++    4) input:   mkTcOcc "(,)"                       -- built-in syntax+       output:  Just (tupleTyConName BoxedTuple 2)  -- user syntax (GHC.Types.Tuple2)++    5) input:   mkTcOcc "(#|#)"               -- built-in syntax+       output:  Just (unboxedSumTyConName 2)  -- user syntax (GHC.Types.Sum2#)++  Therefore, `GHC.Types.Name.isBuiltInSyntax` may or may not hold for the name+  returned by `isBuiltInOcc_maybe`. -} --- | Built-in syntax isn't "in scope" so these OccNames map to wired-in Names--- with BuiltInSyntax. However, this should only be necessary while resolving--- names produced by Template Haskell splices since we take care to encode--- built-in syntax names specially in interface files. See--- Note [Symbol table representation of names] in GHC.Iface.Binary.+-- | Match on built-in syntax as it occurs at use sites.+-- See Note [isBuiltInOcc_maybe]+isBuiltInOcc_maybe :: Bool -> OccName -> Maybe Name+isBuiltInOcc_maybe listTuplePuns occ+  | fs == "->" = Just unrestrictedFunTyConName+  | fs == "[]" = Just (pun listTyConName nilDataConName)+  | fs == ":"  = Just consDataConName+  | Just n <- (is_boxed_tup_syntax fs) = Just (tup_name Boxed n)+  | Just n <- (is_unboxed_tup_syntax fs) = Just (tup_name Unboxed n)+  | Just n <- (is_unboxed_sum_type_syntax fs) = Just (unboxedSumTyConName n)+  | Just (k, n) <- (is_unboxed_sum_data_syntax fs) = Just (unboxedSumDataConName k n)+  | otherwise = Nothing+  where+    fs = occNameFS occ+    ns = occNameSpace occ++    pun :: Name -> Name -> Name+    pun p n+      | listTuplePuns, isTcClsNameSpace ns = p+      | otherwise = n++    tup_name :: Boxity -> Arity -> Name+    tup_name boxity arity+      = pun (tyConName   (tupleTyCon   boxity arity))+            (dataConName (tupleDataCon boxity arity))++-- | Check if the OccName is an occurrence of built-in syntax. ----- Moreover, there is no need to include names of things that the user can't--- write (e.g. type representation bindings like $tc(,,,)).-isBuiltInOcc_maybe :: OccName -> Maybe Name-isBuiltInOcc_maybe occ =-    case name of-      "[]" -> Just $ choose_ns listTyConName nilDataConName-      ":"    -> Just consDataConName+-- This is a variant of `isBuiltInOcc_maybe` that returns a `Bool`.+-- See Note [isBuiltInOcc_maybe]+--+-- `isBuiltInOcc` holds for:+--   * function arrow `->`+--   * list syntax `[]`, `:`+--   * boxed tuple syntax `()`, `(,)`, `(,,)`, `(,,,)`, ...+--   * unboxed tuple syntax `(##)`, `(#,#)`, `(#,,#)`, ...+--   * unboxed sum type syntax `(#|#)`, `(#||#)`, `(#|||#)`, ...+--   * unboxed sum data syntax `(#_|#)`, `(#|_#)`, `(#_||#), ...+isBuiltInOcc :: OccName -> Bool+isBuiltInOcc = isJust . isBuiltInOcc_maybe listTuplePuns+  where+    listTuplePuns = False+      -- True/False here is inconsequential because ListTuplePuns doesn't affect+      -- whether isBuiltInOcc_maybe matches. See Note [isBuiltInOcc_maybe] -      -- function tycon-      "->"  -> Just unrestrictedFunTyConName+-- Match on original names of infinite families (tuples and sums).+-- See Note [Infinite families of known-key names] in GHC.Builtin.Names+isInfiniteFamilyOrigName_maybe :: Module -> OccName -> Maybe Name+isInfiniteFamilyOrigName_maybe mod occ = -      -- tuple data/tycon-      -- We deliberately exclude Solo (the boxed 1-tuple).-      -- See Note [One-tuples] (Wrinkle: Make boxed one-tuple names have known keys)-      "()"    -> Just $ tup_name Boxed 0-      _ | Just rest <- "(" `BS.stripPrefix` name-        , (commas, rest') <- BS.span (==',') rest-        , ")" <- rest'-             -> Just $ tup_name Boxed (1+BS.length commas)+  -- Tuples, boxed and unboxed+  isTupleTyOrigName_maybe mod occ+  <|> isTupleDataOrigName_maybe mod occ -      -- unboxed tuple data/tycon-      "(##)"  -> Just $ tup_name Unboxed 0-      "(# #)" -> Just $ tup_name Unboxed 1-      _ | Just rest <- "(#" `BS.stripPrefix` name-        , (commas, rest') <- BS.span (==',') rest-        , "#)" <- rest'-             -> Just $ tup_name Unboxed (1+BS.length commas)+  -- Constraint tuples+  <|> isCTupleOrigName_maybe mod occ -      -- unboxed sum tycon-      _ | Just rest <- "(#" `BS.stripPrefix` name-        , (nb_pipes, rest') <- span_pipes rest-        , "#)" <- rest'-             -> Just $ tyConName $ sumTyCon (1+nb_pipes)+  -- Unboxed sums+  <|> isSumTyOrigName_maybe mod occ+  <|> isSumDataOrigName_maybe mod occ -      -- unboxed sum datacon-      _ | Just rest <- "(#" `BS.stripPrefix` name-        , (nb_pipes1, rest') <- span_pipes rest-        , Just rest'' <- "_" `BS.stripPrefix` rest'-        , (nb_pipes2, rest''') <- span_pipes rest''-        , "#)" <- rest'''-             -> let arity = nb_pipes1 + nb_pipes2 + 1-                    alt = nb_pipes1 + 1-                in Just $ dataConName $ sumDataCon alt arity+-- Check if the string has form "()", "(,)", "(,,)", etc,+-- and return the corresponding tuple arity.+is_boxed_tup_syntax :: FastString -> Maybe Arity+is_boxed_tup_syntax fs+  | fs == "()" = Just 0+  | n >= 2+  , SBS.unsafeIndex sbs 0     == 40  -- ord '('+  , SBS.unsafeIndex sbs (n-1) == 41  -- ord ')'+  , sbs_all sbs 1 (n-1)          44  -- ord ','+  = Just (n-1)+  where+    n   = SBS.length sbs                   -- O(1)+    sbs = fastStringToShortByteString fs   -- O(1) field access+is_boxed_tup_syntax _ = Nothing -      _ -> Nothing+-- Check if the string has form "(##)", "(# #)", (#,#)", "(#,,#)", etc,+-- and return the corresponding tuple arity.+is_unboxed_tup_syntax :: FastString -> Maybe Arity+is_unboxed_tup_syntax fs+  | fs == "(##)"  = Just 0+  | fs == "(# #)" = Just 1+  | sbs_unboxed sbs+  , sbs_all sbs 2 (n-2) 44  -- ord ','+  = Just (n-3)   where-    name = bytesFS $ occNameFS occ+    n   = SBS.length sbs                   -- O(1)+    sbs = fastStringToShortByteString fs   -- O(1) field access+is_unboxed_tup_syntax _ = Nothing -    span_pipes :: BS.ByteString -> (Int, BS.ByteString)-    span_pipes = go 0-      where-        go nb_pipes bs = case BS.uncons bs of-          Just ('|',rest) -> go (nb_pipes + 1) rest-          Just (' ',rest) -> go nb_pipes       rest-          _               -> (nb_pipes, bs)+-- Check if the string has form "(#|#)", "(#||#)", (#|||#)", etc,+-- and return the corresponding sum arity.+is_unboxed_sum_type_syntax :: FastString -> Maybe Arity+is_unboxed_sum_type_syntax fs+  | sbs_unboxed sbs+  , Just k <- sbs_pipes sbs 2 (n-2)+  , k > 0+  = Just (k+1)+  where+    n   = SBS.length sbs                   -- O(1)+    sbs = fastStringToShortByteString fs   -- O(1) field access+is_unboxed_sum_type_syntax _ = Nothing -    choose_ns :: Name -> Name -> Name-    choose_ns tc dc-      | isTcClsNameSpace ns   = tc-      | isDataConNameSpace ns = dc-      | otherwise             = pprPanic "tup_name" (ppr occ <+> parens (pprNameSpace ns))-      where ns = occNameSpace occ+-- Check if the string has form "(#_|#)", "(#_||#)", (#|_|#)", etc,+-- and return the corresponding sum tag and sum arity.+is_unboxed_sum_data_syntax :: FastString -> Maybe (ConTag, Arity)+is_unboxed_sum_data_syntax fs+  | sbs_unboxed sbs+  , Just u <- SBS.elemIndex 95 sbs        -- ord '_'+  , Just k1 <- sbs_pipes sbs 2 u          -- pipes to the left  of '_'+  , Just k2 <- sbs_pipes sbs (u+1) (n-2)  -- pipes to the right of '_'+  = Just (k1+1, k1+k2+1)+  where+    n   = SBS.length sbs                   -- O(1)+    sbs = fastStringToShortByteString fs   -- O(1) field access+is_unboxed_sum_data_syntax _ = Nothing -    tup_name boxity arity-      = choose_ns (getName (tupleTyCon   boxity arity))-                  (getName (tupleDataCon boxity arity))+-- (sbs_all sbs i n x) checks if all bytes in the slice [i..n) are equal to x.+sbs_all :: SBS.ShortByteString -> Int -> Int -> Word8 -> Bool+sbs_all !sbs !i !n !x+  | i < n     = SBS.unsafeIndex sbs i == x && sbs_all sbs (i+1) n x+  | otherwise = True -isTupleTyOcc_maybe :: Module -> OccName -> Maybe Name-isTupleTyOcc_maybe mod occ-  | mod == gHC_INTERNAL_TUPLE || mod == gHC_TYPES-  = match_occ+-- (sbs_pipes sbs i n) checks if all bytes in the slice [i..n) are equal to '|'+-- or ' ', and returns the number of encountered '|'.+sbs_pipes :: SBS.ShortByteString -> Int -> Int -> Maybe Int+sbs_pipes !sbs = go 0   where-    match_occ+    go :: Int -> Int -> Int -> Maybe Int+    go !k !i !n+      | i < n =+        if | SBS.unsafeIndex sbs i == 124 -> go (k+1) (i+1) n -- ord '|'+           | SBS.unsafeIndex sbs i == 32  -> go k     (i+1) n -- ord ' '+           | otherwise                    -> Nothing+      | otherwise = Just k++-- (sbs_unboxed sbs) checks if the string starts with "(#" and ends with "#)".+sbs_unboxed :: SBS.ShortByteString -> Bool+sbs_unboxed !sbs =+  n >= 4 && SBS.unsafeIndex sbs 0     == 40  -- ord '('+         && SBS.unsafeIndex sbs 1     == 35  -- ord '#'+         && SBS.unsafeIndex sbs (n-2) == 35  -- ord '#'+         && SBS.unsafeIndex sbs (n-1) == 41  -- ord ')'+  where+    n = SBS.length sbs -- O(1)++-- (sbs_Sum sbs) checks if the string has form "SumN#" or "SumNM#",+-- where "N" or "NM" is a decimal numeral in the [2..mAX_SUM_SIZE] range.+sbs_Sum :: SBS.ShortByteString -> Maybe Arity+sbs_Sum !sbs+  | n >= 3 && SBS.unsafeIndex sbs 0 == 83   -- ord 'S'+           && SBS.unsafeIndex sbs 1 == 117  -- ord 'u'+           && SBS.unsafeIndex sbs 2 == 109  -- ord 'm'+  , Just (Unboxed, arity) <- sbs_arity_boxity sbs 3+  , arity >= 2, arity <= mAX_SUM_SIZE+  = Just arity+  | otherwise = Nothing+  where+    n = SBS.length sbs -- O(1)++-- (sbs_Tuple sbs) checks if the string has form "TupleN", "TupleNM", "TupleN#" or "TupleNM#",+-- where "N" or "NM" is a decimal numeral in the [2..mAX_TUPLE_SIZE] range.+sbs_Tuple :: SBS.ShortByteString -> Maybe (Boxity, Arity)+sbs_Tuple !sbs+  | n >= 5 && SBS.unsafeIndex sbs 0 == 84   -- ord 'T'+           && SBS.unsafeIndex sbs 1 == 117  -- ord 'u'+           && SBS.unsafeIndex sbs 2 == 112  -- ord 'p'+           && SBS.unsafeIndex sbs 3 == 108  -- ord 'l'+           && SBS.unsafeIndex sbs 4 == 101  -- ord 'e'+  , Just r@(_, arity) <- sbs_arity_boxity sbs 5+  , arity >= 2, arity <= mAX_TUPLE_SIZE+  = Just r+  | otherwise = Nothing+  where+    n = SBS.length sbs -- O(1)++-- (sbs_CTuple sbs) checks if the string has form "CTupleN" or "CTupleNM",+-- where "N" or "NM" is a decimal numeral in the [2..mAX_CTUPLE_SIZE] range.+sbs_CTuple :: SBS.ShortByteString -> Maybe Arity+sbs_CTuple !sbs+  | n >= 6 && SBS.unsafeIndex sbs 0 == 67   -- ord 'C'+           && SBS.unsafeIndex sbs 1 == 84   -- ord 'T'+           && SBS.unsafeIndex sbs 2 == 117  -- ord 'u'+           && SBS.unsafeIndex sbs 3 == 112  -- ord 'p'+           && SBS.unsafeIndex sbs 4 == 108  -- ord 'l'+           && SBS.unsafeIndex sbs 5 == 101  -- ord 'e'+  , Just (Boxed, arity) <- sbs_arity_boxity sbs 6+  , arity >= 2, arity <= mAX_CTUPLE_SIZE+  = Just arity+  | otherwise = Nothing+  where+    n = SBS.length sbs -- O(1)++-- (sbs_arity_boxity sbs i) parses bytes from position `i` to the end,+-- matching single- and double-digit decimals numerals (i.e. from 0 to 99)+-- possibly followed by '#'. See Note [Small Ints parsing]+sbs_arity_boxity :: SBS.ShortByteString -> Int -> Maybe (Boxity, Arity)+sbs_arity_boxity !sbs !i =+  case n - i of  -- bytes to parse+    1 -> parse1 (SBS.unsafeIndex sbs i)+    2 -> parse2 (SBS.unsafeIndex sbs i) (SBS.unsafeIndex sbs (i+1))+    3 -> parse3 (SBS.unsafeIndex sbs i) (SBS.unsafeIndex sbs (i+1)) (SBS.unsafeIndex sbs (i+2))+    _ -> Nothing+  where+    n = SBS.length sbs -- O(1)++    is_digit :: Word8 -> Bool+    is_digit x = x >= 48 && x <= 57  -- between (ord '0') and (ord '9')++    from_digit :: Word8 -> Int+    from_digit x = fromIntegral (x - 48)++    -- single-digit number+    parse1 :: Word8 -> Maybe (Boxity, Arity)+    parse1 x1 | is_digit x1 = Just (Boxed, from_digit x1)+    parse1 _ = Nothing++    -- double-digit number, or a single-digit number followed by '#'+    parse2 :: Word8 -> Word8 -> Maybe (Boxity, Arity)+    parse2 x1 35  -- ord '#'+      | is_digit x1 = Just (Unboxed, from_digit x1)+    parse2 x1 x2+      | is_digit x1, is_digit x2+      = Just (Boxed, from_digit x1 * 10 + from_digit x2)+    parse2 _ _ = Nothing++    -- double-digit number followed by '#'+    parse3 :: Word8 -> Word8 -> Word8 -> Maybe (Boxity, Arity)+    parse3 x1 x2 35 -- ord '#'+      | is_digit x1, is_digit x2+      = Just (Unboxed, from_digit x1 * 10 + from_digit x2)+    parse3 _ _ _ = Nothing++-- Identify original names of boxed and unboxed tuple type constructors.+-- Examples:+--   0b) isTupleTyOrigName_maybe GHC.Tuple (mkTcOcc "Unit")    =  Just <wired-in Name for 0-tuples>+--   1b) isTupleTyOrigName_maybe GHC.Tuple (mkTcOcc "Solo")    =  Just <wired-in Name for 1-tuples>+--   2b) isTupleTyOrigName_maybe GHC.Tuple (mkTcOcc "Tuple2")  =  Just <wired-in Name for 2-tuples>+--   0u) isTupleTyOrigName_maybe GHC.Types (mkTcOcc "Unit#")   =  Just <wired-in Name for unboxed 0-tuples>+--   1u) isTupleTyOrigName_maybe GHC.Types (mkTcOcc "Solo#")   =  Just <wired-in Name for unboxed 1-tuples>+--   2u) isTupleTyOrigName_maybe GHC.Types (mkTcOcc "Tuple2#") =  Just <wired-in Name for unboxed 2-tuples>+--   ...+--   64b) isTupleTyOrigName_maybe GHC.Tuple (mkTcOcc "Tuple64")  =  Just <wired-in Name for 64-tuples>+--   64u) isTupleTyOrigName_maybe GHC.Types (mkTcOcc "Tuple64#") =  Just <wired-in Name for unboxed 64-tuples>+--+-- Non-examples: "()", "(##)", "(,)", "(#,#)", "(,,)", "(#,,#)", etc.+-- As far as tuple /types/ are concerned, these are not the original names+-- but rather punned names under ListTuplePuns.+--+-- Also non-examples: "Tuple0", "Tuple0#", "Tuple1", and "Tuple1#".+-- These are merely type synonyms for "Unit", "Unit#", "Solo", and "Solo#".+isTupleTyOrigName_maybe :: Module -> OccName -> Maybe Name+isTupleTyOrigName_maybe mod occ+  | mod == gHC_INTERNAL_TUPLE = match_occ_boxed+  | mod == gHC_TYPES          = match_occ_unboxed+  where+    fs  = occNameFS occ+    ns  = occNameSpace occ+    sbs = fastStringToShortByteString fs   -- O(1) field access++    match_occ_boxed       | occ == occName unitTyConName = Just unitTyConName       | occ == occName soloTyConName = Just soloTyConName+      | isTcClsNameSpace ns, Just (boxity@Boxed, n) <- sbs_Tuple sbs, n >= 2+      = Just (tyConName (tupleTyCon boxity n))+      | otherwise = Nothing++    match_occ_unboxed       | occ == occName unboxedUnitTyConName = Just unboxedUnitTyConName       | occ == occName unboxedSoloTyConName = Just unboxedSoloTyConName-      | otherwise = isTupleNTyOcc_maybe occ-isTupleTyOcc_maybe _ _ = Nothing+      | isTcClsNameSpace ns, Just (boxity@Unboxed, n) <- sbs_Tuple sbs, n >= 2+      = Just (tyConName (tupleTyCon boxity n))+      | otherwise = Nothing -isCTupleOcc_maybe :: Module -> OccName -> Maybe Name-isCTupleOcc_maybe mod occ+isTupleTyOrigName_maybe _ _ = Nothing++-- Identify original names of boxed and unboxed tuple data constructors.+-- Examples:+--   0b) isTupleDataOrigName_maybe GHC.Tuple (mkDataOcc "()")      =  Just <wired-in Name for 0-tuples>+--   1b) isTupleDataOrigName_maybe GHC.Tuple (mkDataOcc "MkSolo")  =  Just <wired-in Name for 1-tuples>+--   2b) isTupleDataOrigName_maybe GHC.Tuple (mkDataOcc "(,)")     =  Just <wired-in Name for 2-tuples>+--   ...+--   0u) isTupleDataOrigName_maybe GHC.Types (mkDataOcc "(##)")    =  Just <wired-in Name for unboxed 0-tuples>+--   1u) isTupleDataOrigName_maybe GHC.Types (mkDataOcc "MkSolo#") =  Just <wired-in Name for unboxed 1-tuples>+--   2u) isTupleDataOrigName_maybe GHC.Types (mkDataOcc "(#,#)")   =  Just <wired-in Name for unboxed 2-tuples>+--   ...+--+-- Non-examples: Tuple<n> or Tuple<n>#, as this is the name format of tuple /type/ constructors.+isTupleDataOrigName_maybe :: Module -> OccName -> Maybe Name+isTupleDataOrigName_maybe mod occ+  | mod == gHC_INTERNAL_TUPLE = match_occ_boxed+  | mod == gHC_TYPES          = match_occ_unboxed+  where+    match_occ_boxed+      | occ == occName soloDataConName = Just soloDataConName+      | isDataConNameSpace ns, Just n <- (is_boxed_tup_syntax fs)+      = Just (tupleDataConName Boxed n)+      | otherwise = Nothing+    match_occ_unboxed+      | occ == occName unboxedSoloDataConName = Just unboxedSoloDataConName+      | isDataConNameSpace ns, Just n <- (is_unboxed_tup_syntax fs)+      = Just (tupleDataConName Unboxed n)+      | otherwise = Nothing+    fs = occNameFS occ+    ns = occNameSpace occ+isTupleDataOrigName_maybe _ _ = Nothing++-- Identify original names of constraint tuples.+-- Examples:+--   0) isCTupleOrigName_maybe GHC.Classes (mkClsOcc "CUnit")    =  Just <wired-in Name for 0-ctuples>+--   1) isCTupleOrigName_maybe GHC.Classes (mkClsOcc "CSolo")    =  Just <wired-in Name for 1-ctuples>+--   2) isCTupleOrigName_maybe GHC.Classes (mkClsOcc "CTuple2")  =  Just <wired-in Name for 2-ctuples>+--   ...+--   64) isCTupleOrigName_maybe GHC.Classes (mkClsOcc "CTuple64")  =  Just <wired-in Name for 64-ctuples>+--+-- Non-examples: "()", "(,)", "(,,)", etc.+-- As far as constraint tuples are concerned, these are not the original names+-- but rather punned names under ListTuplePuns.+--+-- Also non-examples: "CTuple0" and "CTuple1".+-- These are merely type synonyms for "CUnit" and "CSolo".+isCTupleOrigName_maybe :: Module -> OccName -> Maybe Name+isCTupleOrigName_maybe mod occ   | mod == gHC_CLASSES   = match_occ   where+    fs  = occNameFS occ+    sbs = fastStringToShortByteString fs   -- O(1) field access     match_occ-      | occ == occName (cTupleTyConName 0) = Just (cTupleTyConName 0)-      | occ == occName (cTupleTyConName 1) = Just (cTupleTyConName 1)-      | 'C':'T':'u':'p':'l':'e' : rest <- occNameString occ-      , Just (BoxedTuple, num) <- arity_and_boxity rest-      , num >= 2 && num <= 64-           = Just $ cTupleTyConName num-      | otherwise = Nothing--isCTupleOcc_maybe _ _ = Nothing+      | occ == occName (cTupleTyConName 0) = Just (cTupleTyConName 0)  -- CUnit+      | occ == occName (cTupleTyConName 1) = Just (cTupleTyConName 1)  -- CSolo --- | This is only for Tuple<n>, not for Unit or Solo-isTupleNTyOcc_maybe :: OccName -> Maybe Name-isTupleNTyOcc_maybe occ =-  case occNameString occ of-    'T':'u':'p':'l':'e':str | Just (sort, n) <- arity_and_boxity str, n > 1-      -> Just (tupleTyConName sort n)-    _ -> Nothing+      | Just num <- sbs_CTuple sbs, num >= 2+      = Just $ cTupleTyConName num -isSumTyOcc_maybe :: Module -> OccName -> Maybe Name-isSumTyOcc_maybe mod occ | mod == gHC_TYPES =-  isSumNTyOcc_maybe occ-isSumTyOcc_maybe _ _ = Nothing+      | otherwise = Nothing -isSumNTyOcc_maybe :: OccName -> Maybe Name-isSumNTyOcc_maybe occ =-  case occNameString occ of-    'S':'u':'m':str | Just (UnboxedTuple, n) <- arity_and_boxity str, n > 1-      -> Just (tyConName (sumTyCon n))-    _ -> Nothing+isCTupleOrigName_maybe _ _ = Nothing --- | See Note [Small Ints parsing]+-- Identify original names of unboxed sum type constructors.+-- Examples:+--   2) isSumTyOrigName_maybe GHC.Types (mkTcOcc "Sum2#") =  Just <wired-in Name for unboxed 2-sums>+--   3) isSumTyOrigName_maybe GHC.Types (mkTcOcc "Sum3#") =  Just <wired-in Name for unboxed 3-sums>+--   4) isSumTyOrigName_maybe GHC.Types (mkTcOcc "Sum4#") =  Just <wired-in Name for unboxed 4-sums>+--   ...+--   64) isSumTyOrigName_maybe GHC.Types (mkTcOcc "Sum64#") =  Just <wired-in Name for unboxed 64-sums> ----- Analyze a string as the suffix of an OccName of a tuple or sum tycon to--- determine its arity and boxity (based on the presence of a @#@).-arity_and_boxity :: String -> Maybe (TupleSort, Int)-arity_and_boxity s = case s of-  c1 : t1 | isDigit c1 -> case t1 of-    [] -> Just (BoxedTuple, digit_to_int c1)-    ['#'] -> Just (UnboxedTuple, digit_to_int c1)-    c2 : t2 | isDigit c2 ->-      let ar = digit_to_int c1 * 10 + digit_to_int c2-      in case t2 of-        [] -> Just (BoxedTuple, ar)-        ['#'] -> Just (UnboxedTuple, ar)-        _ -> Nothing-    _ -> Nothing-  _ -> Nothing+-- Non-examples: "(#|#)", "(#||#)", "(#|||#)", etc. These are not valid syntax.+-- Also non-examples: "Sum0#", "Sum1#". These do not exist.+isSumTyOrigName_maybe :: Module -> OccName -> Maybe Name+isSumTyOrigName_maybe mod occ+  | mod == gHC_TYPES+  , isTcClsNameSpace ns+  , Just n <- sbs_Sum sbs+  , n >= 2+  = Just (tyConName (sumTyCon n))   where-    digit_to_int :: Char -> Int-    digit_to_int c = ord c - ord '0'+    fs  = occNameFS occ+    ns  = occNameSpace occ+    sbs = fastStringToShortByteString fs   -- O(1) field access+isSumTyOrigName_maybe _ _ = Nothing +-- Identify original names of unboxed sum data constructors.+-- "(#_|#)", "(#_||#)", (#|_|#)"+--+-- Examples:+--   1/2) isSumTyOrigName_maybe GHC.Types (mkDataOcc "(#_|#)")  =  Just <wired-in Name for 1st alt of unboxed 2-sums>+--   1/3) isSumTyOrigName_maybe GHC.Types (mkDataOcc "(#_||#)") =  Just <wired-in Name for 1st alt of unboxed 3-sums>+--   2/3) isSumTyOrigName_maybe GHC.Types (mkDataOcc "(#|_|#)") =  Just <wired-in Name for 2nd alt of unboxed 3-sums>+--   ...+--+-- Non-examples: Sum<n>#, as this is the name format of unboxed sum /type/ constructors.+isSumDataOrigName_maybe :: Module -> OccName -> Maybe Name+isSumDataOrigName_maybe mod occ+  | mod == gHC_TYPES+  , isDataConNameSpace ns+  , Just (k,n) <- (is_unboxed_sum_data_syntax fs)+  = Just (unboxedSumDataConName k n)+  where fs = occNameFS occ+        ns = occNameSpace occ+isSumDataOrigName_maybe _ _ = Nothing+ {- Note [Small Ints parsing] ~~~~~~~~~~~~~~~~~~~~~~~~~@@ -1034,26 +1320,6 @@ `readMaybe @Int` on my machine. -} --- When resolving names produced by Template Haskell (see thOrigRdrName--- in GHC.ThToHs), we want ghc-prim:GHC.Types.List to yield an Exact name, not--- an Orig name.------ This matters for pretty-printing under ListTuplePuns. If we don't do it,--- then -ddump-splices will print ''[] as ''GHC.Types.List.------ Test case: th/T13776----isPunOcc_maybe :: Module -> OccName -> Maybe Name-isPunOcc_maybe mod occ-  | mod == gHC_TYPES, occ == occName listTyConName-  = Just listTyConName-  | mod == gHC_TYPES, occ == occName unboxedSoloDataConName-  = Just unboxedSoloDataConName-  | otherwise-  = isTupleTyOcc_maybe mod occ <|>-    isCTupleOcc_maybe  mod occ <|>-    isSumTyOcc_maybe   mod occ- mkTupleOcc :: NameSpace -> Boxity -> Arity -> (OccName, BuiltInSyntax) mkTupleOcc ns b ar = (mkOccName ns str, built_in)   where (str, built_in) = mkTupleStr' ns b ar@@ -1112,16 +1378,6 @@  = assertPpr (isExternalName n) (ppr n) $    getUnique n `memberUniqueSet` cTupleTyConKeys --- | If the given name is that of a constraint tuple, return its arity.-cTupleTyConNameArity_maybe :: Name -> Maybe Arity-cTupleTyConNameArity_maybe n-  | not (isCTupleTyConName n) = Nothing-  | otherwise = fmap adjustArity (n `elemIndex` cTupleTyConNames)-  where-    -- Since `cTupleTyConNames` jumps straight from the `0` to the `2`-    -- case, we have to adjust accordingly our calculated arity.-    adjustArity a = if a > 0 then a + 1 else a- cTupleDataCon :: Arity -> DataCon cTupleDataCon i   | i > mAX_CTUPLE_SIZE = sndOf3 (mk_ctuple i) -- Build one specially@@ -1202,14 +1458,6 @@ -- tuple and the inner array is indexed by the superclass position. cTupleArr :: Array Int (TyCon, DataCon, Array Int Id) cTupleArr = listArray (0,mAX_CTUPLE_SIZE) [mk_ctuple i | i <- [0..mAX_CTUPLE_SIZE]]-  -- Although GHC does not make use of unary constraint tuples-  -- (see Note [Ignore unary constraint tuples] in GHC.Tc.Gen.HsType),-  -- this array creates one anyway. This is primarily motivated by the fact-  -- that (1) the indices of an Array must be contiguous, and (2) we would like-  -- the index of a constraint tuple in this Array to correspond to its Arity.-  -- We could envision skipping over the unary constraint tuple and having index-  -- 1 correspond to a 2-constraint tuple (and so on), but that's more-  -- complicated than it's worth.  -- | Given the TupleRep/SumRep tycon and list of RuntimeReps of the unboxed -- tuple/sum arguments, produces the return kind of an unboxed tuple/sum type@@ -1400,6 +1648,9 @@   | otherwise   = fst (unboxedSumArr ! arity) +unboxedSumTyConName :: Arity -> Name+unboxedSumTyConName arity = tyConName (sumTyCon arity)+ -- | Data constructor for i-th alternative of a n-ary unboxed sum. sumDataCon :: ConTag -- Alternative            -> Arity  -- Arity@@ -1423,6 +1674,9 @@   | otherwise   = snd (unboxedSumArr ! arity) ! (alt - 1) +unboxedSumDataConName :: ConTag -> Arity -> Name+unboxedSumDataConName alt arity = dataConName (sumDataCon alt arity)+ -- | Cached type and data constructors for sums. The outer array is -- indexed by the arity of the sum and the inner array is indexed by -- the alternative.@@ -1511,6 +1765,9 @@     binders   = mkTemplateTyConBinders [liftedTypeKind] (\[k] -> [k,k])     roles     = [Nominal, Nominal, Nominal]     rhs       = mkDataTyConRhs [datacon]+                -- rhs: a DataTyCon, not a UnaryClassTyCon!  Yes it has one+                --      field, but it has unboxed type (a ~# b),+                --      so the class must provide the box.      tvs@[k,a,b] = binderVars binders     sc_pred     = mkTyConApp eqPrimTyCon (mkTyVarTys [k,k,a,b])@@ -2633,13 +2890,6 @@ naturalNBDataCon :: DataCon naturalNBDataCon = pcDataCon naturalNBDataConName [] [byteArrayPrimTy] naturalTyCon ---- | Replaces constraint tuple names with corresponding boxed ones.-filterCTuple :: RdrName -> RdrName-filterCTuple (Exact n)-  | Just arity <- cTupleTyConNameArity_maybe n-  = Exact $ tupleTyConName BoxedTuple arity-filterCTuple rdr = rdr  {- ************************************************************************
GHC/Builtin/Types/Prim.hs view
@@ -77,7 +77,6 @@         mutVarPrimTyCon, mkMutVarPrimTy,          mVarPrimTyCon,                  mkMVarPrimTy,-        ioPortPrimTyCon,                mkIOPortPrimTy,         tVarPrimTyCon,                  mkTVarPrimTy,         stablePtrPrimTyCon,             mkStablePtrPrimTy,         stableNamePrimTyCon,            mkStableNamePrimTy,@@ -278,7 +277,6 @@     , mutableByteArrayPrimTyCon     , smallMutableArrayPrimTyCon     , mVarPrimTyCon-    , ioPortPrimTyCon     , tVarPrimTyCon     , mutVarPrimTyCon     , realWorldTyCon@@ -310,7 +308,7 @@   arrayPrimTyConName, smallArrayPrimTyConName, byteArrayPrimTyConName,   mutableArrayPrimTyConName, mutableByteArrayPrimTyConName,   smallMutableArrayPrimTyConName, mutVarPrimTyConName, mVarPrimTyConName,-  ioPortPrimTyConName, tVarPrimTyConName, stablePtrPrimTyConName,+  tVarPrimTyConName, stablePtrPrimTyConName,   stableNamePrimTyConName, compactPrimTyConName, bcoPrimTyConName,   weakPrimTyConName, threadIdPrimTyConName,   eqPrimTyConName, eqReprPrimTyConName, eqPhantPrimTyConName,@@ -342,7 +340,6 @@ mutableByteArrayPrimTyConName = mkPrimTc (fsLit "MutableByteArray#") mutableByteArrayPrimTyConKey mutableByteArrayPrimTyCon smallMutableArrayPrimTyConName= mkPrimTc (fsLit "SmallMutableArray#") smallMutableArrayPrimTyConKey smallMutableArrayPrimTyCon mutVarPrimTyConName           = mkPrimTc (fsLit "MutVar#") mutVarPrimTyConKey mutVarPrimTyCon-ioPortPrimTyConName           = mkPrimTc (fsLit "IOPort#") ioPortPrimTyConKey ioPortPrimTyCon mVarPrimTyConName             = mkPrimTc (fsLit "MVar#") mVarPrimTyConKey mVarPrimTyCon tVarPrimTyConName             = mkPrimTc (fsLit "TVar#") tVarPrimTyConKey tVarPrimTyCon stablePtrPrimTyConName        = mkPrimTc (fsLit "StablePtr#") stablePtrPrimTyConKey stablePtrPrimTyCon@@ -1017,7 +1014,7 @@     -------------------------- This is The Type Of Equality in GHC. It classifies nominal coercions. This type is used in the solver for recording equality constraints.-It responds "yes" to Type.isEqPrimPred and classifies as an EqPred in+It responds "yes" to Type.isEqPred and classifies as an EqPred in Type.classifyPredType.  All wanted constraints of this type are built with coercion holes.@@ -1279,20 +1276,6 @@  mkMutVarPrimTy :: Type -> Type -> Type mkMutVarPrimTy s elt        = TyConApp mutVarPrimTyCon [getLevity elt, s, elt]--{--************************************************************************-*                                                                      *-\subsection[TysPrim-io-port-var]{The synchronizing I/O Port type}-*                                                                      *-************************************************************************--}--ioPortPrimTyCon :: TyCon-ioPortPrimTyCon = pcPrimTyCon_LevPolyLastArg ioPortPrimTyConName [Nominal, Representational] unliftedRepTy--mkIOPortPrimTy :: Type -> Type -> Type-mkIOPortPrimTy s elt          = TyConApp ioPortPrimTyCon [getLevity elt, s, elt]  {- ************************************************************************
GHC/Builtin/Uniques.hs view
@@ -26,6 +26,7 @@     , mkCTupleTyConUnique     , mkCTupleDataConUnique     , mkCTupleSelIdUnique+    , isCTupleTyConUnique        -- ** Making built-in uniques     , mkAlphaTyVarUnique@@ -122,6 +123,7 @@               -- alternative     mkUniqueInt 'z' (arity `shiftL` 8 .|. 0xfc) +-- | Inverse of 'mkSumTyConUnique' isSumTyConUnique :: Unique -> Maybe Arity isSumTyConUnique u =   case (tag, n .&. 0xfc) of@@ -234,6 +236,17 @@   | otherwise   = mkUniqueInt 'j' (arity `shiftL` cTupleSelIdArityBits + sc_pos) +-- | Inverse of 'mkCTupleTyConUnique'+isCTupleTyConUnique :: Unique -> Maybe Arity+isCTupleTyConUnique u =+  case (tag, i) of+    ('k', 0) -> Just arity+    _        -> Nothing+  where+    (tag, n) = unpkUnique u+    (arity', i) = quotRem n 2+    arity = word64ToInt arity'+ getCTupleTyConName :: Int -> Name getCTupleTyConName n =     case n `divMod` 2 of@@ -282,7 +295,7 @@ mkTupleTyConUnique Boxed           a  = mkUniqueInt '4' (2*a) mkTupleTyConUnique Unboxed         a  = mkUniqueInt '5' (2*a) --- | This function is an inverse of `mkTupleTyConUnique`+-- | Inverse of 'mkTupleTyConUnique' isTupleTyConUnique :: Unique -> Maybe (Boxity, Arity) isTupleTyConUnique u =   case (tag, i) of@@ -294,7 +307,7 @@     (arity', i) = quotRem n 2     arity = word64ToInt arity' --- | This function is an inverse of `mkTupleTyDataUnique` that also matches the worker and promoted tycon.+-- | Inverse of 'mkTupleTyDataUnique' that also matches the worker and promoted tycon. isTupleDataConLikeUnique :: Unique -> Maybe (Boxity, Arity) isTupleDataConLikeUnique u =   case tag of
GHC/Builtin/primops.txt.pp view
@@ -1132,10 +1132,18 @@  primop   DoubleMinOp   "minDouble#"      GenPrimOp    Double# -> Double# -> Double#+   {Return the minimum of the arguments.+   When the arguments are numerically equal (e.g. @0.0##@ and @-0.0##@)+   or one of the arguments is not-a-number (NaN),+   it is unspecified which one is returned.}    with commutable = True  primop   DoubleMaxOp   "maxDouble#"      GenPrimOp    Double# -> Double# -> Double#+   {Return the maximum of the arguments.+   When the arguments are numerically equal (e.g. @0.0##@ and @-0.0##@)+   or one of the arguments is not-a-number (NaN),+   it is unspecified which one is returned.}    with commutable = True  primop   DoubleAddOp   "+##"   GenPrimOp@@ -1306,10 +1314,18 @@  primop   FloatMinOp   "minFloat#"      GenPrimOp    Float# -> Float# -> Float#+   {Return the minimum of the arguments.+   When the arguments are numerically equal (e.g. @0.0#@ and @-0.0#@)+   or one of the arguments is not-a-number (NaN),+   it is unspecified which one is returned.}    with commutable = True  primop   FloatMaxOp   "maxFloat#"      GenPrimOp    Float# -> Float# -> Float#+   {Return the maximum of the arguments.+   When the arguments are numerically equal (e.g. @0.0#@ and @-0.0#@)+   or one of the arguments is not-a-number (NaN),+   it is unspecified which one is returned.}    with commutable = True  primop   FloatAddOp   "plusFloat#"      GenPrimOp@@ -3223,43 +3239,6 @@   -------------------------------------------------------------------------section "Synchronized I/O Ports"-        {Operations on 'IOPort#'s. }---------------------------------------------------------------------------primtype IOPort# s a-        { A shared I/O port is almost the same as an 'MVar#'.-        The main difference is that IOPort has no deadlock detection or-        deadlock breaking code that forcibly releases the lock. }--primop  NewIOPortOp "newIOPort#"  GenPrimOp-   State# s -> (# State# s, IOPort# s a_levpoly #)-   {Create new 'IOPort#'; initially empty.}-   with-   out_of_line = True-   effect = ReadWriteEffect--primop  ReadIOPortOp "readIOPort#" GenPrimOp-   IOPort# s a_levpoly -> State# s -> (# State# s, a_levpoly #)-   {If 'IOPort#' is empty, block until it becomes full.-   Then remove and return its contents, and set it empty.-   Throws an 'IOPortException' if another thread is already-   waiting to read this 'IOPort#'.}-   with-   out_of_line      = True-   effect = ReadWriteEffect--primop  WriteIOPortOp "writeIOPort#" GenPrimOp-   IOPort# s a_levpoly -> a_levpoly -> State# s -> (# State# s, Int# #)-   {If 'IOPort#' is full, immediately return with integer 0,-    throwing an 'IOPortException'.-    Otherwise, store value arg as 'IOPort#''s new contents,-    and return with integer 1. }-   with-   out_of_line      = True-   effect = ReadWriteEffect-------------------------------------------------------------------------- section "Delay/wait operations" ------------------------------------------------------------------------ @@ -3703,7 +3682,6 @@ --   sameMutVar# :: MutVar# s a -> MutVar# s a -> Int# --   sameTVar# :: TVar# s a -> TVar# s a -> Int# --   sameMVar# :: MVar# s a -> MVar# s a -> Int#---   sameIOPort# :: IOPort# s a -> IOPort# s a -> Int# --   eqStableName# :: StableName# a -> StableName# b -> Int# -- -- These operations are all specialisations of unsafePtrEquality#.@@ -3949,6 +3927,16 @@    out_of_line = True  ------------------------------------------------------------------------+section "Annotating call stacks"+------------------------------------------------------------------------++primop AnnotateStackOp "annotateStack#" GenPrimOp+   b -> (State# s -> (# State# s, a_reppoly #)) -> State# s -> (# State# s, a_reppoly #)+   { Pushes an annotation frame to the stack which can be reported by backtraces. }+   with+   out_of_line = True++------------------------------------------------------------------------ section "Info Table Origin" ------------------------------------------------------------------------ primop WhereFromOp "whereFrom#" GenPrimOp@@ -4055,6 +4043,15 @@    effect = ReadWriteEffect    out_of_line      = True +primop  SetOtherThreadAllocationCounter "setOtherThreadAllocationCounter#" GenPrimOp+   Int64# -> ThreadId# -> State# RealWorld -> State# RealWorld+   { Sets the allocation counter for the another thread to the given value.+     This doesn't take allocations into the current nursery chunk into account.+     Therefore it is only accurate if the other thread is not currently running. }+   with+   effect = ReadWriteEffect+   out_of_line      = True+ primtype StackSnapshot#    { Haskell representation of a @StgStack*@ that was created (cloned)      with a function in "GHC.Stack.CloneStack". Please check the@@ -4146,12 +4143,13 @@  primop VecUnpackOp "unpack#" GenPrimOp    VECTOR -> VECTUPLE-   { Unpack the elements of a vector into an unboxed tuple. #}+   { Unpack the elements of a vector into an unboxed tuple. }    with vector = ALL_VECTOR_TYPES  primop VecInsertOp "insert#" GenPrimOp    VECTOR -> SCALAR -> Int# -> VECTOR-   { Insert a scalar at the given position in a vector. }+   { Insert a scalar at the given position in a vector.+     The position must be a compile-time constant. }    with effect = CanFail         vector = ALL_VECTOR_TYPES @@ -4180,14 +4178,20 @@  primop VecQuotOp "quot#" GenPrimOp    VECTOR -> VECTOR -> VECTOR-   { Rounds towards zero element-wise. }+   { Rounds towards zero element-wise.++     Note: Most CPU ISAs do not contain any SIMD integer division instructions.+     Do not expect high performance. }    with effect = CanFail         vector = INT_VECTOR_TYPES         div_like = True  primop VecRemOp "rem#" GenPrimOp    VECTOR -> VECTOR -> VECTOR-   { Satisfies @('quot#' x y) 'times#' y 'plus#' ('rem#' x y) == x@. }+   { Satisfies @('quot#' x y) 'times#' y 'plus#' ('rem#' x y) == x@.++     Note: Most CPU ISAs do not contain any SIMD integer division instructions.+     Do not expect high performance. }    with effect = CanFail         vector = INT_VECTOR_TYPES         div_like = True@@ -4200,40 +4204,43 @@  primop VecIndexByteArrayOp "indexArray#" GenPrimOp    ByteArray# -> Int# -> VECTOR-   { Read a vector from specified index of immutable array. }+   { Read a vector from the specified index of an immutable array.+     The index is counted in units of SIMD vectors (not scalar elements). }    with effect = CanFail         vector = ALL_VECTOR_TYPES  primop VecReadByteArrayOp "readArray#" GenPrimOp    MutableByteArray# s -> Int# -> State# s -> (# State# s, VECTOR #)-   { Read a vector from specified index of mutable array. }+   { Read a vector from the specified index of a mutable array.+     The index is counted in units of SIMD vectors (not scalar elements). }    with effect = ReadWriteEffect         can_fail_warning = YesWarnCanFail         vector = ALL_VECTOR_TYPES  primop VecWriteByteArrayOp "writeArray#" GenPrimOp    MutableByteArray# s -> Int# -> VECTOR -> State# s -> State# s-   { Write a vector to specified index of mutable array. }+   { Write a vector to the specified index of a mutable array.+     The index is counted in units of SIMD vectors (not scalar elements). }    with effect = ReadWriteEffect         can_fail_warning = YesWarnCanFail         vector = ALL_VECTOR_TYPES  primop VecIndexOffAddrOp "indexOffAddr#" GenPrimOp    Addr# -> Int# -> VECTOR-   { Reads vector; offset in bytes. }+   { Reads vector; offset in units of SIMD vectors (not scalar elements). }    with effect = CanFail         vector = ALL_VECTOR_TYPES  primop VecReadOffAddrOp "readOffAddr#" GenPrimOp    Addr# -> Int# -> State# s -> (# State# s, VECTOR #)-   { Reads vector; offset in bytes. }+   { Reads vector; offset in units of SIMD vectors (not scalar elements). }    with effect = ReadWriteEffect         can_fail_warning = YesWarnCanFail         vector = ALL_VECTOR_TYPES  primop VecWriteOffAddrOp "writeOffAddr#" GenPrimOp    Addr# -> Int# -> VECTOR -> State# s -> State# s-   { Write vector; offset in bytes. }+   { Write vector; offset in units of SIMD vectors (not scalar elements). }    with effect = ReadWriteEffect         can_fail_warning = YesWarnCanFail         vector = ALL_VECTOR_TYPES@@ -4303,7 +4310,7 @@ primop VecShuffleOp "shuffle#" GenPrimOp   VECTOR -> VECTOR -> INTVECTUPLE -> VECTOR   {Shuffle elements of the concatenation of the input two vectors-  into the result vector.}+  into the result vector. The indices must be compile-time constants.}    with vector = ALL_VECTOR_TYPES  primop VecMinOp "min#" GenPrimOp
GHC/ByteCode/Asm.hs view
@@ -1,27 +1,33 @@ {-# LANGUAGE CPP             #-} {-# LANGUAGE DeriveFunctor   #-} {-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE MagicHash       #-}+{-# LANGUAGE UnboxedTuples   #-}+{-# LANGUAGE PatternSynonyms   #-} {-# OPTIONS_GHC -optc-DNON_POSIX_SOURCE #-} --+-- --  (c) The University of Glasgow 2002-2006 --  -- | Bytecode assembler and linker module GHC.ByteCode.Asm (-        assembleBCOs, assembleOneBCO,+        assembleBCOs,         bcoFreeNames,         SizedSeq, sizeSS, ssElts,         iNTERP_STACK_CHECK_THRESH,-        mkNativeCallInfoLit+        mkNativeCallInfoLit,++        -- * For testing+        assembleBCO   ) where -import GHC.Prelude+import GHC.Prelude hiding ( any ) + import GHC.ByteCode.Instr import GHC.ByteCode.InfoTable import GHC.ByteCode.Types-import GHCi.RemoteTypes-import GHC.Runtime.Interpreter import GHC.Runtime.Heap.Layout ( fromStgWord, StgWord )  import GHC.Types.Name@@ -29,13 +35,15 @@ import GHC.Types.Literal import GHC.Types.Unique.DSet import GHC.Types.SptEntry+import GHC.Types.Unique.FM+import GHC.Unit.Types  import GHC.Utils.Outputable import GHC.Utils.Panic  import GHC.Core.TyCon-import GHC.Data.FlatBag import GHC.Data.SizedSeq+import GHC.Data.SmallArray  import GHC.StgToCmm.Layout     ( ArgRep(..) ) import GHC.Cmm.Expr@@ -43,22 +51,29 @@ import GHC.Cmm.CallConv        ( allArgRegsCover ) import GHC.Platform import GHC.Platform.Profile+import Language.Haskell.Syntax.Module.Name  import Control.Monad-import Control.Monad.Trans.Class-import Control.Monad.Trans.State.Strict+import qualified Control.Monad.Trans.State.Strict as MTL  import qualified Data.Array.Unboxed as Array-import Data.Array.Base  ( UArray(..) )+import qualified Data.Array.IO as Array+import Data.Array.Base  ( UArray(..), numElements, unsafeFreeze ) +#if ! defined(DEBUG)+import Data.Array.Base  ( unsafeWrite )+#endif+ import Foreign hiding (shiftL, shiftR)-import Data.Char        ( ord )-import Data.List        ( genericLength )-import Data.Map.Strict (Map)+import Data.ByteString (ByteString)+import Data.Char  (ord) import Data.Maybe (fromMaybe)-import qualified Data.Map.Strict as Map import GHC.Float (castFloatToWord32, castDoubleToWord64) +import qualified Data.List as List ( any )+import GHC.Exts++ -- ----------------------------------------------------------------------------- -- Unlinked BCOs @@ -90,24 +105,21 @@  -- Top level assembler fn. assembleBCOs-  :: Interp-  -> Profile+  :: Profile   -> FlatBag (ProtoBCO Name)   -> [TyCon]-  -> AddrEnv-  -> Maybe ModBreaks+  -> [(Name, ByteString)]+  -> Maybe InternalModBreaks   -> [SptEntry]   -> IO CompiledByteCode-assembleBCOs interp profile proto_bcos tycons top_strs modbreaks spt_entries = do+assembleBCOs profile proto_bcos tycons top_strs modbreaks spt_entries = do   -- TODO: the profile should be bundled with the interpreter: the rts ways are   -- fixed for an interpreter-  itblenv <- mkITbls interp profile tycons+  let itbls = mkITbls profile tycons   bcos    <- mapM (assembleBCO (profilePlatform profile)) proto_bcos-  bcos'   <- mallocStrings interp bcos   return CompiledByteCode-    { bc_bcos = bcos'-    , bc_itbls = itblenv-    , bc_ffis = concatMap protoBCOFFIs proto_bcos+    { bc_bcos = bcos+    , bc_itbls = itbls     , bc_strs = top_strs     , bc_breaks = modbreaks     , bc_spt_entries = spt_entries@@ -123,60 +135,66 @@ -- memory for them, and bake the resulting addresses into the instruction stream -- in the form of BCONPtrWord arguments. ----- Since we do this when assembling, we only allocate the memory when we compile--- the module, not each time we relink it. However, we do want to take care to--- malloc the memory all in one go, since that is more efficient with--- -fexternal-interpreter, especially when compiling in parallel.+-- We used to allocate remote buffers for BCONPtrStr ByteStrings when+-- assembling, but this gets in the way of bytecode serialization: we+-- want the ability to serialize and reload assembled bytecode, so+-- it's better to preserve BCONPtrStr as-is, and only perform the+-- actual allocation at link-time. -- -- Note that, as with top-level string literal bindings, this memory is never -- freed, so it just leaks if the BCO is unloaded. See Note [Generating code for -- top-level string literal bindings] in GHC.StgToByteCode for some discussion -- about why. ---mallocStrings ::  Interp -> FlatBag UnlinkedBCO -> IO (FlatBag UnlinkedBCO)-mallocStrings interp ulbcos = do-  let bytestrings = reverse (execState (mapM_ collect ulbcos) [])-  ptrs <- interpCmd interp (MallocStrings bytestrings)-  return (evalState (mapM splice ulbcos) ptrs)- where-  splice bco@UnlinkedBCO{..} = do-    lits <- mapM spliceLit unlinkedBCOLits-    ptrs <- mapM splicePtr unlinkedBCOPtrs-    return bco { unlinkedBCOLits = lits, unlinkedBCOPtrs = ptrs } -  spliceLit (BCONPtrStr _) = do-    rptrs <- get-    case rptrs of-      (RemotePtr p : rest) -> do-        put rest-        return (BCONPtrWord (fromIntegral p))-      _ -> panic "mallocStrings:spliceLit"-  spliceLit other = return other+data RunAsmReader = RunAsmReader { isn_array :: {-# UNPACK #-} !(Array.IOUArray Int Word16)+                                  , ptr_array :: {-# UNPACK #-} !(SmallMutableArrayIO BCOPtr)+                                  , lit_array :: {-# UNPACK #-} !(SmallMutableArrayIO BCONPtr )+                                  } -  splicePtr (BCOPtrBCO bco) = BCOPtrBCO <$> splice bco-  splicePtr other = return other+data RunAsmResult = RunAsmResult { final_isn_array :: !(Array.UArray Int Word16)+                                 , final_ptr_array :: !(SmallArray BCOPtr)+                                 , final_lit_array :: !(SmallArray BCONPtr) } -  collect UnlinkedBCO{..} = do-    mapM_ collectLit unlinkedBCOLits-    mapM_ collectPtr unlinkedBCOPtrs+-- How many words we have written so far.+data AsmState = AsmState { nisn :: !Int, nptr :: !Int, nlit :: !Int } -  collectLit (BCONPtrStr bs) = do-    strs <- get-    put (bs:strs)-  collectLit _ = return () -  collectPtr (BCOPtrBCO bco) = collect bco-  collectPtr _ = return ()+{-# NOINLINE inspectInstrs #-}+-- | Perform analysis of the bytecode to determine+--  1. How many instructions we will produce+--  2. If we are going to need long jumps.+--  3. The offsets that labels refer to+inspectInstrs :: Platform -> Bool -> Word -> [BCInstr] -> InspectState+inspectInstrs platform long_jump e instrs =+  inspectAsm long_jump e (mapM_ (assembleInspectAsm platform) instrs) +{-# NOINLINE runInstrs #-}+-- | Assemble the bytecode from the instructions.+runInstrs ::  Platform -> Bool -> InspectState -> [BCInstr] -> IO RunAsmResult+runInstrs platform long_jumps is_state instrs = do+  -- Produce arrays of exactly the right size, corresponding to the result of inspectInstrs.+  isn_array <- Array.newArray_ (0, (fromIntegral $ instrCount is_state) - 1)+  ptr_array <- newSmallArrayIO (fromIntegral $ ptrCount is_state) undefined+  lit_array <- newSmallArrayIO (fromIntegral $ litCount is_state) undefined+  let env :: LocalLabel -> Word+      env lbl = fromMaybe+        (pprPanic "assembleBCO.findLabel" (ppr lbl))+        (lookupUFM (lblEnv is_state) lbl)+  let initial_state  = AsmState 0 0 0+  let initial_reader = RunAsmReader{..}+  runAsm long_jumps env initial_reader initial_state (mapM_ (\i -> assembleRunAsm platform i) instrs)+  final_isn_array <- unsafeFreeze isn_array+  final_ptr_array <- unsafeFreezeSmallArrayIO ptr_array+  final_lit_array <- unsafeFreezeSmallArrayIO lit_array+  return $ RunAsmResult {..} -assembleOneBCO :: Interp -> Profile -> ProtoBCO Name -> IO UnlinkedBCO-assembleOneBCO interp profile pbco = do-  -- TODO: the profile should be bundled with the interpreter: the rts ways are-  -- fixed for an interpreter-  ubco <- assembleBCO (profilePlatform profile) pbco-  UnitFlatBag ubco' <- mallocStrings interp (UnitFlatBag ubco)-  return ubco'+assembleRunAsm :: Platform -> BCInstr -> RunAsm ()+assembleRunAsm p i = assembleI @RunAsm p i +assembleInspectAsm :: Platform -> BCInstr -> InspectAsm ()+assembleInspectAsm p i = assembleI @InspectAsm p i+ assembleBCO :: Platform -> ProtoBCO Name -> IO UnlinkedBCO assembleBCO platform             (ProtoBCO { protoBCOName       = nm@@ -185,9 +203,7 @@                       , protoBCOBitmapSize = bsize                       , protoBCOArity      = arity }) = do   -- pass 1: collect up the offsets of the local labels.-  let asm = mapM_ (assembleI platform) instrs--      initial_offset = 0+  let initial_offset = 0        -- Jump instructions are variable-sized, there are long and short variants       -- depending on the magnitude of the offset.  However, we can't tell what@@ -197,30 +213,31 @@       -- and if the final size is indeed small enough for short jumps, we are       -- done.  Otherwise, we repeat the calculation, and we force all jumps in       -- this BCO to be long.-      (n_insns0, lbl_map0) = inspectAsm platform False initial_offset asm-      ((n_insns, lbl_map), long_jumps)-        | isLargeW (fromIntegral $ Map.size lbl_map0)-          || isLargeW n_insns0-                    = (inspectAsm platform True initial_offset asm, True)-        | otherwise = ((n_insns0, lbl_map0), False)+      is0 = inspectInstrs platform False initial_offset instrs+      (is1, long_jumps)+        | isLargeInspectState is0+                    = (inspectInstrs platform True initial_offset instrs, True)+        | otherwise = (is0, False) -      env :: LocalLabel -> Word-      env lbl = fromMaybe-        (pprPanic "assembleBCO.findLabel" (ppr lbl))-        (Map.lookup lbl lbl_map)    -- pass 2: run assembler and generate instructions, literals and pointers-  let initial_state = (emptySS, emptySS, emptySS)-  (final_insns, final_lits, final_ptrs) <- flip execStateT initial_state $ runAsm platform long_jumps env asm+  RunAsmResult{..} <- runInstrs platform long_jumps is1 instrs    -- precomputed size should be equal to final size-  massertPpr (n_insns == sizeSS final_insns)+  massertPpr (fromIntegral (instrCount is1) == numElements final_isn_array+              && fromIntegral (ptrCount is1) == sizeofSmallArray final_ptr_array+              && fromIntegral (litCount is1) == sizeofSmallArray final_lit_array)              (text "bytecode instruction count mismatch") -  let asm_insns = ssElts final_insns-      !insns_arr =  mkBCOByteArray $ Array.listArray (0 :: Int, fromIntegral n_insns - 1) asm_insns+  let !insns_arr =  mkBCOByteArray $ final_isn_array       !bitmap_arr = mkBCOByteArray $ mkBitmapArray bsize bitmap-      ul_bco = UnlinkedBCO nm arity insns_arr bitmap_arr (fromSizedSeq final_lits) (fromSizedSeq final_ptrs)+      ul_bco = UnlinkedBCO { unlinkedBCOName = nm+                           , unlinkedBCOArity = arity+                           , unlinkedBCOInstrs = insns_arr+                           , unlinkedBCOBitmap = bitmap_arr+                           , unlinkedBCOLits = fromSmallArray final_lit_array+                           , unlinkedBCOPtrs = fromSmallArray final_ptr_array+                           }    -- 8 Aug 01: Finalisers aren't safe when attached to non-primitive   -- objects, since they might get run too early.  Disable this until@@ -229,6 +246,7 @@    return ul_bco +-- | Construct a word-array containing an @StgLargeBitmap@. mkBitmapArray :: Word -> [StgWord] -> UArray Int Word -- Here the return type must be an array of Words, not StgWords, -- because the underlying ByteArray# will end up as a component@@ -237,10 +255,6 @@   = Array.listArray (0, length bitmap) $       fromIntegral bsize : map (fromInteger . fromStgWord) bitmap --- instrs nonptrs ptrs-type AsmState = (SizedSeq Word16,-                 SizedSeq BCONPtr,-                 SizedSeq BCOPtr)  data Operand   = Op Word@@ -260,40 +274,10 @@   PW8 | w <= 4294967295 -> Op (fromIntegral w)   _ -> pprPanic "GHC.ByteCode.Asm.truncHalfWord" (ppr w) -data Assembler a-  = AllocPtr (IO BCOPtr) (Word -> Assembler a)-  | AllocLit [BCONPtr] (Word -> Assembler a)-  | AllocLabel LocalLabel (Assembler a)-  | Emit Word16 [Operand] (Assembler a)-  | NullAsm a-  deriving (Functor) -instance Applicative Assembler where-    pure = NullAsm-    (<*>) = ap--instance Monad Assembler where-  NullAsm x >>= f = f x-  AllocPtr p k >>= f = AllocPtr p (k >=> f)-  AllocLit l k >>= f = AllocLit l (k >=> f)-  AllocLabel lbl k >>= f = AllocLabel lbl (k >>= f)-  Emit w ops k >>= f = Emit w ops (k >>= f)--ioptr :: IO BCOPtr -> Assembler Word-ioptr p = AllocPtr p return--ptr :: BCOPtr -> Assembler Word+ptr :: MonadAssembler m => BCOPtr -> m Word ptr = ioptr . return -lit :: [BCONPtr] -> Assembler Word-lit l = AllocLit l return--label :: LocalLabel -> Assembler ()-label w = AllocLabel w (return ())--emit :: Word16 -> [Operand] -> Assembler ()-emit w ops = Emit w ops (return ())- type LabelEnv = LocalLabel -> Word  largeOp :: Bool -> Operand -> Bool@@ -303,39 +287,143 @@    IOp i     -> isLargeI i    LabelOp _ -> long_jumps -runAsm :: Platform -> Bool -> LabelEnv -> Assembler a -> StateT AsmState IO a-runAsm platform long_jumps e = go+newtype RunAsm a = RunAsm' { runRunAsm :: Bool+                                       -> LabelEnv+                                       -> RunAsmReader+                                       -> AsmState+                                       -> IO (AsmState, a) }++pattern RunAsm :: (Bool -> LabelEnv -> RunAsmReader -> AsmState -> IO (AsmState, a))+                  -> RunAsm a+pattern RunAsm m <- RunAsm' m   where-    go (NullAsm x) = return x-    go (AllocPtr p_io k) = do-      p <- lift p_io-      w <- state $ \(st_i0,st_l0,st_p0) ->-        let st_p1 = addToSS st_p0 p-        in (sizeSS st_p0, (st_i0,st_l0,st_p1))-      go $ k w-    go (AllocLit lits k) = do-      w <- state $ \(st_i0,st_l0,st_p0) ->-        let st_l1 = addListToSS st_l0 lits-        in (sizeSS st_l0, (st_i0,st_l1,st_p0))-      go $ k w-    go (AllocLabel _ k) = go k-    go (Emit w ops k) = do-      let largeArgs = any (largeOp long_jumps) ops-          opcode-            | largeArgs = largeArgInstr w-            | otherwise = w-          words = concatMap expand ops-          expand (SmallOp w) = [w]-          expand (LabelOp w) = expand (Op (e w))-          expand (Op w) = if largeArgs then largeArg platform (fromIntegral w) else [fromIntegral w]-          expand (IOp i) = if largeArgs then largeArg platform (fromIntegral i) else [fromIntegral i]-      state $ \(st_i0,st_l0,st_p0) ->-        let st_i1 = addListToSS st_i0 (opcode : words)-        in ((), (st_i1,st_l0,st_p0))-      go k+    RunAsm m = RunAsm' (oneShot $ \a -> oneShot $ \b -> oneShot $ \c -> oneShot $ \d -> m a b c d)+{-# COMPLETE RunAsm #-} -type LabelEnvMap = Map LocalLabel Word+instance Functor RunAsm where+  fmap f (RunAsm x) = RunAsm (\a b c !s -> fmap (fmap f) (x a b c s)) +instance Applicative RunAsm where+  pure x = RunAsm $ \_ _ _ !s -> pure (s, x)+  (RunAsm f) <*> (RunAsm x) = RunAsm $ \a b c !s -> do+                                  (!s', f') <- f a b c s+                                  (!s'', x') <- x a b c s'+                                  return (s'', f' x')+  {-# INLINE (<*>) #-}+++instance Monad RunAsm where+  return  = pure+  (RunAsm m) >>= f = RunAsm $ \a b c !s -> m a b c s >>= \(s', r) -> runRunAsm (f r) a b c s'+  {-# INLINE (>>=) #-}++runAsm :: Bool -> LabelEnv -> RunAsmReader -> AsmState -> RunAsm a -> IO a+runAsm long_jumps e r s (RunAsm'{runRunAsm}) = fmap snd $ runRunAsm long_jumps e r s++expand :: PlatformWordSize -> Bool -> Operand -> RunAsm ()+expand word_size largeArgs o = do+  e <- askEnv+  case o of+    (SmallOp w) -> writeIsn w+    (LabelOp w) -> let !r = e w in handleLargeArg r+    (Op w) -> handleLargeArg w+    (IOp i) -> handleLargeArg i++  where+    handleLargeArg :: Integral a => a -> RunAsm ()+    handleLargeArg w  =+      if largeArgs+        then largeArg word_size (fromIntegral w)+        else writeIsn (fromIntegral w)++lift :: IO a -> RunAsm a+lift io = RunAsm $ \_ _ _ s -> io >>= \a -> pure (s, a)++askLongJumps :: RunAsm Bool+askLongJumps = RunAsm $ \a _ _ s -> pure (s, a)++askEnv :: RunAsm LabelEnv+askEnv = RunAsm $ \_ b _ s -> pure (s, b)++writePtr :: BCOPtr -> RunAsm Word+writePtr w+            = RunAsm $ \_ _ (RunAsmReader{..}) asm -> do+              writeSmallArrayIO ptr_array (nptr asm) w+              let !n' = nptr asm + 1+              let !asm' = asm { nptr = n' }+              return (asm', fromIntegral (nptr asm))++writeLit :: BCONPtr -> RunAsm Word+writeLit w = RunAsm $ \_ _ (RunAsmReader{..}) asm -> do+              writeSmallArrayIO lit_array (nlit asm) w+              let !n' = nlit asm + 1+              let !asm' = asm { nlit = n' }+              return (asm', fromIntegral (nlit asm))++writeLits :: OneOrTwo BCONPtr -> RunAsm Word+writeLits (OnlyOne l) = writeLit l+writeLits (OnlyTwo l1 l2) = writeLit l1 <* writeLit l2++writeIsn :: Word16 -> RunAsm ()+writeIsn w = RunAsm $ \_ _ (RunAsmReader{..}) asm -> do+#if defined(DEBUG)+              Array.writeArray isn_array (nisn asm) w+#else+              unsafeWrite isn_array (nisn asm) w+#endif+              let !n' = nisn asm + 1+              let !asm' = asm { nisn = n' }+              return (asm', ())++{-# INLINE any #-}+-- Any is unrolled manually so that the call in `emit` can be eliminated without+-- relying on SpecConstr (which does not work across modules).+any :: (a -> Bool) -> [a] -> Bool+any _ [] = False+any f [x] = f x+any f [x,y] = f x || f y+any f [x,y,z] = f x || f y || f z+any f [x1,x2,x3,x4] = f x1 || f x2 || f x3 || f x4+any f [x1,x2,x3,x4, x5] = f x1 || f x2 || f x3 || f x4 || f x5+any f [x1,x2,x3,x4,x5,x6] = f x1 || f x2 || f x3 || f x4 || f x5 || f x6+any f xs = List.any f xs++{-# INLINE mapM6_ #-}+mapM6_ :: Monad m => (a -> m b) -> [a] -> m ()+mapM6_ _ [] = return ()+mapM6_ f [x] = () <$ f x+mapM6_ f [x,y] = () <$ f x <* f y+mapM6_ f [x,y,z] = () <$ f x <* f y <* f z+mapM6_ f [a1,a2,a3,a4] = () <$ f a1 <* f a2 <* f a3 <* f a4+mapM6_ f [a1,a2,a3,a4,a5] = () <$ f a1 <* f a2 <* f a3 <* f a4 <* f a5+mapM6_ f [a1,a2,a3,a4,a5,a6] = () <$ f a1 <* f a2 <* f a3 <* f a4 <* f a5 <* f a6+mapM6_ f xs = mapM_ f xs++instance MonadAssembler RunAsm where+  ioptr p_io = do+    p <- lift p_io+    writePtr p+  lit lits = writeLits lits++  label _ = return ()++  emit pwordsize w ops = do+    long_jumps <- askLongJumps+    -- See the definition of `any` above+    let largeArgs = any (largeOp long_jumps) ops+    let opcode+          | largeArgs = largeArgInstr w+          | otherwise = w+    writeIsn opcode+    mapM6_ (expand pwordsize largeArgs) ops++  {-# INLINE emit #-}+  {-# INLINE label #-}+  {-# INLINE lit #-}+  {-# INLINE ioptr #-}++type LabelEnvMap = UniqFM LocalLabel Word+ data InspectState = InspectState   { instrCount :: !Word   , ptrCount :: !Word@@ -343,74 +431,173 @@   , lblEnv :: LabelEnvMap   } -inspectAsm :: Platform -> Bool -> Word -> Assembler a -> (Word, LabelEnvMap)-inspectAsm platform long_jumps initial_offset-  = go (InspectState initial_offset 0 0 Map.empty)+instance Outputable InspectState where+  ppr (InspectState i p l m) = text "InspectState" <+> ppr [ppr i, ppr p, ppr l, ppr (sizeUFM m)]++isLargeInspectState :: InspectState -> Bool+isLargeInspectState InspectState{..} =+  isLargeW (fromIntegral $ sizeUFM lblEnv)+    || isLargeW instrCount++newtype InspectEnv = InspectEnv { _inspectLongJumps :: Bool+                                }++newtype InspectAsm a = InspectAsm' { runInspectAsm :: InspectEnv -> InspectState -> (# InspectState,  a #) }++pattern InspectAsm :: (InspectEnv -> InspectState -> (# InspectState, a #))+                   -> InspectAsm a+pattern InspectAsm m <- InspectAsm' m   where-    go s (NullAsm _) = (instrCount s, lblEnv s)-    go s (AllocPtr _ k) = go (s { ptrCount = n + 1 }) (k n)-      where n = ptrCount s-    go s (AllocLit ls k) = go (s { litCount = n + genericLength ls }) (k n)-      where n = litCount s-    go s (AllocLabel lbl k) = go s' k-      where s' = s { lblEnv = Map.insert lbl (instrCount s) (lblEnv s) }-    go s (Emit _ ops k) = go s' k-      where-        s' = s { instrCount = instrCount s + size }-        size = sum (map count ops) + 1+    InspectAsm m = InspectAsm' (oneShot $ \a -> oneShot $ \b -> m a b)+{-# COMPLETE InspectAsm #-}++instance Functor InspectAsm where+  fmap f (InspectAsm k) = InspectAsm $ \a b -> case k a b of+                                                  (# b', c #) -> (# b', f c #)++instance Applicative InspectAsm where+  pure x = InspectAsm $ \_ s -> (# s, x #)+  (InspectAsm f) <*> (InspectAsm x) = InspectAsm $ \a b -> case f a b of+                                                              (# s', f' #) ->+                                                                case x a s' of+                                                                  (# s'', x' #) -> (# s'', f' x' #)++instance Monad InspectAsm where+  return = pure+  (InspectAsm m) >>= f = InspectAsm $ \ a b -> case m a b of+                                                (# s', a' #) -> runInspectAsm (f a') a s'++get_ :: InspectAsm InspectState+get_ = InspectAsm $ \_ b -> (# b, b #)++put_ :: InspectState -> InspectAsm ()+put_ !s = InspectAsm $ \_ _ -> (# s, () #)++modify_ :: (InspectState -> InspectState) -> InspectAsm ()+modify_ f = InspectAsm $ \_ s -> let !s' = f s in (# s', () #)++ask_ :: InspectAsm InspectEnv+ask_ = InspectAsm $ \a b -> (# b, a #)++inspectAsm :: Bool -> Word -> InspectAsm () -> InspectState+inspectAsm long_jumps initial_offset (InspectAsm s) =+  case s (InspectEnv long_jumps) (InspectState initial_offset 0 0 emptyUFM) of+    (# res, () #) -> res+{-# INLINE inspectAsm #-}++++instance MonadAssembler InspectAsm where+  ioptr _ = do+    s <- get_+    let n = ptrCount s+    put_ (s { ptrCount = n + 1 })+    return n++  lit ls = do+    s <- get_+    let n = litCount s+    put_ (s { litCount = n + oneTwoLength ls })+    return n++  label lbl = modify_ (\s -> let !count = instrCount s in let !env' = addToUFM (lblEnv s) lbl count in s { lblEnv = env' })++  emit pwordsize _ ops = do+    InspectEnv long_jumps <- ask_+    -- Size is written in this way as `mapM6_` is also used by RunAsm, and guaranteed+    -- to unroll for arguments up to size 6.+    let size = (MTL.execState (mapM6_ (\x -> MTL.modify (count' x +)) ops) 0) + 1         largeOps = any (largeOp long_jumps) ops-        count (SmallOp _) = 1-        count (LabelOp _) = count (Op 0)-        count (Op _) = if largeOps then largeArg16s platform else 1-        count (IOp _) = if largeOps then largeArg16s platform else 1+        bigSize = largeArg16s pwordsize+        count' = if largeOps then countLarge bigSize else countSmall bigSize +    s <- get_+    put_ (s { instrCount = instrCount s + size })++  {-# INLINE emit #-}+  {-# INLINE label #-}+  {-# INLINE lit #-}+  {-# INLINE ioptr #-}++count :: Word -> Bool -> Operand -> Word+count _ _ (SmallOp _)          = 1+count big largeOps (LabelOp _) = if largeOps then big else 1+count big largeOps (Op _)      = if largeOps then big else 1+count big largeOps (IOp _)     = if largeOps then big else 1+{-# INLINE count #-}++countSmall, countLarge :: Word -> Operand -> Word+countLarge big x = count big True x+countSmall big x = count big False x++ -- Bring in all the bci_ bytecode constants. #include "Bytecodes.h"  largeArgInstr :: Word16 -> Word16 largeArgInstr bci = bci_FLAG_LARGE_ARGS .|. bci -largeArg :: Platform -> Word64 -> [Word16]-largeArg platform w = case platformWordSize platform of-   PW8 -> [fromIntegral (w `shiftR` 48),-           fromIntegral (w `shiftR` 32),-           fromIntegral (w `shiftR` 16),-           fromIntegral w]+{-# INLINE largeArg #-}+largeArg :: PlatformWordSize -> Word64 -> RunAsm ()+largeArg wsize w = case wsize of+   PW8 ->  do writeIsn (fromIntegral (w `shiftR` 48))+              writeIsn (fromIntegral (w `shiftR` 32))+              writeIsn (fromIntegral (w `shiftR` 16))+              writeIsn (fromIntegral w)    PW4 -> assertPpr (w < fromIntegral (maxBound :: Word32))-                    (text "largeArg too big:" <+> ppr w) $-          [fromIntegral (w `shiftR` 16),-           fromIntegral w]+                    (text "largeArg too big:" <+> ppr w) $ do+          writeIsn (fromIntegral (w `shiftR` 16))+          writeIsn (fromIntegral w) -largeArg16s :: Platform -> Word-largeArg16s platform = case platformWordSize platform of+largeArg16s :: PlatformWordSize -> Word+largeArg16s pwordsize = case pwordsize of    PW8 -> 4    PW4 -> 2 -assembleI :: Platform+data OneOrTwo a = OnlyOne a | OnlyTwo a a deriving (Functor)++oneTwoLength :: OneOrTwo a -> Word+oneTwoLength (OnlyOne {}) = 1+oneTwoLength (OnlyTwo {}) = 2++class Monad m => MonadAssembler m where+  ioptr :: IO BCOPtr -> m Word+  lit :: OneOrTwo BCONPtr -> m Word+  label :: LocalLabel -> m ()+  emit :: PlatformWordSize -> Word16 -> [Operand] -> m ()++lit1 :: MonadAssembler m => BCONPtr -> m Word+lit1 p = lit (OnlyOne p)++{-# SPECIALISE assembleI :: Platform -> BCInstr -> InspectAsm () #-}+{-# SPECIALISE assembleI :: Platform -> BCInstr -> RunAsm () #-}++assembleI :: forall m . MonadAssembler m+          => Platform           -> BCInstr-          -> Assembler ()+          -> m () assembleI platform i = case i of-  STKCHECK n               -> emit bci_STKCHECK [Op n]-  PUSH_L o1                -> emit bci_PUSH_L [wOp o1]-  PUSH_LL o1 o2            -> emit bci_PUSH_LL [wOp o1, wOp o2]-  PUSH_LLL o1 o2 o3        -> emit bci_PUSH_LLL [wOp o1, wOp o2, wOp o3]-  PUSH8 o1                 -> emit bci_PUSH8 [bOp o1]-  PUSH16 o1                -> emit bci_PUSH16 [bOp o1]-  PUSH32 o1                -> emit bci_PUSH32 [bOp o1]-  PUSH8_W o1               -> emit bci_PUSH8_W [bOp o1]-  PUSH16_W o1              -> emit bci_PUSH16_W [bOp o1]-  PUSH32_W o1              -> emit bci_PUSH32_W [bOp o1]+  STKCHECK n               -> emit_ bci_STKCHECK [Op n]+  PUSH_L o1                -> emit_ bci_PUSH_L [wOp o1]+  PUSH_LL o1 o2            -> emit_ bci_PUSH_LL [wOp o1, wOp o2]+  PUSH_LLL o1 o2 o3        -> emit_ bci_PUSH_LLL [wOp o1, wOp o2, wOp o3]+  PUSH8 o1                 -> emit_ bci_PUSH8 [bOp o1]+  PUSH16 o1                -> emit_ bci_PUSH16 [bOp o1]+  PUSH32 o1                -> emit_ bci_PUSH32 [bOp o1]+  PUSH8_W o1               -> emit_ bci_PUSH8_W [bOp o1]+  PUSH16_W o1              -> emit_ bci_PUSH16_W [bOp o1]+  PUSH32_W o1              -> emit_ bci_PUSH32_W [bOp o1]   PUSH_G nm                -> do p <- ptr (BCOPtrName nm)-                                 emit bci_PUSH_G [Op p]+                                 emit_ bci_PUSH_G [Op p]   PUSH_PRIMOP op           -> do p <- ptr (BCOPtrPrimOp op)-                                 emit bci_PUSH_G [Op p]+                                 emit_ bci_PUSH_G [Op p]   PUSH_BCO proto           -> do let ul_bco = assembleBCO platform proto                                  p <- ioptr (liftM BCOPtrBCO ul_bco)-                                 emit bci_PUSH_G [Op p]+                                 emit_ bci_PUSH_G [Op p]   PUSH_ALTS proto pk                            -> do let ul_bco = assembleBCO platform proto                                  p <- ioptr (liftM BCOPtrBCO ul_bco)-                                 emit (push_alts pk) [Op p]+                                 emit_ (push_alts pk) [Op p]   PUSH_ALTS_TUPLE proto call_info tuple_proto                            -> do let ul_bco = assembleBCO platform proto                                      ul_tuple_bco = assembleBCO platform@@ -419,280 +606,274 @@                                  p_tup <- ioptr (liftM BCOPtrBCO ul_tuple_bco)                                  info <- word (fromIntegral $                                               mkNativeCallInfoSig platform call_info)-                                 emit bci_PUSH_ALTS_T+                                 emit_ bci_PUSH_ALTS_T                                       [Op p, Op info, Op p_tup]-  PUSH_PAD8                -> emit bci_PUSH_PAD8 []-  PUSH_PAD16               -> emit bci_PUSH_PAD16 []-  PUSH_PAD32               -> emit bci_PUSH_PAD32 []+  PUSH_PAD8                -> emit_ bci_PUSH_PAD8 []+  PUSH_PAD16               -> emit_ bci_PUSH_PAD16 []+  PUSH_PAD32               -> emit_ bci_PUSH_PAD32 []   PUSH_UBX8 lit            -> do np <- literal lit-                                 emit bci_PUSH_UBX8 [Op np]+                                 emit_ bci_PUSH_UBX8 [Op np]   PUSH_UBX16 lit           -> do np <- literal lit-                                 emit bci_PUSH_UBX16 [Op np]+                                 emit_ bci_PUSH_UBX16 [Op np]   PUSH_UBX32 lit           -> do np <- literal lit-                                 emit bci_PUSH_UBX32 [Op np]+                                 emit_ bci_PUSH_UBX32 [Op np]   PUSH_UBX lit nws         -> do np <- literal lit-                                 emit bci_PUSH_UBX [Op np, wOp nws]-+                                 emit_ bci_PUSH_UBX [Op np, wOp nws]   -- see Note [Generating code for top-level string literal bindings] in GHC.StgToByteCode-  PUSH_ADDR nm             -> do np <- lit [BCONPtrAddr nm]-                                 emit bci_PUSH_UBX [Op np, SmallOp 1]+  PUSH_ADDR nm             -> do np <- lit1 (BCONPtrAddr nm)+                                 emit_ bci_PUSH_UBX [Op np, SmallOp 1] -  PUSH_APPLY_N             -> emit bci_PUSH_APPLY_N []-  PUSH_APPLY_V             -> emit bci_PUSH_APPLY_V []-  PUSH_APPLY_F             -> emit bci_PUSH_APPLY_F []-  PUSH_APPLY_D             -> emit bci_PUSH_APPLY_D []-  PUSH_APPLY_L             -> emit bci_PUSH_APPLY_L []-  PUSH_APPLY_P             -> emit bci_PUSH_APPLY_P []-  PUSH_APPLY_PP            -> emit bci_PUSH_APPLY_PP []-  PUSH_APPLY_PPP           -> emit bci_PUSH_APPLY_PPP []-  PUSH_APPLY_PPPP          -> emit bci_PUSH_APPLY_PPPP []-  PUSH_APPLY_PPPPP         -> emit bci_PUSH_APPLY_PPPPP []-  PUSH_APPLY_PPPPPP        -> emit bci_PUSH_APPLY_PPPPPP []+  PUSH_APPLY_N             -> emit_ bci_PUSH_APPLY_N []+  PUSH_APPLY_V             -> emit_ bci_PUSH_APPLY_V []+  PUSH_APPLY_F             -> emit_ bci_PUSH_APPLY_F []+  PUSH_APPLY_D             -> emit_ bci_PUSH_APPLY_D []+  PUSH_APPLY_L             -> emit_ bci_PUSH_APPLY_L []+  PUSH_APPLY_P             -> emit_ bci_PUSH_APPLY_P []+  PUSH_APPLY_PP            -> emit_ bci_PUSH_APPLY_PP []+  PUSH_APPLY_PPP           -> emit_ bci_PUSH_APPLY_PPP []+  PUSH_APPLY_PPPP          -> emit_ bci_PUSH_APPLY_PPPP []+  PUSH_APPLY_PPPPP         -> emit_ bci_PUSH_APPLY_PPPPP []+  PUSH_APPLY_PPPPPP        -> emit_ bci_PUSH_APPLY_PPPPPP [] -  SLIDE     n by           -> emit bci_SLIDE [wOp n, wOp by]-  ALLOC_AP  n              -> emit bci_ALLOC_AP [truncHalfWord platform n]-  ALLOC_AP_NOUPD n         -> emit bci_ALLOC_AP_NOUPD [truncHalfWord platform n]-  ALLOC_PAP arity n        -> emit bci_ALLOC_PAP [truncHalfWord platform arity, truncHalfWord platform n]-  MKAP      off sz         -> emit bci_MKAP [wOp off, truncHalfWord platform sz]-  MKPAP     off sz         -> emit bci_MKPAP [wOp off, truncHalfWord platform sz]-  UNPACK    n              -> emit bci_UNPACK [wOp n]-  PACK      dcon sz        -> do itbl_no <- lit [BCONPtrItbl (getName dcon)]-                                 emit bci_PACK [Op itbl_no, wOp sz]+  SLIDE     n by           -> emit_ bci_SLIDE [wOp n, wOp by]+  ALLOC_AP  n              -> emit_ bci_ALLOC_AP [truncHalfWord platform n]+  ALLOC_AP_NOUPD n         -> emit_ bci_ALLOC_AP_NOUPD [truncHalfWord platform n]+  ALLOC_PAP arity n        -> emit_ bci_ALLOC_PAP [truncHalfWord platform arity, truncHalfWord platform n]+  MKAP      off sz         -> emit_ bci_MKAP [wOp off, truncHalfWord platform sz]+  MKPAP     off sz         -> emit_ bci_MKPAP [wOp off, truncHalfWord platform sz]+  UNPACK    n              -> emit_ bci_UNPACK [wOp n]+  PACK      dcon sz        -> do itbl_no <- lit1 (BCONPtrItbl (getName dcon))+                                 emit_ bci_PACK [Op itbl_no, wOp sz]   LABEL     lbl            -> label lbl   TESTLT_I  i l            -> do np <- int i-                                 emit bci_TESTLT_I [Op np, LabelOp l]+                                 emit_ bci_TESTLT_I [Op np, LabelOp l]   TESTEQ_I  i l            -> do np <- int i-                                 emit bci_TESTEQ_I [Op np, LabelOp l]+                                 emit_ bci_TESTEQ_I [Op np, LabelOp l]   TESTLT_W  w l            -> do np <- word w-                                 emit bci_TESTLT_W [Op np, LabelOp l]+                                 emit_ bci_TESTLT_W [Op np, LabelOp l]   TESTEQ_W  w l            -> do np <- word w-                                 emit bci_TESTEQ_W [Op np, LabelOp l]+                                 emit_ bci_TESTEQ_W [Op np, LabelOp l]   TESTLT_I64  i l          -> do np <- word64 (fromIntegral i)-                                 emit bci_TESTLT_I64 [Op np, LabelOp l]+                                 emit_ bci_TESTLT_I64 [Op np, LabelOp l]   TESTEQ_I64  i l          -> do np <- word64 (fromIntegral i)-                                 emit bci_TESTEQ_I64 [Op np, LabelOp l]+                                 emit_ bci_TESTEQ_I64 [Op np, LabelOp l]   TESTLT_I32  i l          -> do np <- word (fromIntegral i)-                                 emit bci_TESTLT_I32 [Op np, LabelOp l]+                                 emit_ bci_TESTLT_I32 [Op np, LabelOp l]   TESTEQ_I32 i l           -> do np <- word (fromIntegral i)-                                 emit bci_TESTEQ_I32 [Op np, LabelOp l]+                                 emit_ bci_TESTEQ_I32 [Op np, LabelOp l]   TESTLT_I16  i l          -> do np <- word (fromIntegral i)-                                 emit bci_TESTLT_I16 [Op np, LabelOp l]+                                 emit_ bci_TESTLT_I16 [Op np, LabelOp l]   TESTEQ_I16 i l           -> do np <- word (fromIntegral i)-                                 emit bci_TESTEQ_I16 [Op np, LabelOp l]+                                 emit_ bci_TESTEQ_I16 [Op np, LabelOp l]   TESTLT_I8  i l           -> do np <- word (fromIntegral i)-                                 emit bci_TESTLT_I8 [Op np, LabelOp l]+                                 emit_ bci_TESTLT_I8 [Op np, LabelOp l]   TESTEQ_I8 i l            -> do np <- word (fromIntegral i)-                                 emit bci_TESTEQ_I8 [Op np, LabelOp l]+                                 emit_ bci_TESTEQ_I8 [Op np, LabelOp l]   TESTLT_W64  w l          -> do np <- word64 w-                                 emit bci_TESTLT_W64 [Op np, LabelOp l]+                                 emit_ bci_TESTLT_W64 [Op np, LabelOp l]   TESTEQ_W64  w l          -> do np <- word64 w-                                 emit bci_TESTEQ_W64 [Op np, LabelOp l]+                                 emit_ bci_TESTEQ_W64 [Op np, LabelOp l]   TESTLT_W32  w l          -> do np <- word (fromIntegral w)-                                 emit bci_TESTLT_W32 [Op np, LabelOp l]+                                 emit_ bci_TESTLT_W32 [Op np, LabelOp l]   TESTEQ_W32  w l          -> do np <- word (fromIntegral w)-                                 emit bci_TESTEQ_W32 [Op np, LabelOp l]+                                 emit_ bci_TESTEQ_W32 [Op np, LabelOp l]   TESTLT_W16  w l          -> do np <- word (fromIntegral w)-                                 emit bci_TESTLT_W16 [Op np, LabelOp l]+                                 emit_ bci_TESTLT_W16 [Op np, LabelOp l]   TESTEQ_W16  w l          -> do np <- word (fromIntegral w)-                                 emit bci_TESTEQ_W16 [Op np, LabelOp l]+                                 emit_ bci_TESTEQ_W16 [Op np, LabelOp l]   TESTLT_W8  w l           -> do np <- word (fromIntegral w)-                                 emit bci_TESTLT_W8 [Op np, LabelOp l]+                                 emit_ bci_TESTLT_W8 [Op np, LabelOp l]   TESTEQ_W8  w l           -> do np <- word (fromIntegral w)-                                 emit bci_TESTEQ_W8 [Op np, LabelOp l]+                                 emit_ bci_TESTEQ_W8 [Op np, LabelOp l]   TESTLT_F  f l            -> do np <- float f-                                 emit bci_TESTLT_F [Op np, LabelOp l]+                                 emit_ bci_TESTLT_F [Op np, LabelOp l]   TESTEQ_F  f l            -> do np <- float f-                                 emit bci_TESTEQ_F [Op np, LabelOp l]+                                 emit_ bci_TESTEQ_F [Op np, LabelOp l]   TESTLT_D  d l            -> do np <- double d-                                 emit bci_TESTLT_D [Op np, LabelOp l]+                                 emit_ bci_TESTLT_D [Op np, LabelOp l]   TESTEQ_D  d l            -> do np <- double d-                                 emit bci_TESTEQ_D [Op np, LabelOp l]-  TESTLT_P  i l            -> emit bci_TESTLT_P [SmallOp i, LabelOp l]-  TESTEQ_P  i l            -> emit bci_TESTEQ_P [SmallOp i, LabelOp l]-  CASEFAIL                 -> emit bci_CASEFAIL []-  SWIZZLE   stkoff n       -> emit bci_SWIZZLE [wOp stkoff, IOp n]-  JMP       l              -> emit bci_JMP [LabelOp l]-  ENTER                    -> emit bci_ENTER []-  RETURN rep               -> emit (return_non_tuple rep) []-  RETURN_TUPLE             -> emit bci_RETURN_T []-  CCALL off m_addr i       -> do np <- addr m_addr-                                 emit bci_CCALL [wOp off, Op np, SmallOp i]-  PRIMCALL                 -> emit bci_PRIMCALL []+                                 emit_ bci_TESTEQ_D [Op np, LabelOp l]+  TESTLT_P  i l            -> emit_ bci_TESTLT_P [SmallOp i, LabelOp l]+  TESTEQ_P  i l            -> emit_ bci_TESTEQ_P [SmallOp i, LabelOp l]+  CASEFAIL                 -> emit_ bci_CASEFAIL []+  SWIZZLE   stkoff n       -> emit_ bci_SWIZZLE [wOp stkoff, IOp n]+  JMP       l              -> emit_ bci_JMP [LabelOp l]+  ENTER                    -> emit_ bci_ENTER []+  RETURN rep               -> emit_ (return_non_tuple rep) []+  RETURN_TUPLE             -> emit_ bci_RETURN_T []+  CCALL off ffi i          -> do np <- lit1 $ BCONPtrFFIInfo ffi+                                 emit_ bci_CCALL [wOp off, Op np, SmallOp i]+  PRIMCALL                 -> emit_ bci_PRIMCALL []    OP_ADD w -> case w of-    W64                   -> emit bci_OP_ADD_64 []-    W32                   -> emit bci_OP_ADD_32 []-    W16                   -> emit bci_OP_ADD_16 []-    W8                    -> emit bci_OP_ADD_08 []+    W64                   -> emit_ bci_OP_ADD_64 []+    W32                   -> emit_ bci_OP_ADD_32 []+    W16                   -> emit_ bci_OP_ADD_16 []+    W8                    -> emit_ bci_OP_ADD_08 []     _                     -> unsupported_width   OP_SUB w -> case w of-    W64                   -> emit bci_OP_SUB_64 []-    W32                   -> emit bci_OP_SUB_32 []-    W16                   -> emit bci_OP_SUB_16 []-    W8                    -> emit bci_OP_SUB_08 []+    W64                   -> emit_ bci_OP_SUB_64 []+    W32                   -> emit_ bci_OP_SUB_32 []+    W16                   -> emit_ bci_OP_SUB_16 []+    W8                    -> emit_ bci_OP_SUB_08 []     _                     -> unsupported_width   OP_AND w -> case w of-    W64                   -> emit bci_OP_AND_64 []-    W32                   -> emit bci_OP_AND_32 []-    W16                   -> emit bci_OP_AND_16 []-    W8                    -> emit bci_OP_AND_08 []+    W64                   -> emit_ bci_OP_AND_64 []+    W32                   -> emit_ bci_OP_AND_32 []+    W16                   -> emit_ bci_OP_AND_16 []+    W8                    -> emit_ bci_OP_AND_08 []     _                     -> unsupported_width   OP_XOR w -> case w of-    W64                   -> emit bci_OP_XOR_64 []-    W32                   -> emit bci_OP_XOR_32 []-    W16                   -> emit bci_OP_XOR_16 []-    W8                    -> emit bci_OP_XOR_08 []+    W64                   -> emit_ bci_OP_XOR_64 []+    W32                   -> emit_ bci_OP_XOR_32 []+    W16                   -> emit_ bci_OP_XOR_16 []+    W8                    -> emit_ bci_OP_XOR_08 []     _                     -> unsupported_width   OP_OR w -> case w of-    W64                    -> emit bci_OP_OR_64 []-    W32                    -> emit bci_OP_OR_32 []-    W16                    -> emit bci_OP_OR_16 []-    W8                     -> emit bci_OP_OR_08 []+    W64                    -> emit_ bci_OP_OR_64 []+    W32                    -> emit_ bci_OP_OR_32 []+    W16                    -> emit_ bci_OP_OR_16 []+    W8                     -> emit_ bci_OP_OR_08 []     _                      -> unsupported_width   OP_NOT w -> case w of-    W64                   -> emit bci_OP_NOT_64 []-    W32                   -> emit bci_OP_NOT_32 []-    W16                   -> emit bci_OP_NOT_16 []-    W8                    -> emit bci_OP_NOT_08 []+    W64                   -> emit_ bci_OP_NOT_64 []+    W32                   -> emit_ bci_OP_NOT_32 []+    W16                   -> emit_ bci_OP_NOT_16 []+    W8                    -> emit_ bci_OP_NOT_08 []     _                     -> unsupported_width   OP_NEG w -> case w of-    W64                   -> emit bci_OP_NEG_64 []-    W32                   -> emit bci_OP_NEG_32 []-    W16                   -> emit bci_OP_NEG_16 []-    W8                    -> emit bci_OP_NEG_08 []+    W64                   -> emit_ bci_OP_NEG_64 []+    W32                   -> emit_ bci_OP_NEG_32 []+    W16                   -> emit_ bci_OP_NEG_16 []+    W8                    -> emit_ bci_OP_NEG_08 []     _                     -> unsupported_width   OP_MUL w -> case w of-    W64                   -> emit bci_OP_MUL_64 []-    W32                   -> emit bci_OP_MUL_32 []-    W16                   -> emit bci_OP_MUL_16 []-    W8                    -> emit bci_OP_MUL_08 []+    W64                   -> emit_ bci_OP_MUL_64 []+    W32                   -> emit_ bci_OP_MUL_32 []+    W16                   -> emit_ bci_OP_MUL_16 []+    W8                    -> emit_ bci_OP_MUL_08 []     _                     -> unsupported_width   OP_SHL w -> case w of-    W64                   -> emit bci_OP_SHL_64 []-    W32                   -> emit bci_OP_SHL_32 []-    W16                   -> emit bci_OP_SHL_16 []-    W8                    -> emit bci_OP_SHL_08 []+    W64                   -> emit_ bci_OP_SHL_64 []+    W32                   -> emit_ bci_OP_SHL_32 []+    W16                   -> emit_ bci_OP_SHL_16 []+    W8                    -> emit_ bci_OP_SHL_08 []     _                     -> unsupported_width   OP_ASR w -> case w of-    W64                   -> emit bci_OP_ASR_64 []-    W32                   -> emit bci_OP_ASR_32 []-    W16                   -> emit bci_OP_ASR_16 []-    W8                    -> emit bci_OP_ASR_08 []+    W64                   -> emit_ bci_OP_ASR_64 []+    W32                   -> emit_ bci_OP_ASR_32 []+    W16                   -> emit_ bci_OP_ASR_16 []+    W8                    -> emit_ bci_OP_ASR_08 []     _                     -> unsupported_width   OP_LSR w -> case w of-    W64                   -> emit bci_OP_LSR_64 []-    W32                   -> emit bci_OP_LSR_32 []-    W16                   -> emit bci_OP_LSR_16 []-    W8                    -> emit bci_OP_LSR_08 []+    W64                   -> emit_ bci_OP_LSR_64 []+    W32                   -> emit_ bci_OP_LSR_32 []+    W16                   -> emit_ bci_OP_LSR_16 []+    W8                    -> emit_ bci_OP_LSR_08 []     _                     -> unsupported_width    OP_NEQ w -> case w of-    W64                   -> emit bci_OP_NEQ_64 []-    W32                   -> emit bci_OP_NEQ_32 []-    W16                   -> emit bci_OP_NEQ_16 []-    W8                    -> emit bci_OP_NEQ_08 []+    W64                   -> emit_ bci_OP_NEQ_64 []+    W32                   -> emit_ bci_OP_NEQ_32 []+    W16                   -> emit_ bci_OP_NEQ_16 []+    W8                    -> emit_ bci_OP_NEQ_08 []     _                     -> unsupported_width   OP_EQ w -> case w of-    W64                    -> emit bci_OP_EQ_64 []-    W32                    -> emit bci_OP_EQ_32 []-    W16                    -> emit bci_OP_EQ_16 []-    W8                     -> emit bci_OP_EQ_08 []+    W64                    -> emit_ bci_OP_EQ_64 []+    W32                    -> emit_ bci_OP_EQ_32 []+    W16                    -> emit_ bci_OP_EQ_16 []+    W8                     -> emit_ bci_OP_EQ_08 []     _                      -> unsupported_width    OP_U_LT w -> case w of-    W64                  -> emit bci_OP_U_LT_64 []-    W32                  -> emit bci_OP_U_LT_32 []-    W16                  -> emit bci_OP_U_LT_16 []-    W8                   -> emit bci_OP_U_LT_08 []+    W64                  -> emit_ bci_OP_U_LT_64 []+    W32                  -> emit_ bci_OP_U_LT_32 []+    W16                  -> emit_ bci_OP_U_LT_16 []+    W8                   -> emit_ bci_OP_U_LT_08 []     _                    -> unsupported_width   OP_S_LT w -> case w of-    W64                  -> emit bci_OP_S_LT_64 []-    W32                  -> emit bci_OP_S_LT_32 []-    W16                  -> emit bci_OP_S_LT_16 []-    W8                   -> emit bci_OP_S_LT_08 []+    W64                  -> emit_ bci_OP_S_LT_64 []+    W32                  -> emit_ bci_OP_S_LT_32 []+    W16                  -> emit_ bci_OP_S_LT_16 []+    W8                   -> emit_ bci_OP_S_LT_08 []     _                    -> unsupported_width   OP_U_GE w -> case w of-    W64                  -> emit bci_OP_U_GE_64 []-    W32                  -> emit bci_OP_U_GE_32 []-    W16                  -> emit bci_OP_U_GE_16 []-    W8                   -> emit bci_OP_U_GE_08 []+    W64                  -> emit_ bci_OP_U_GE_64 []+    W32                  -> emit_ bci_OP_U_GE_32 []+    W16                  -> emit_ bci_OP_U_GE_16 []+    W8                   -> emit_ bci_OP_U_GE_08 []     _                    -> unsupported_width   OP_S_GE w -> case w of-    W64                  -> emit bci_OP_S_GE_64 []-    W32                  -> emit bci_OP_S_GE_32 []-    W16                  -> emit bci_OP_S_GE_16 []-    W8                   -> emit bci_OP_S_GE_08 []+    W64                  -> emit_ bci_OP_S_GE_64 []+    W32                  -> emit_ bci_OP_S_GE_32 []+    W16                  -> emit_ bci_OP_S_GE_16 []+    W8                   -> emit_ bci_OP_S_GE_08 []     _                    -> unsupported_width   OP_U_GT w -> case w of-    W64                  -> emit bci_OP_U_GT_64 []-    W32                  -> emit bci_OP_U_GT_32 []-    W16                  -> emit bci_OP_U_GT_16 []-    W8                   -> emit bci_OP_U_GT_08 []+    W64                  -> emit_ bci_OP_U_GT_64 []+    W32                  -> emit_ bci_OP_U_GT_32 []+    W16                  -> emit_ bci_OP_U_GT_16 []+    W8                   -> emit_ bci_OP_U_GT_08 []     _                    -> unsupported_width   OP_S_GT w -> case w of-    W64                  -> emit bci_OP_S_GT_64 []-    W32                  -> emit bci_OP_S_GT_32 []-    W16                  -> emit bci_OP_S_GT_16 []-    W8                   -> emit bci_OP_S_GT_08 []+    W64                  -> emit_ bci_OP_S_GT_64 []+    W32                  -> emit_ bci_OP_S_GT_32 []+    W16                  -> emit_ bci_OP_S_GT_16 []+    W8                   -> emit_ bci_OP_S_GT_08 []     _                    -> unsupported_width   OP_U_LE w -> case w of-    W64                  -> emit bci_OP_U_LE_64 []-    W32                  -> emit bci_OP_U_LE_32 []-    W16                  -> emit bci_OP_U_LE_16 []-    W8                   -> emit bci_OP_U_LE_08 []+    W64                  -> emit_ bci_OP_U_LE_64 []+    W32                  -> emit_ bci_OP_U_LE_32 []+    W16                  -> emit_ bci_OP_U_LE_16 []+    W8                   -> emit_ bci_OP_U_LE_08 []     _                    -> unsupported_width   OP_S_LE w -> case w of-    W64                  -> emit bci_OP_S_LE_64 []-    W32                  -> emit bci_OP_S_LE_32 []-    W16                  -> emit bci_OP_S_LE_16 []-    W8                   -> emit bci_OP_S_LE_08 []+    W64                  -> emit_ bci_OP_S_LE_64 []+    W32                  -> emit_ bci_OP_S_LE_32 []+    W16                  -> emit_ bci_OP_S_LE_16 []+    W8                   -> emit_ bci_OP_S_LE_08 []     _                    -> unsupported_width    OP_INDEX_ADDR w -> case w of-    W64                  -> emit bci_OP_INDEX_ADDR_64 []-    W32                  -> emit bci_OP_INDEX_ADDR_32 []-    W16                  -> emit bci_OP_INDEX_ADDR_16 []-    W8                   -> emit bci_OP_INDEX_ADDR_08 []+    W64                  -> emit_ bci_OP_INDEX_ADDR_64 []+    W32                  -> emit_ bci_OP_INDEX_ADDR_32 []+    W16                  -> emit_ bci_OP_INDEX_ADDR_16 []+    W8                   -> emit_ bci_OP_INDEX_ADDR_08 []     _                    -> unsupported_width -  BRK_FUN arr tick_mod tickx info_mod infox cc ->-                              do p1 <- ptr (BCOPtrBreakArray arr)-                                 tick_addr <- addr tick_mod-                                 info_addr <- addr info_mod-                                 np <- addr cc-                                 let -- cast that checks that round-tripping through-                                     -- Word32 doesn't change the value-                                     toW32 x = let r = fromIntegral x :: Word32-                                                in if fromIntegral r == x-                                                  then r-                                                  else pprPanic "schemeER_wrk: breakpoint tick/info index too large!" (ppr x)-                                     tick32 = toW32 tickx-                                     tick_hi = fromIntegral (tick32 `shiftR` 16)-                                     tick_lo = fromIntegral (tick32 .&. 0xffff)-                                     info32 = toW32 infox-                                     info_hi = fromIntegral (info32 `shiftR` 16)-                                     info_lo = fromIntegral (info32 .&. 0xffff)-                                 emit bci_BRK_FUN [ Op p1-                                                  , Op tick_addr, Op info_addr-                                                  , SmallOp tick_hi, SmallOp tick_lo-                                                  , SmallOp info_hi, SmallOp info_lo-                                                  , Op np-                                                  ]+  BRK_FUN ibi@(InternalBreakpointId info_mod infox) -> do+    p1 <- ptr $ BCOPtrBreakArray info_mod+    let -- cast that checks that round-tripping through Word32 doesn't change the value+        infoW32 = let r = fromIntegral infox :: Word32+                   in if fromIntegral r == infox+                    then r+                    else pprPanic "schemeER_wrk: breakpoint tick/info index too large!" (ppr infox)+        ix_hi = fromIntegral (infoW32 `shiftR` 16)+        ix_lo = fromIntegral (infoW32 .&. 0xffff)+    info_addr        <- lit1 $ BCONPtrFS $ moduleNameFS $ moduleName info_mod+    info_unitid_addr <- lit1 $ BCONPtrFS $ unitIdFS     $ moduleUnitId info_mod+    np               <- lit1 $ BCONPtrCostCentre ibi+    emit_ bci_BRK_FUN [ Op p1, Op info_addr, Op info_unitid_addr+                      , SmallOp ix_hi, SmallOp ix_lo, Op np ]  #if MIN_VERSION_rts(1,0,3)-  BCO_NAME name            -> do np <- lit [BCONPtrStr name]-                                 emit bci_BCO_NAME [Op np]+  BCO_NAME name            -> do np <- lit1 (BCONPtrStr name)+                                 emit_ bci_BCO_NAME [Op np] #endif ++   where     unsupported_width = panic "GHC.ByteCode.Asm: Unsupported Width"+    emit_ = emit word_size +    literal :: Literal -> m Word     literal (LitLabel fs _)   = litlabel fs     literal LitNullAddr       = word 0     literal (LitFloat r)      = float (fromRational r)     literal (LitDouble r)     = double (fromRational r)     literal (LitChar c)       = int (ord c)-    literal (LitString bs)    = lit [BCONPtrStr bs]+    literal (LitString bs)    = lit1 (BCONPtrStr bs)        -- LitString requires a zero-terminator when emitted     literal (LitNumber nt i) = case nt of       LitNumInt     -> word (fromIntegral i)@@ -712,10 +893,10 @@     -- analysis messed up.     literal (LitRubbish {}) = word 0 -    litlabel fs = lit [BCONPtrLbl fs]-    addr (RemotePtr a) = words [fromIntegral a]-    words ws = lit (map BCONPtrWord ws)-    word w = words [w]+    litlabel fs = lit1 (BCONPtrLbl fs)+    words ws = lit (fmap BCONPtrWord ws)+    word w = words (OnlyOne w)+    word2 w1 w2 = words (OnlyTwo w1 w2)     word_size  = platformWordSize platform     word_size_bits = platformWordSizeInBits platform @@ -726,36 +907,36 @@     -- Note that we only support host endianness == target endianness for now,     -- even with the external interpreter. This would need to be fixed to     -- support host endianness /= target endianness-    int :: Int -> Assembler Word+    int :: Int -> m Word     int  i = word (fromIntegral i) -    float :: Float -> Assembler Word+    float :: Float -> m Word     float f = word32 (castFloatToWord32 f) -    double :: Double -> Assembler Word+    double :: Double -> m Word     double d = word64 (castDoubleToWord64 d) -    word64 :: Word64 -> Assembler Word+    word64 :: Word64 -> m Word     word64 ww = case word_size of        PW4 ->         let !wl = fromIntegral ww             !wh = fromIntegral (ww `unsafeShiftR` 32)         in case platformByteOrder platform of-            LittleEndian -> words [wl,wh]-            BigEndian    -> words [wh,wl]+            LittleEndian -> word2 wl wh+            BigEndian    -> word2 wh wl        PW8 -> word (fromIntegral ww) -    word8 :: Word8 -> Assembler Word+    word8 :: Word8 -> m Word     word8  x = case platformByteOrder platform of       LittleEndian -> word (fromIntegral x)       BigEndian    -> word (fromIntegral x `unsafeShiftL` (word_size_bits - 8)) -    word16 :: Word16 -> Assembler Word+    word16 :: Word16 -> m Word     word16 x = case platformByteOrder platform of       LittleEndian -> word (fromIntegral x)       BigEndian    -> word (fromIntegral x `unsafeShiftL` (word_size_bits - 16)) -    word32 :: Word32 -> Assembler Word+    word32 :: Word32 -> m Word     word32 x = case platformByteOrder platform of       LittleEndian -> word (fromIntegral x)       BigEndian    -> case word_size of
+ GHC/ByteCode/Breakpoints.hs view
@@ -0,0 +1,299 @@+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE DerivingStrategies #-}++-- | Breakpoint information constructed during ByteCode generation.+--+-- Specifically, code-generation breakpoints are referred to as "internal+-- breakpoints", the internal breakpoint data for a module is stored in+-- 'InternalModBreaks', and is uniquely identified at runtime by an+-- 'InternalBreakpointId'.+--+-- See Note [ModBreaks vs InternalModBreaks] and Note [Breakpoint identifiers]+module GHC.ByteCode.Breakpoints+  ( -- * Internal Mod Breaks+    InternalModBreaks(..), CgBreakInfo(..)+  , mkInternalModBreaks, imodBreaks_module++    -- ** Internal breakpoint identifier+  , InternalBreakpointId(..), BreakInfoIndex+  , InternalBreakLoc(..)++    -- * Operations++    -- ** Internal-level operations+  , getInternalBreak++    -- ** Source-level information operations+  , getBreakLoc, getBreakVars, getBreakDecls, getBreakCCS+  , getBreakSourceId, getBreakSourceMod++    -- * Utils+  , seqInternalModBreaks++  )+  where++import GHC.Prelude+import GHC.Types.SrcLoc+import GHC.Types.Name.Occurrence+import Control.DeepSeq+import Data.IntMap.Strict (IntMap)+import qualified Data.IntMap.Strict as IM++import GHC.HsToCore.Breakpoints+import GHC.Iface.Syntax++import GHC.Unit.Module (Module)+import GHC.Utils.Outputable+import GHC.Utils.Panic+import Data.Array++{-+Note [ModBreaks vs InternalModBreaks]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+'ModBreaks' and 'BreakpointId's must not to be confused with+'InternalModBreaks' and 'InternalBreakId's.++'ModBreaks' is constructed once during HsToCore from the information attached+to source-level breakpoint ticks and is never changed afterwards. A 'ModBreaks'+can be queried using 'BreakpointId's, which uniquely identifies a breakpoint+within the list of breakpoint information for a given module's 'ModBreaks'.++'InternalModBreaks' are constructed during bytecode generation and are indexed+by a 'InternalBreakpointId'. They contain all the information relevant to a+breakpoint for code generation that can be accessed during runtime execution+(such as a 'BreakArray' for triggering breakpoints). 'InternalBreakpointId's+are used at runtime to trigger and inspect breakpoints -- a 'BRK_FUN'+instruction receives 'InternalBreakpointId' as an argument.++We keep a mapping from 'InternalModBreaks' to a 'BreakpointId', which can then be used+to get source-level information about a breakpoint via the corresponding 'ModBreaks'.++Notably, 'InternalModBreaks' can contain entries for so-called internal+breakpoints, which do not necessarily have a source-level location attached to+it (i.e. do not have a matching entry in 'ModBreaks'). We may leverage this to+introduce breakpoints during code generation for features such as stepping-out.++Note [Breakpoint identifiers]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+Before optimization a breakpoint is identified uniquely with a tick module+and a tick index. See 'BreakpointId'. A tick module contains an array, indexed+with the tick indexes, which indicates breakpoint status.++When we generate ByteCode, we collect information for every breakpoint at+their *occurrence sites* (see CgBreakInfo) and these info+are stored in the ModIface of the occurrence module. Because of inlining, we+can't reuse the tick index to uniquely identify an occurrence; because of+cross-module inlining, we can't assume that the occurrence module is the same+as the tick module (#24712).++So every breakpoint occurrence gets assigned a module-unique *info index* and+we store it alongside the occurrence module (*info module*) in the+'InternalBreakpointId' datatype. This is the index that we use at runtime to+identify a breakpoint.++When the internal breakpoint has a matching tick-level breakpoint we can fetch+the related tick-level information by first looking up a mapping+@'InternalBreakpointId' -> 'BreakpointId'@ in @'CgBreakInfo'@.+-}++--------------------------------------------------------------------------------+-- * Internal breakpoint identifiers+--------------------------------------------------------------------------------++-- | Internal breakpoint info index+type BreakInfoIndex = Int++-- | Internal breakpoint identifier+--+-- Indexes into the structures in the @'InternalModBreaks'@ produced during ByteCode generation.+-- See Note [Breakpoint identifiers]+data InternalBreakpointId = InternalBreakpointId+  { ibi_info_mod   :: !Module         -- ^ Breakpoint info module+  , ibi_info_index :: !BreakInfoIndex -- ^ Breakpoint info index+  }+  deriving (Eq, Ord)++--------------------------------------------------------------------------------+-- * Internal Mod Breaks+--------------------------------------------------------------------------------++-- | Internal mod breaks store the runtime-relevant information of breakpoints.+--+-- Importantly, it maps 'InternalBreakpointId's to 'CgBreakInfo'.+--+-- 'InternalModBreaks' are constructed during bytecode generation and stored in+-- 'CompiledByteCode' afterwards.+data InternalModBreaks = InternalModBreaks+      { imodBreaks_breakInfo :: !(IntMap CgBreakInfo)+        -- ^ Access code-gen time information about a breakpoint, indexed by+        -- 'InternalBreakpointId'.++      , imodBreaks_modBreaks :: !ModBreaks+        -- ^ Store the ModBreaks for this module+        --+        -- Recall Note [Breakpoint identifiers]: for some module A, an+        -- *occurrence* of a breakpoint in A may have been inlined from some+        -- breakpoint *defined* in module B.+        --+        -- This 'ModBreaks' contains information regarding all the breakpoints+        -- defined in the module this 'InternalModBreaks' corresponds to. It+        -- /does not/ necessarily have information regarding all the breakpoint+        -- occurrences registered in 'imodBreaks_breakInfo'. Some of those+        -- occurrences may refer breakpoints inlined from other modules.+      }++-- | Construct an 'InternalModBreaks'.+--+-- INVARIANT: The given 'ModBreaks' correspond to the same module as this+-- 'InternalModBreaks' module (the first argument) and its breakpoint infos+-- (the @IntMap CgBreakInfo@ argument)+mkInternalModBreaks :: Module -> IntMap CgBreakInfo -> ModBreaks -> InternalModBreaks+mkInternalModBreaks mod im mbs =+  assertPpr (mod == modBreaks_module mbs)+    (text "Constructing InternalModBreaks with the ModBreaks of a different module!") $+      InternalModBreaks im mbs++-- | Get the module to which these 'InternalModBreaks' correspond+imodBreaks_module :: InternalModBreaks -> Module+imodBreaks_module = modBreaks_module . imodBreaks_modBreaks++-- | Information about a breakpoint that we know at code-generation time+-- In order to be used, this needs to be hydrated relative to the current HscEnv by+-- 'hydrateCgBreakInfo'. Everything here can be fully forced and that's critical for+-- preventing space leaks (see #22530)+data CgBreakInfo+   = CgBreakInfo+   { cgb_tyvars  :: ![IfaceTvBndr] -- ^ Type variables in scope at the breakpoint+   , cgb_vars    :: ![Maybe (IfaceIdBndr, Word)]+   , cgb_resty   :: !IfaceType+   , cgb_tick_id :: !(Either InternalBreakLoc BreakpointId)+     -- ^ This field records the original breakpoint tick identifier for this+     -- internal breakpoint info. It is used to convert a breakpoint+     -- *occurrence* index ('InternalBreakpointId') into a *definition* index+     -- ('BreakpointId').+     --+     -- The modules of breakpoint occurrence and breakpoint definition are not+     -- necessarily the same: See Note [Breakpoint identifiers].+     --+     -- If there is no original tick identifier (that is, the breakpoint was+     -- created during code generation), we re-use the BreakpointId of something else.+     -- It would also be reasonable to have an @Either something BreakpointId@+     -- for @cgb_tick_id@, but currently we can always re-use a source-level BreakpointId.+     -- In the case of step-out, see Note [Debugger: Stepout internal break locs]+   }+-- See Note [Syncing breakpoint info] in GHC.Runtime.Eval++-- | Breakpoints created during code generation don't have a source-level tick+-- location. Instead, we re-use an existing one.+newtype InternalBreakLoc = InternalBreakLoc { internalBreakLoc :: BreakpointId }+  deriving newtype (Eq, NFData, Outputable)++-- | Get an internal breakpoint info by 'InternalBreakpointId'+getInternalBreak :: InternalBreakpointId -> InternalModBreaks -> CgBreakInfo+getInternalBreak (InternalBreakpointId mod ix) imbs =+  assert_modules_match mod (imodBreaks_module imbs) $+    imodBreaks_breakInfo imbs IM.! ix++-- | Assert that the module in the 'InternalBreakpointId' and in+-- 'InternalModBreaks' match.+assert_modules_match :: Module -> Module -> a -> a+assert_modules_match ibi_mod imbs_mod =+  assertPpr (ibi_mod == imbs_mod)+    (text "Tried to query the InternalModBreaks of module" <+> ppr imbs_mod+        <+> text "with an InternalBreakpointId for module" <+> ppr ibi_mod)++--------------------------------------------------------------------------------+-- Tick-level Breakpoint information+--------------------------------------------------------------------------------++-- | Get the source module and tick index for this breakpoint+-- (as opposed to the module where this breakpoint occurs, which is in 'InternalBreakpointId')+getBreakSourceId :: InternalBreakpointId -> InternalModBreaks -> BreakpointId+getBreakSourceId (InternalBreakpointId ibi_mod ibi_ix) imbs =+  assert_modules_match ibi_mod (imodBreaks_module imbs) $+    let cgb = imodBreaks_breakInfo imbs IM.! ibi_ix+     in either internalBreakLoc id (cgb_tick_id cgb)++-- | Get the source module for this breakpoint (where the breakpoint is defined)+getBreakSourceMod :: InternalBreakpointId -> InternalModBreaks -> Module+getBreakSourceMod (InternalBreakpointId ibi_mod ibi_ix) imbs =+  assert_modules_match ibi_mod (imodBreaks_module imbs) $+    let cgb = imodBreaks_breakInfo imbs IM.! ibi_ix+     in either (bi_tick_mod . internalBreakLoc) bi_tick_mod (cgb_tick_id cgb)++-- | Get the source span for this breakpoint+getBreakLoc :: (Module -> IO ModBreaks) -> InternalBreakpointId -> InternalModBreaks -> IO SrcSpan+getBreakLoc = getBreakXXX modBreaks_locs++-- | Get the vars for this breakpoint+getBreakVars :: (Module -> IO ModBreaks) -> InternalBreakpointId -> InternalModBreaks -> IO [OccName]+getBreakVars = getBreakXXX modBreaks_vars++-- | Get the decls for this breakpoint+getBreakDecls :: (Module -> IO ModBreaks) -> InternalBreakpointId -> InternalModBreaks -> IO [String]+getBreakDecls = getBreakXXX modBreaks_decls++-- | Get the decls for this breakpoint+getBreakCCS :: (Module -> IO ModBreaks) -> InternalBreakpointId -> InternalModBreaks -> IO ((String, String))+getBreakCCS = getBreakXXX modBreaks_ccs++-- | Internal utility to access a ModBreaks field at a particular breakpoint index+--+-- Recall Note [Breakpoint identifiers]: the internal breakpoint module (the+-- *occurrence* module) doesn't necessarily match the module where the+-- tick breakpoint was defined with the relevant 'ModBreaks'.+--+-- When the tick module is the same as the internal module, we use the stored+-- 'ModBreaks'. When the tick module is different, we need to look up the+-- 'ModBreaks' in the HUG for that other module.+--+-- When there is no tick module (the breakpoint was generated at codegen), use+-- the function on internal mod breaks.+--+-- To avoid cyclic dependencies, we instead receive a function that looks up+-- the 'ModBreaks' given a 'Module'+getBreakXXX :: (ModBreaks -> Array BreakTickIndex a) -> (Module -> IO ModBreaks) -> InternalBreakpointId -> InternalModBreaks -> IO a+getBreakXXX view lookupModule (InternalBreakpointId ibi_mod ibi_ix) imbs =+  assert_modules_match ibi_mod (imodBreaks_module imbs) $ do+    let cgb = imodBreaks_breakInfo imbs IM.! ibi_ix+    case either internalBreakLoc id (cgb_tick_id cgb) of+      BreakpointId{bi_tick_mod, bi_tick_index}+        | bi_tick_mod == ibi_mod+        -> do+          let these_mbs = imodBreaks_modBreaks imbs+          return $ view these_mbs ! bi_tick_index+        | otherwise+        -> do+          other_mbs <- lookupModule bi_tick_mod+          return $ view other_mbs ! bi_tick_index++--------------------------------------------------------------------------------+-- Instances+--------------------------------------------------------------------------------++-- | Fully force an 'InternalModBreaks' value+seqInternalModBreaks :: InternalModBreaks -> ()+seqInternalModBreaks InternalModBreaks{..} =+    rnf (fmap seqCgBreakInfo imodBreaks_breakInfo)+  where+    seqCgBreakInfo :: CgBreakInfo -> ()+    seqCgBreakInfo CgBreakInfo{..} =+        rnf cgb_tyvars `seq`+        rnf cgb_vars `seq`+        rnf cgb_resty `seq`+        rnf cgb_tick_id++instance Outputable InternalBreakpointId where+  ppr InternalBreakpointId{..} =+    text "InternalBreakpointId" <+> ppr ibi_info_mod <+> ppr ibi_info_index++instance NFData InternalBreakpointId where+  rnf InternalBreakpointId{..} =+    rnf ibi_info_mod `seq` rnf ibi_info_index++instance Outputable CgBreakInfo where+   ppr info = text "CgBreakInfo" <+>+              parens (ppr (cgb_vars info) <+>+                      ppr (cgb_resty info) <+>+                      ppr (cgb_tick_id info))
GHC/ByteCode/InfoTable.hs view
@@ -13,15 +13,13 @@ import GHC.Platform import GHC.Platform.Profile -import GHC.ByteCode.Types-import GHC.Runtime.Interpreter+import GHCi.Message  import GHC.Types.Name       ( Name, getName )-import GHC.Types.Name.Env import GHC.Types.RepType  import GHC.Core.DataCon     ( DataCon, dataConRepArgTys, dataConIdentity )-import GHC.Core.TyCon       ( TyCon, tyConFamilySize, isDataTyCon, tyConDataCons )+import GHC.Core.TyCon       ( TyCon, tyConFamilySize, isBoxedDataTyCon, tyConDataCons ) import GHC.Core.Multiplicity     ( scaledThing )  import GHC.StgToCmm.Layout  ( mkVirtConstrSizes )@@ -35,33 +33,38 @@ -}  -- Make info tables for the data decls in this module-mkITbls :: Interp -> Profile -> [TyCon] -> IO ItblEnv-mkITbls interp profile tcs =-  foldr plusNameEnv emptyNameEnv <$>-    mapM mkITbl (filter isDataTyCon tcs)+mkITbls :: Profile -> [TyCon] -> [(Name, ConInfoTable)]+mkITbls profile tcs = concatMap mkITbl (filter isBoxedDataTyCon tcs)  where-  mkITbl :: TyCon -> IO ItblEnv+  mkITbl :: TyCon -> [(Name, ConInfoTable)]   mkITbl tc     | dcs `lengthIs` n -- paranoia; this is an assertion.-    = make_constr_itbls interp profile dcs+    = make_constr_itbls profile dcs        where           dcs = tyConDataCons tc           n   = tyConFamilySize tc   mkITbl _ = panic "mkITbl" -mkItblEnv :: [(Name,ItblPtr)] -> ItblEnv-mkItblEnv pairs = mkNameEnv [(n, (n,p)) | (n,p) <- pairs]- -- Assumes constructors are numbered from zero, not one-make_constr_itbls :: Interp -> Profile -> [DataCon] -> IO ItblEnv-make_constr_itbls interp profile cons =+make_constr_itbls :: Profile -> [DataCon] -> [(Name, ConInfoTable)]+make_constr_itbls profile cons =   -- TODO: the profile should be bundled with the interpreter: the rts ways are   -- fixed for an interpreter-  mkItblEnv <$> mapM (uncurry mk_itbl) (zip cons [0..])- where-  mk_itbl :: DataCon -> Int -> IO (Name,ItblPtr)-  mk_itbl dcon conNo = do-     let rep_args = [ prim_rep+  map (uncurry mk_itbl) (zip cons [0..])+  where+    mk_itbl :: DataCon -> Int -> (Name, ConInfoTable)+    mk_itbl dcon conNo =+      ( getName dcon,+        ConInfoTable+          tables_next_to_code+          ptrs'+          nptrs_really+          conNo+          (tagForCon platform dcon)+          descr+      )+      where+         rep_args = [ prim_rep                     | arg <- dataConRepArgTys dcon                     , prim_rep <- typePrimRep (scaledThing arg) ] @@ -79,7 +82,3 @@          platform = profilePlatform profile          constants = platformConstants platform          tables_next_to_code = platformTablesNextToCode platform--     r <- interpCmd interp (MkConInfoTable tables_next_to_code ptrs' nptrs_really-                              conNo (tagForCon platform dcon) descr)-     return (getName dcon, ItblPtr r)
GHC/ByteCode/Instr.hs view
@@ -15,12 +15,11 @@  import GHC.ByteCode.Types import GHC.Cmm.Type (Width)-import GHCi.RemoteTypes-import GHCi.FFI (C_ffi_cif) import GHC.StgToCmm.Layout     ( ArgRep(..) ) import GHC.Utils.Outputable import GHC.Types.Name import GHC.Types.Literal+import GHC.Types.Unique import GHC.Core.DataCon import GHC.Builtin.PrimOps import GHC.Runtime.Heap.Layout ( StgWord )@@ -32,11 +31,8 @@ import Data.ByteString (ByteString) #endif -import GHC.Stack.CCS (CostCentre)  import GHC.Stg.Syntax-import GHCi.BreakArray (BreakArray)-import Language.Haskell.Syntax.Module.Name (ModuleName)  -- ---------------------------------------------------------------------------- -- Bytecode instructions@@ -50,15 +46,17 @@         protoBCOBitmapSize :: Word,         protoBCOArity      :: Int,         -- what the BCO came from, for debugging only-        protoBCOExpr       :: Either [CgStgAlt] CgStgRhs,-        -- malloc'd pointers-        protoBCOFFIs       :: [FFIInfo]+        protoBCOExpr       :: Either [CgStgAlt] CgStgRhs    }  -- | A local block label (e.g. identifying a case alternative). newtype LocalLabel = LocalLabel { getLocalLabel :: Word32 }   deriving (Eq, Ord) +-- Just so we can easily juse UniqFM.+instance Uniquable LocalLabel where+  getUnique (LocalLabel w) = mkUniqueGrimily $ fromIntegral w+ instance Outputable LocalLabel where   ppr (LocalLabel lbl) = text "lbl:" <> ppr lbl @@ -191,7 +189,12 @@    -- The Word16 value is a constructor number and therefore    -- stored in the insn stream rather than as an offset into    -- the literal pool.++   -- | Test whether the tag of a closure pointer is less than the given value.+   -- If not, jump to the given label.    | TESTLT_P  !Word16 LocalLabel+   -- | Test whether the tag of a closure pointer is equal to the given value.+   -- If not, jump to the given label.    | TESTEQ_P  !Word16 LocalLabel     | CASEFAIL@@ -199,7 +202,7 @@     -- For doing calls to C (via glue code generated by libffi)    | CCALL            !WordOff  -- stack frame size-                      (RemotePtr C_ffi_cif) -- addr of the glue code+                      !FFIInfo  -- libffi ffi_cif function prototype                       !Word16   -- flags.                                 --                                 -- 0x1: call is interruptible@@ -255,12 +258,7 @@                    -- Note [unboxed tuple bytecodes and tuple_BCO] in GHC.StgToByteCode     -- Breakpoints-   | BRK_FUN          (ForeignRef BreakArray)-                      (RemotePtr ModuleName) -- breakpoint tick module-                      !Word16                -- breakpoint tick index-                      (RemotePtr ModuleName) -- breakpoint info module-                      !Word16                -- breakpoint info index-                      (RemotePtr CostCentre)+   | BRK_FUN          !InternalBreakpointId  #if MIN_VERSION_rts(1,0,3)    -- | A "meta"-instruction for recording the name of a BCO for debugging purposes.@@ -287,10 +285,9 @@                  , protoBCOBitmap     = bitmap                  , protoBCOBitmapSize = bsize                  , protoBCOArity      = arity-                 , protoBCOExpr       = origin-                 , protoBCOFFIs       = ffis })+                 , protoBCOExpr       = origin })       = (text "ProtoBCO" <+> ppr name <> char '#' <> int arity-                <+> text (show ffis) <> colon)+                <> colon)         $$ nest 3 (case origin of                       Left alts ->                         vcat (zipWith (<+>) (char '{' : repeat (char ';'))@@ -414,9 +411,9 @@    ppr (TESTEQ_P  i lab)     = text "TESTEQ_P" <+> ppr i <+> text "__" <> ppr lab    ppr CASEFAIL              = text "CASEFAIL"    ppr (JMP lab)             = text "JMP"      <+> ppr lab-   ppr (CCALL off marshal_addr flags) = text "CCALL   " <+> ppr off+   ppr (CCALL off ffi flags) = text "CCALL   " <+> ppr off                                                 <+> text "marshal code at"-                                               <+> text (show marshal_addr)+                                               <+> text (show ffi)                                                <+> (case flags of                                                       0x1 -> text "(interruptible)"                                                       0x2 -> text "(unsafe)"@@ -453,10 +450,9 @@    ppr ENTER                 = text "ENTER"    ppr (RETURN pk)           = text "RETURN  " <+> ppr pk    ppr (RETURN_TUPLE)        = text "RETURN_TUPLE"-   ppr (BRK_FUN _ _tick_mod tickx _info_mod infox _)+   ppr (BRK_FUN (InternalBreakpointId info_mod infox))                              = text "BRK_FUN" <+> text "<breakarray>"-                               <+> text "<tick_module>" <+> ppr tickx-                               <+> text "<info_module>" <+> ppr infox+                               <+> ppr info_mod <+> ppr infox                                <+> text "<cc>" #if MIN_VERSION_rts(1,0,3)    ppr (BCO_NAME nm)         = text "BCO_NAME" <+> text (show nm)
GHC/ByteCode/Linker.hs view
@@ -1,6 +1,9 @@ {-# LANGUAGE FlexibleInstances     #-} {-# LANGUAGE MagicHash             #-} {-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE OverloadedStrings     #-}+{-# LANGUAGE DataKinds             #-}+{-# LANGUAGE RecordWildCards       #-} {-# OPTIONS_GHC -optc-DNON_POSIX_SOURCE #-} -- --  (c) The University of Glasgow 2002-2006@@ -11,7 +14,6 @@   ( linkBCO   , lookupStaticPtr   , lookupIE-  , nameToCLabel   , linkFail   ) where@@ -25,11 +27,12 @@  import GHC.Builtin.PrimOps import GHC.Builtin.PrimOps.Ids-import GHC.Builtin.Names +import GHC.Unit.Module.Env import GHC.Unit.Types  import GHC.Data.FastString+import GHC.Data.Maybe import GHC.Data.SizedSeq  import GHC.Linker.Types@@ -42,8 +45,6 @@ import qualified GHC.Types.Id as Id import GHC.Types.Unique.DFM -import Language.Haskell.Syntax.Module.Name- -- Standard libraries import Data.Array.Unboxed import Foreign.Ptr@@ -57,24 +58,27 @@   :: Interp   -> PkgsLoaded   -> LinkerEnv+  -> LinkedBreaks   -> NameEnv Int   -> UnlinkedBCO   -> IO ResolvedBCO-linkBCO interp pkgs_loaded le bco_ix+linkBCO interp pkgs_loaded le lb bco_ix            (UnlinkedBCO _ arity insns bitmap lits0 ptrs0) = do   -- fromIntegral Word -> Word64 should be a no op if Word is Word64   -- otherwise it will result in a cast to longlong on 32bit systems.-  (lits :: [Word]) <- mapM (fmap fromIntegral . lookupLiteral interp pkgs_loaded le) (elemsFlatBag lits0)-  ptrs <- mapM (resolvePtr interp pkgs_loaded le bco_ix) (elemsFlatBag ptrs0)+  (lits :: [Word]) <- mapM (fmap fromIntegral . lookupLiteral interp pkgs_loaded le lb) (elemsFlatBag lits0)+  ptrs <- mapM (resolvePtr interp pkgs_loaded le lb bco_ix) (elemsFlatBag ptrs0)   let lits' = listArray (0 :: Int, fromIntegral (sizeFlatBag lits0)-1) lits-  return (ResolvedBCO isLittleEndian arity-              insns-              bitmap-              (mkBCOByteArray lits')-              (addListToSS emptySS ptrs))+  return $ ResolvedBCO { resolvedBCOIsLE   = isLittleEndian+                       , resolvedBCOArity  = arity+                       , resolvedBCOInstrs = insns+                       , resolvedBCOBitmap = bitmap+                       , resolvedBCOLits   = mkBCOByteArray lits'+                       , resolvedBCOPtrs   = addListToSS emptySS ptrs+                       } -lookupLiteral :: Interp -> PkgsLoaded -> LinkerEnv -> BCONPtr -> IO Word-lookupLiteral interp pkgs_loaded le ptr = case ptr of+lookupLiteral :: Interp -> PkgsLoaded -> LinkerEnv -> LinkedBreaks -> BCONPtr -> IO Word+lookupLiteral interp pkgs_loaded le lb ptr = case ptr of   BCONPtrWord lit -> return lit   BCONPtrLbl  sym -> do     Ptr a# <- lookupStaticPtr interp sym@@ -85,36 +89,49 @@   BCONPtrAddr nm -> do     Ptr a# <- lookupAddr interp pkgs_loaded (addr_env le) nm     return (W# (int2Word# (addr2Int# a#)))-  BCONPtrStr _ ->-    -- should be eliminated during assembleBCOs-    panic "lookupLiteral: BCONPtrStr"+  BCONPtrStr bs -> do+    RemotePtr p <- fmap head $ interpCmd interp $ MallocStrings [bs]+    pure $ fromIntegral p+  BCONPtrFS fs -> do+    RemotePtr p <- fmap head $ interpCmd interp $ MallocStrings [bytesFS fs]+    pure $ fromIntegral p+  BCONPtrFFIInfo (FFIInfo {..}) -> do+    RemotePtr p <- interpCmd interp $ PrepFFI ffiInfoArgs ffiInfoRet+    pure $ fromIntegral p+  BCONPtrCostCentre InternalBreakpointId{..}+    | interpreterProfiled interp -> do+        case expectJust (lookupModuleEnv (ccs_env lb) ibi_info_mod) ! ibi_info_index of+          RemotePtr p -> pure $ fromIntegral p+    | otherwise ->+        case toRemotePtr nullPtr of+          RemotePtr p -> pure $ fromIntegral p  lookupStaticPtr :: Interp -> FastString -> IO (Ptr ()) lookupStaticPtr interp addr_of_label_string = do-  m <- lookupSymbol interp addr_of_label_string+  m <- lookupSymbol interp (IFaststringSymbol addr_of_label_string)   case m of     Just ptr -> return ptr     Nothing  -> linkFail "GHC.ByteCode.Linker: can't find label"-                  (unpackFS addr_of_label_string)+                  (ppr addr_of_label_string)  lookupIE :: Interp -> PkgsLoaded -> ItblEnv -> Name -> IO (Ptr ()) lookupIE interp pkgs_loaded ie con_nm =   case lookupNameEnv ie con_nm of     Just (_, ItblPtr a) -> return (fromRemotePtr (castRemotePtr a))     Nothing -> do -- try looking up in the object files.-       let sym_to_find1 = nameToCLabel con_nm "con_info"-       m <- lookupHsSymbol interp pkgs_loaded con_nm "con_info"+       let sym_to_find1 = IConInfoSymbol con_nm+       m <- lookupHsSymbol interp pkgs_loaded sym_to_find1        case m of           Just addr -> return addr           Nothing              -> do -- perhaps a nullary constructor?-                   let sym_to_find2 = nameToCLabel con_nm "static_info"-                   n <- lookupHsSymbol interp pkgs_loaded con_nm "static_info"+                   let sym_to_find2 = IStaticInfoSymbol con_nm+                   n <- lookupHsSymbol interp pkgs_loaded sym_to_find2                    case n of                       Just addr -> return addr                       Nothing   -> linkFail "GHC.ByteCode.Linker.lookupIE"-                                      (unpackFS sym_to_find1 ++ " or " ++-                                       unpackFS sym_to_find2)+                                      (ppr sym_to_find1 <> " or " <>+                                       ppr sym_to_find2)  -- see Note [Generating code for top-level string literal bindings] in GHC.StgToByteCode lookupAddr :: Interp -> PkgsLoaded -> AddrEnv -> Name -> IO (Ptr ())@@ -122,30 +139,31 @@   case lookupNameEnv ae addr_nm of     Just (_, AddrPtr ptr) -> return (fromRemotePtr ptr)     Nothing -> do -- try looking up in the object files.-      let sym_to_find = nameToCLabel addr_nm "bytes"+      let sym_to_find = IBytesSymbol addr_nm                           -- see Note [Bytes label] in GHC.Cmm.CLabel-      m <- lookupHsSymbol interp pkgs_loaded addr_nm "bytes"+      m <- lookupHsSymbol interp pkgs_loaded sym_to_find       case m of         Just ptr -> return ptr         Nothing -> linkFail "GHC.ByteCode.Linker.lookupAddr"-                     (unpackFS sym_to_find)+                     (ppr sym_to_find)  lookupPrimOp :: Interp -> PkgsLoaded -> PrimOp -> IO (RemotePtr ()) lookupPrimOp interp pkgs_loaded primop = do   let sym_to_find = primopToCLabel primop "closure"-  m <- lookupHsSymbol interp pkgs_loaded (Id.idName $ primOpId primop) "closure"+  m <- lookupHsSymbol interp pkgs_loaded (IClosureSymbol (Id.idName $ primOpId primop))   case m of     Just p -> return (toRemotePtr p)-    Nothing -> linkFail "GHC.ByteCode.Linker.lookupCE(primop)" sym_to_find+    Nothing -> linkFail "GHC.ByteCode.Linker.lookupCE(primop)" (text sym_to_find)  resolvePtr   :: Interp   -> PkgsLoaded   -> LinkerEnv+  -> LinkedBreaks   -> NameEnv Int   -> BCOPtr   -> IO ResolvedBCOPtr-resolvePtr interp pkgs_loaded le bco_ix ptr = case ptr of+resolvePtr interp pkgs_loaded le lb bco_ix ptr = case ptr of   BCOPtrName nm     | Just ix <- lookupNameEnv bco_ix nm     -> return (ResolvedBCORef ix) -- ref to another BCO in this group@@ -156,30 +174,30 @@     | otherwise     -> assertPpr (isExternalName nm) (ppr nm) $        do-          let sym_to_find = nameToCLabel nm "closure"-          m <- lookupHsSymbol interp pkgs_loaded nm "closure"+          let sym_to_find = IClosureSymbol nm+          m <- lookupHsSymbol interp pkgs_loaded sym_to_find           case m of             Just p -> return (ResolvedBCOStaticPtr (toRemotePtr p))-            Nothing -> linkFail "GHC.ByteCode.Linker.lookupCE" (unpackFS sym_to_find)+            Nothing -> linkFail "GHC.ByteCode.Linker.lookupCE" (ppr sym_to_find)    BCOPtrPrimOp op     -> ResolvedBCOStaticPtr <$> lookupPrimOp interp pkgs_loaded op    BCOPtrBCO bco-    -> ResolvedBCOPtrBCO <$> linkBCO interp pkgs_loaded le bco_ix bco+    -> ResolvedBCOPtrBCO <$> linkBCO interp pkgs_loaded le lb bco_ix bco -  BCOPtrBreakArray breakarray-    -> withForeignRef breakarray $ \ba -> return (ResolvedBCOPtrBreakArray ba)+  BCOPtrBreakArray tick_mod ->+    withForeignRef (expectJust (lookupModuleEnv (breakarray_env lb) tick_mod)) $+      \ba -> pure $ ResolvedBCOPtrBreakArray ba  -- | Look up the address of a Haskell symbol in the currently -- loaded units. -- -- See Note [Looking up symbols in the relevant objects].-lookupHsSymbol :: Interp -> PkgsLoaded -> Name -> String -> IO (Maybe (Ptr ()))-lookupHsSymbol interp pkgs_loaded nm sym_suffix = do-  massertPpr (isExternalName nm) (ppr nm)-  let sym_to_find = nameToCLabel nm sym_suffix-      pkg_id = moduleUnitId $ nameModule nm+lookupHsSymbol :: Interp -> PkgsLoaded -> InterpSymbol (Suffix s) -> IO (Maybe (Ptr ()))+lookupHsSymbol interp pkgs_loaded sym_to_find = do+  massertPpr (isExternalName (interpSymbolName sym_to_find)) (ppr sym_to_find)+  let pkg_id = moduleUnitId $ nameModule (interpSymbolName sym_to_find)       loaded_dlls = maybe [] loaded_pkg_hs_dlls $ lookupUDFM pkgs_loaded pkg_id        go (dll:dlls) = do@@ -193,12 +211,12 @@    go loaded_dlls -linkFail :: String -> String -> IO a+linkFail :: String -> SDoc -> IO a linkFail who what    = throwGhcExceptionIO (ProgramError $         unlines [ "",who                 , "During interactive linking, GHCi couldn't find the following symbol:"-                , ' ' : ' ' : what+                , ' ' : ' ' : showSDocUnsafe what                 , "This may be due to you not asking GHCi to load extra object files,"                 , "archives or DLLs needed by your current session.  Restart GHCi, specifying"                 , "the missing library using the -L/path/to/object/dir and -lmissinglibname"@@ -209,31 +227,14 @@                 ])  -nameToCLabel :: Name -> String -> FastString-nameToCLabel n suffix = mkFastString label-  where-    encodeZ = zString . zEncodeFS-    (Module pkgKey modName) = assert (isExternalName n) $ case nameModule n of-        -- Primops are exported from GHC.Prim, their HValues live in GHC.PrimopWrappers-        -- See Note [Primop wrappers] in GHC.Builtin.PrimOps.-        mod | mod == gHC_PRIM -> gHC_PRIMOPWRAPPERS-        mod -> mod-    packagePart = encodeZ (unitFS pkgKey)-    modulePart  = encodeZ (moduleNameFS modName)-    occPart     = encodeZ $ occNameMangledFS (nameOccName n) -    label = concat-        [ if pkgKey == mainUnit then "" else packagePart ++ "_"-        , modulePart-        , '_':occPart-        , '_':suffix-        ]  + -- See Note [Primop wrappers] in GHC.Builtin.PrimOps primopToCLabel :: PrimOp -> String -> String primopToCLabel primop suffix = concat-    [ "ghczmprim_GHCziPrimopWrappers_"+    [ "ghczminternal_GHCziInternalziPrimopWrappers_"     , zString (zEncodeFS (occNameFS (primOpOcc primop)))     , '_':suffix     ]
GHC/ByteCode/Types.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE CPP                        #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE RecordWildCards            #-} {-# LANGUAGE TypeApplications           #-}@@ -18,10 +19,15 @@   , UnlinkedBCO(..), BCOPtr(..), BCONPtr(..)   , ItblEnv, ItblPtr(..)   , AddrEnv, AddrPtr(..)-  , CgBreakInfo(..)-  , ModBreaks (..), BreakIndex, emptyModBreaks-  , CCostCentre-  , FlatBag, sizeFlatBag, fromSizedSeq, elemsFlatBag+  , FlatBag, sizeFlatBag, fromSmallArray, elemsFlatBag++  -- * Mod Breaks+  , ModBreaks (..), BreakpointId(..), BreakTickIndex++  -- * Internal Mod Breaks+  , InternalModBreaks(..), CgBreakInfo(..), seqInternalModBreaks+  -- ** Internal breakpoint identifier+  , InternalBreakpointId(..), BreakInfoIndex   ) where  import GHC.Prelude@@ -33,23 +39,19 @@ import GHC.Utils.Outputable import GHC.Builtin.PrimOps import GHC.Types.SptEntry-import GHC.Types.SrcLoc-import GHCi.BreakArray+import GHC.HsToCore.Breakpoints+import GHC.ByteCode.Breakpoints+import GHCi.Message import GHCi.RemoteTypes import GHCi.FFI import Control.DeepSeq import GHCi.ResolvedBCO ( BCOByteArray(..), mkBCOByteArray )  import Foreign-import Data.Array import Data.ByteString (ByteString)-import Data.IntMap (IntMap)-import qualified Data.IntMap as IntMap import qualified GHC.Exts.Heap as Heap-import GHC.Stack.CCS import GHC.Cmm.Expr ( GlobalRegSet, emptyRegSet, regSetToList )-import GHC.Iface.Syntax-import Language.Haskell.Syntax.Module.Name (ModuleName)+import GHC.Unit.Module  -- ----------------------------------------------------------------------------- -- Compiled Byte Code@@ -58,27 +60,29 @@   { bc_bcos   :: FlatBag UnlinkedBCO     -- ^ Bunch of interpretable bindings -  , bc_itbls  :: ItblEnv+  , bc_itbls  :: [(Name, ConInfoTable)]     -- ^ Mapping from DataCons to their info tables -  , bc_ffis   :: [FFIInfo]-    -- ^ ffi blocks we allocated--  , bc_strs   :: AddrEnv+  , bc_strs   :: [(Name, ByteString)]     -- ^ top-level strings (heap allocated) -  , bc_breaks :: Maybe ModBreaks-    -- ^ breakpoint info (Nothing if breakpoints are disabled)+  , bc_breaks :: Maybe InternalModBreaks+    -- ^ All breakpoint information (no information if breakpoints are disabled).+    --+    -- This information is used when loading a bytecode object: we will+    -- construct the arrays to be used at runtime to trigger breakpoints at load time+    -- from it (in 'allocateBreakArrays' and 'allocateCCS' in 'GHC.ByteCode.Loader').    , bc_spt_entries :: ![SptEntry]     -- ^ Static pointer table entries which should be loaded along with the     -- BCOs. See Note [Grand plan for static forms] in     -- "GHC.Iface.Tidy.StaticPtrTable".   }-                -- ToDo: we're not tracking strings that we malloc'd-newtype FFIInfo = FFIInfo (RemotePtr C_ffi_cif)-  deriving (Show, NFData) +-- | A libffi ffi_cif function prototype.+data FFIInfo = FFIInfo { ffiInfoArgs :: ![FFIType], ffiInfoRet :: !FFIType }+  deriving (Show)+ instance Outputable CompiledByteCode where   ppr CompiledByteCode{..} = ppr $ elemsFlatBag bc_bcos @@ -87,10 +91,11 @@ seqCompiledByteCode :: CompiledByteCode -> () seqCompiledByteCode CompiledByteCode{..} =   rnf bc_bcos `seq`-  seqEltsNameEnv rnf bc_itbls `seq`-  rnf bc_ffis `seq`-  seqEltsNameEnv rnf bc_strs `seq`-  rnf (fmap seqModBreaks bc_breaks)+  rnf bc_itbls `seq`+  rnf bc_strs `seq`+  case bc_breaks of+    Nothing -> ()+    Just ibks -> seqInternalModBreaks ibks  newtype ByteOff = ByteOff Int     deriving (Enum, Eq, Show, Integral, Num, Ord, Real, Outputable)@@ -166,6 +171,80 @@ newtype AddrPtr = AddrPtr (RemotePtr ())   deriving (NFData) +{-+--------------------------------------------------------------------------------+-- * Byte Code Objects (BCOs)+--------------------------------------------------------------------------------++Note [Case continuation BCOs]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~++A stack with a BCO stack frame at the top looks like:++                                      (an StgBCO)+         |       ...        |      +---> +---------[1]--++         +------------------+      |     | info_tbl_ptr | ------++         |    OTHER FRAME   |      |     +--------------+       |+         +------------------+      |     | StgArrBytes* | <--- the byte code+         |       ...        |      |     +--------------+       |+         +------------------+      |     |     ...      |       |+         |       fvs1       |      |                            |+         +------------------+      |                            |+         |       ...        |      |        (StgInfoTable)      |+         +------------------+      |           +----------+ <---++         |      args1       |      |           |    ...   |+         +------------------+      |           +----------++         |   some StgBCO*   | -----+           | type=BCO |+         +------------------+                  +----------++      Sp | stg_apply_interp | -----+           |   ...    |+         +------------------+      |+                                   |+                                   |   (StgInfoTable)+                                   +----> +--------------++                                          |     ...      |+                                          +--------------++                                          | type=RET_BCO |+                                          +--------------++                                          |     ...      |+++In the case of bytecode objects found on the heap (e.g. thunks and functions),+the bytecode may refer to free variables recorded in the BCO closure itself.+By contrast, in /case continuation/ BCOs the code may additionally refer to free+variables in their stack frame. These are references by way of statically known+stack offsets (tracked using `BCEnv` in `StgToByteCode`).++For instance, consider the function:++    f x y = case y of ... -> g x++Here the RHS of the alternative refers to `x`, which will be recorded in the+continuation stack frame of the `case`.++Even less obvious is that case continuation BCOs may also refer to free+variables in *parent* stack frames. For instance,++    f x y = case y of+      ... -> case g x of+        ... -> x++Here, the RHS of the first alternative still refers to the `x` in the stack+frame of the `case`. Additionally, the RHS of the second alternative also+refers to `x` but it must traverse to its case's *parent* stack frame to find `x`.++However, in /case continuation/ BCOs, the code may additionally refer to free+variables that are outside of that BCO's stack frame -- some free variables of a+case continuation BCO may only be found in the stack frame of a parent BCO.++Yet, references to these out-of-frame variables are also done in terms of stack+offsets. Thus, they rely on the position of /another frame/ to be fixed. (See+Note [PUSH_L underflow] for more information about references to previous+frames and nested BCOs)++This makes case continuation BCOs special: unlike normal BCOs, case cont BCO+frames cannot be moved on the stack independently from their parent BCOs.+-}+ data UnlinkedBCO    = UnlinkedBCO {         unlinkedBCOName   :: !Name,@@ -185,8 +264,8 @@   = BCOPtrName   !Name   | BCOPtrPrimOp !PrimOp   | BCOPtrBCO    !UnlinkedBCO-  | BCOPtrBreakArray (ForeignRef BreakArray)-    -- ^ a pointer to a breakpoint's module's BreakArray in GHCi's memory+  | BCOPtrBreakArray !Module+    -- ^ Converted to the actual 'BreakArray' remote pointer at link-time  instance NFData BCOPtr where   rnf (BCOPtrBCO bco) = rnf bco@@ -199,100 +278,22 @@   -- | A reference to a top-level string literal; see   -- Note [Generating code for top-level string literal bindings] in GHC.StgToByteCode.   | BCONPtrAddr  !Name-  -- | Only used internally in the assembler in an intermediate representation;-  -- should never appear in a fully-assembled UnlinkedBCO.+  -- | A top-level string literal.   -- Also see Note [Allocating string literals] in GHC.ByteCode.Asm.   | BCONPtrStr   !ByteString+  -- | Same as 'BCONPtrStr' but with benefits of 'FastString' interning logic.+  | BCONPtrFS    !FastString+  -- | A libffi ffi_cif function prototype.+  | BCONPtrFFIInfo !FFIInfo+  -- | A 'CostCentre' remote pointer array's respective 'BreakpointId'+  | BCONPtrCostCentre !InternalBreakpointId  instance NFData BCONPtr where   rnf x = x `seq` () --- | Information about a breakpoint that we know at code-generation time--- In order to be used, this needs to be hydrated relative to the current HscEnv by--- 'hydrateCgBreakInfo'. Everything here can be fully forced and that's critical for--- preventing space leaks (see #22530)-data CgBreakInfo-   = CgBreakInfo-   { cgb_tyvars :: ![IfaceTvBndr] -- ^ Type variables in scope at the breakpoint-   , cgb_vars   :: ![Maybe (IfaceIdBndr, Word)]-   , cgb_resty  :: !IfaceType-   }--- See Note [Syncing breakpoint info] in GHC.Runtime.Eval--seqCgBreakInfo :: CgBreakInfo -> ()-seqCgBreakInfo CgBreakInfo{..} =-    rnf cgb_tyvars `seq`-    rnf cgb_vars `seq`-    rnf cgb_resty- instance Outputable UnlinkedBCO where    ppr (UnlinkedBCO nm _arity _insns _bitmap lits ptrs)       = sep [text "BCO", ppr nm, text "with",              ppr (sizeFlatBag lits), text "lits",              ppr (sizeFlatBag ptrs), text "ptrs" ] -instance Outputable CgBreakInfo where-   ppr info = text "CgBreakInfo" <+>-              parens (ppr (cgb_vars info) <+>-                      ppr (cgb_resty info))---- -------------------------------------------------------------------------------- Breakpoints---- | Breakpoint index-type BreakIndex = Int---- | C CostCentre type-data CCostCentre---- | All the information about the breakpoints for a module-data ModBreaks-   = ModBreaks-   { modBreaks_flags :: ForeignRef BreakArray-        -- ^ The array of flags, one per breakpoint,-        -- indicating which breakpoints are enabled.-   , modBreaks_locs :: !(Array BreakIndex SrcSpan)-        -- ^ An array giving the source span of each breakpoint.-   , modBreaks_vars :: !(Array BreakIndex [OccName])-        -- ^ An array giving the names of the free variables at each breakpoint.-   , modBreaks_decls :: !(Array BreakIndex [String])-        -- ^ An array giving the names of the declarations enclosing each breakpoint.-        -- See Note [Field modBreaks_decls]-   , modBreaks_ccs :: !(Array BreakIndex (RemotePtr CostCentre))-        -- ^ Array pointing to cost centre for each breakpoint-   , modBreaks_breakInfo :: IntMap CgBreakInfo-        -- ^ info about each breakpoint from the bytecode generator-   , modBreaks_module :: RemotePtr ModuleName-   }--seqModBreaks :: ModBreaks -> ()-seqModBreaks ModBreaks{..} =-  rnf modBreaks_flags `seq`-  rnf modBreaks_locs `seq`-  rnf modBreaks_vars `seq`-  rnf modBreaks_decls `seq`-  rnf modBreaks_ccs `seq`-  rnf (fmap seqCgBreakInfo modBreaks_breakInfo) `seq`-  rnf modBreaks_module---- | Construct an empty ModBreaks-emptyModBreaks :: ModBreaks-emptyModBreaks = ModBreaks-   { modBreaks_flags = error "ModBreaks.modBreaks_array not initialised"-         -- ToDo: can we avoid this?-   , modBreaks_locs  = array (0,-1) []-   , modBreaks_vars  = array (0,-1) []-   , modBreaks_decls = array (0,-1) []-   , modBreaks_ccs = array (0,-1) []-   , modBreaks_breakInfo = IntMap.empty-   , modBreaks_module = toRemotePtr nullPtr-   }--{--Note [Field modBreaks_decls]-~~~~~~~~~~~~~~~~~~~~~~-A value of eg ["foo", "bar", "baz"] in a `modBreaks_decls` field means:-The breakpoint is in the function called "baz" that is declared in a `let`-or `where` clause of a declaration called "bar", which itself is declared-in a `let` or `where` clause of the top-level function called "foo".--}
GHC/Cmm.hs view
@@ -288,8 +288,8 @@   deriving (Eq)  -- | Should a data in this section be considered constant at runtime-sectionProtection :: SectionType -> SectionProtection-sectionProtection t = case t of+sectionProtection :: Section -> SectionProtection+sectionProtection (Section t _) = case t of     Text                    -> ReadOnlySection     ReadOnlyData            -> ReadOnlySection     RelocatableReadOnlyData -> WriteProtectedSection
GHC/Cmm/CLabel.hs view
@@ -1729,6 +1729,9 @@       | platformArch platform == ArchRISCV64       = ppLbl +      | platformArch platform == ArchLoongArch64+      = ppLbl+       | platformArch platform == ArchX86_64       = case dllInfo of           CodeStub        -> ppLbl <> text "@plt"
GHC/Cmm/CallConv.hs view
GHC/Cmm/Dataflow/Label.hs view
@@ -63,10 +63,12 @@     , mapToList     , mapFromList     , mapFromListWith+    , mapMapMaybe     ) where  import GHC.Prelude +import GHC.Utils.Misc import GHC.Utils.Outputable  import GHC.Types.Unique (Uniquable(..), mkUniqueGrimily)@@ -82,7 +84,6 @@ import GHC.Data.TrieMap  import Data.Word (Word64)-import Data.List (foldl1')   -----------------------------------------------------------------------------@@ -139,8 +140,7 @@  {-# INLINE setUnions #-} setUnions :: [LabelSet] -> LabelSet-setUnions [] = setEmpty-setUnions sets = foldl1' setUnion sets+setUnions = foldl1WithDefault' setEmpty setUnion  setDifference :: LabelSet -> LabelSet -> LabelSet setDifference (LS x) (LS y) = LS (S.difference x y)@@ -219,8 +219,7 @@  {-# INLINE mapUnions #-} mapUnions :: [LabelMap a] -> LabelMap a-mapUnions [] = mapEmpty-mapUnions maps = foldl1' mapUnion maps+mapUnions = foldl1WithDefault' mapEmpty mapUnion  mapUnionWithKey :: (Label -> v -> v -> v) -> LabelMap v -> LabelMap v -> LabelMap v mapUnionWithKey f (LM x) (LM y) = LM (M.unionWithKey (f . mkHooplLabel) x y)@@ -282,6 +281,9 @@ mapFromListWith :: (v -> v -> v) -> [(Label, v)] -> LabelMap v mapFromListWith f assocs = LM (M.fromListWith f [(lblToUnique k, v) | (k, v) <- assocs]) +mapMapMaybe :: (a -> Maybe b) -> LabelMap a -> LabelMap b+mapMapMaybe f (LM m) = LM (M.mapMaybe f m)+ ----------------------------------------------------------------------------- -- Instances @@ -300,7 +302,8 @@   lookupTM k m  = mapLookup k m   alterTM k f m = mapAlter f k m   foldTM k m z  = mapFoldr k z m-  filterTM f m  = mapFilter f m+  filterTM f    = mapFilter f+  mapMaybeTM f  = mapMapMaybe f  ----------------------------------------------------------------------------- -- FactBase
GHC/Cmm/DebugBlock.hs view
@@ -6,9 +6,7 @@ {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE UndecidableInstances #-} {-# LANGUAGE LambdaCase #-}---{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-}+{-# LANGUAGE EmptyCase #-}  ----------------------------------------------------------------------------- --@@ -41,22 +39,27 @@ import GHC.Cmm import GHC.Cmm.Reg ( pprGlobalReg, pprGlobalRegUse ) import GHC.Cmm.Utils-import GHC.Data.FastString ( nilFS, mkFastString )+import GHC.Data.FastString ( LexicalFastString, nilFS, mkFastString ) import GHC.Unit.Module import GHC.Utils.Outputable import GHC.Utils.Panic import GHC.Types.SrcLoc import GHC.Types.Tickish-import GHC.Utils.Misc      ( partitionWith, seqList )+import GHC.Utils.Misc      ( seqList )  import GHC.Cmm.Dataflow.Block import GHC.Cmm.Dataflow.Graph import GHC.Cmm.Dataflow.Label  import Data.Maybe-import Data.List     ( minimumBy, nubBy )+import Data.List     ( nubBy )+import Data.List.NonEmpty ( NonEmpty (..), nonEmpty )+import qualified Data.List.NonEmpty as NE import Data.Ord      ( comparing ) import qualified Data.Map as Map+import Data.Foldable ( toList )+import Data.Either ( partitionEithers )+import Data.Void  -- | Debug information about a block of code. Ticks scope over nested -- blocks.@@ -94,23 +97,32 @@  -- | Intermediate data structure holding debug-relevant context information -- about a block.-type BlockContext = (CmmBlock, RawCmmDecl)+type BlockContext = (CmmBlock, RawCmmDeclNoStatics) +-- Same as `RawCmmDecl`, but statically (in GHC) excludes the possibility of statics (in the CMM+-- code). (The first argument is `Void` rather than `RawCmmStatics`.+type RawCmmDeclNoStatics+   = GenCmmDecl+        Void+        (LabelMap RawCmmStatics)+        CmmGraph+ -- | Extract debug data from a group of procedures. We will prefer -- source notes that come from the given module (presumably the module -- that we are currently compiling).-cmmDebugGen :: ModLocation -> RawCmmGroup -> [DebugBlock]+cmmDebugGen :: ModLocation -> [RawCmmDecl] -> [DebugBlock] cmmDebugGen modLoc decls = map (blocksForScope Nothing) topScopes   where-      blockCtxs :: Map.Map CmmTickScope [BlockContext]+      blockCtxs :: Map.Map CmmTickScope (NonEmpty BlockContext)       blockCtxs = blockContexts decls        -- Analyse tick scope structure: Each one is either a top-level       -- tick scope, or the child of another.       (topScopes, childScopes)-        = partitionWith (\a -> findP a a) $ Map.keys blockCtxs+        = partitionEithers $ map (\(k, a) -> findP (k, a) k) $ Map.toList blockCtxs+       findP tsc GlobalScope = Left tsc -- top scope-      findP tsc scp | scp' `Map.member` blockCtxs = Right (scp', tsc)+      findP tsc scp | Just x <- Map.lookup scp' blockCtxs = Right (scp', tsc, x)                     | otherwise                   = findP tsc scp'         where -- Note that we only following the left parent of               -- combined scopes. This loses us ticks, which we will@@ -118,7 +130,7 @@               scp' | SubScope _ scp' <- scp      = scp'                    | CombinedScope scp' _ <- scp = scp' -      scopeMap = foldl' (\acc (key, scope) -> insertMulti key scope acc) Map.empty childScopes+      scopeMap = foldl' (\ acc (k, (k', a'), _) -> insertMulti k (k', a') acc) Map.empty childScopes        -- This allows us to recover ticks that we lost by flattening       -- the graph. Basically, if the parent is A but the child is@@ -137,7 +149,7 @@                    | SubScope _ s' <- s       = ticks ++ go s'                    | CombinedScope s1 s2 <- s = ticks ++ go s1 ++ go s2                    | otherwise                = panic "ticksToCopy impossible"-                where ticks = bCtxsTicks $ fromMaybe [] $ Map.lookup s blockCtxs+                where ticks = bCtxsTicks $ maybe [] toList $ Map.lookup s blockCtxs       ticksToCopy _ = []       bCtxsTicks = concatMap (blockTicks . fst) @@ -147,21 +159,19 @@       -- (if we generated one, we probably want debug information to       -- refer to it).       bestSrcTick = minimumBy (comparing rangeRating)-      rangeRating (SourceNote span _)+      rangeRating (span, _)         | srcSpanFile span == thisFile = 1         | otherwise                    = 2 :: Int-      rangeRating note                 = pprPanic "rangeRating" (ppr note)       thisFile = maybe nilFS mkFastString $ ml_hs_file modLoc        -- Returns block tree for this scope as well as all nested       -- scopes. Note that if there are multiple blocks in the (exact)       -- same scope we elect one as the "branch" node and add the rest       -- as children.-      blocksForScope :: Maybe CmmTickish -> CmmTickScope -> DebugBlock-      blocksForScope cstick scope = mkBlock True (head bctxs)-        where bctxs = fromJust $ Map.lookup scope blockCtxs-              nested = fromMaybe [] $ Map.lookup scope scopeMap-              childs = map (mkBlock False) (tail bctxs) +++      blocksForScope :: Maybe (RealSrcSpan, LexicalFastString) -> (CmmTickScope, NonEmpty BlockContext) -> DebugBlock+      blocksForScope cstick (scope, bctx:|bctxs) = mkBlock True bctx+        where nested = fromMaybe [] $ Map.lookup scope scopeMap+              childs = map (mkBlock False) bctxs ++                        map (blocksForScope stick) nested                mkBlock :: Bool -> BlockContext -> DebugBlock@@ -173,11 +183,13 @@                              , dblParent       = Nothing                              , dblTicks        = ticks                              , dblPosition     = Nothing -- see cmmDebugLink-                             , dblSourceTick   = stick+                             , dblSourceTick   = uncurry SourceNote <$> stick                              , dblBlocks       = blocks                              , dblUnwind       = []                              }-                where (CmmProc infos _entryLbl _ graph) = prc+                where (infos, graph) = case prc of+                          CmmProc infos _ _ graph -> (infos, graph)+                          CmmData _ v -> case v of                       label = entryLabel block                       info = mapLookup label infos                       blocks | top       = seqList childs childs@@ -185,26 +197,26 @@                -- A source tick scopes over all nested blocks. However               -- their source ticks might take priority.-              isSourceTick SourceNote {} = True-              isSourceTick _             = False+              isSourceTick (SourceNote span a) = Just (span, a)+              isSourceTick _ = Nothing               -- Collect ticks from all blocks inside the tick scope.               -- We attempt to filter out duplicates while we're at it.               ticks = nubBy (flip tickishContains) $                       bCtxsTicks bctxs ++ ticksToCopy scope-              stick = case filter isSourceTick ticks of-                []     -> cstick-                sticks -> Just $! bestSrcTick (sticks ++ maybeToList cstick)+              stick = case nonEmpty $ mapMaybe isSourceTick ticks of+                Nothing -> cstick+                Just sticks -> Just $! bestSrcTick (sticks `NE.appendList` maybeToList cstick)  -- | Build a map of blocks sorted by their tick scopes -- -- This involves a pre-order traversal, as we want blocks in rough -- control flow order (so ticks have a chance to be sorted in the -- right order).-blockContexts :: RawCmmGroup -> Map.Map CmmTickScope [BlockContext]-blockContexts decls = Map.map reverse $ foldr walkProc Map.empty decls-  where walkProc :: RawCmmDecl-                 -> Map.Map CmmTickScope [BlockContext]-                 -> Map.Map CmmTickScope [BlockContext]+blockContexts :: [GenCmmDecl a (LabelMap RawCmmStatics) CmmGraph] -> Map.Map CmmTickScope (NonEmpty BlockContext)+blockContexts = Map.map NE.reverse . foldr walkProc Map.empty+  where walkProc :: GenCmmDecl a (LabelMap RawCmmStatics) CmmGraph+                 -> Map.Map CmmTickScope (NonEmpty BlockContext)+                 -> Map.Map CmmTickScope (NonEmpty BlockContext)         walkProc CmmData{}                 m = m         walkProc prc@(CmmProc _ _ _ graph) m           | mapNull blocks = m@@ -213,26 +225,27 @@                 entry  = [mapFind (g_entry graph) blocks]                 emptyLbls = setEmpty :: LabelSet -        walkBlock :: RawCmmDecl -> [Block CmmNode C C]-                  -> (LabelSet, Map.Map CmmTickScope [BlockContext])-                  -> (LabelSet, Map.Map CmmTickScope [BlockContext])+        walkBlock :: GenCmmDecl a (LabelMap RawCmmStatics) CmmGraph -> [Block CmmNode C C]+                  -> (LabelSet, Map.Map CmmTickScope (NonEmpty BlockContext))+                  -> (LabelSet, Map.Map CmmTickScope (NonEmpty BlockContext))         walkBlock _   []             c            = c-        walkBlock prc (block:blocks) (visited, m)-          | lbl `setMember` visited-          = walkBlock prc blocks (visited, m)-          | otherwise-          = walkBlock prc blocks $-            walkBlock prc succs-              (lbl `setInsert` visited,-               insertMulti scope (block, prc) m)+        walkBlock prc (block:blocks) (visited, m) = case (prc, setMember lbl visited) of+            (CmmProc x y z graph, False) ->+                let succs = flip mapFind (toBlockMap graph) <$>+                        successors (lastNode block) in+                walkBlock prc blocks $+                walkBlock prc succs+                  ( lbl `setInsert` visited+                  , insertMultiNE scope (block, CmmProc x y z graph) m )+            _ -> walkBlock prc blocks (visited, m)           where CmmEntry lbl scope = firstNode block-                (CmmProc _ _ _ graph) = prc-                succs = map (flip mapFind (toBlockMap graph))-                            (successors (lastNode block))         mapFind = mapFindWithDefault (error "contextTree: block not found!")  insertMulti :: Ord k => k -> a -> Map.Map k [a] -> Map.Map k [a] insertMulti k v = Map.insertWith (const (v:)) k [v]++insertMultiNE :: Ord k => k -> a -> Map.Map k (NonEmpty a) -> Map.Map k (NonEmpty a)+insertMultiNE k v = Map.insertWith (const (v NE.<|)) k (NE.singleton v)  cmmDebugLabels :: (BlockId -> Bool) -> (i -> Bool) -> GenCmmGroup d g (ListGraph i) -> [Label] cmmDebugLabels is_valid_label isMeta nats = seqList lbls lbls
GHC/Cmm/InitFini.hs view
@@ -2,7 +2,6 @@ module GHC.Cmm.InitFini     ( InitOrFini(..)     , isInitOrFiniArray-    , isInitOrFiniSection     ) where  import GHC.Prelude@@ -64,8 +63,8 @@ data InitOrFini = IsInitArray | IsFiniArray  isInitOrFiniArray :: RawCmmDecl -> Maybe (InitOrFini, [CLabel])-isInitOrFiniArray (CmmData (Section t _) (CmmStaticsRaw _ lits))-  | Just initOrFini <- isInitOrFiniSection t+isInitOrFiniArray (CmmData sect (CmmStaticsRaw _ lits))+  | Just initOrFini <- isInitOrFiniSection sect   = Just (initOrFini, map get_label lits)   where     get_label :: CmmStatic -> CLabel@@ -73,7 +72,7 @@     get_label static = pprPanic "isInitOrFiniArray: invalid entry" (ppr static) isInitOrFiniArray _ = Nothing -isInitOrFiniSection :: SectionType -> Maybe InitOrFini-isInitOrFiniSection InitArray = Just IsInitArray-isInitOrFiniSection FiniArray = Just IsFiniArray+isInitOrFiniSection :: Section -> Maybe InitOrFini+isInitOrFiniSection (Section InitArray _) = Just IsInitArray+isInitOrFiniSection (Section FiniArray _) = Just IsFiniArray isInitOrFiniSection _                     = Nothing
GHC/Cmm/LayoutStack.hs view
@@ -36,6 +36,7 @@ import Control.Monad.Fix import Data.Array as Array import Data.List (nub)+import Data.List.NonEmpty ( NonEmpty (..) )  {- Note [Stack Layout]    ~~~~~~~~~~~~~~~~~~~@@ -346,7 +347,7 @@            this_sp_hwm | isGcJump last0 = 0                        | otherwise      = sp0 - sp_off -           hwm' = maximum (acc_hwm : this_sp_hwm : map sm_sp (mapElems out))+           hwm' = maximum (acc_hwm :| this_sp_hwm : map sm_sp (mapElems out))         go bs acc_stackmaps' hwm' (final_blocks ++ acc_blocks) @@ -373,7 +374,7 @@  collectContInfo :: [CmmBlock] -> (ByteOff, LabelMap ByteOff) collectContInfo blocks-  = (maximum ret_offs, mapFromList (catMaybes mb_argss))+  = (maximum (expectNonEmpty ret_offs), mapFromList (catMaybes mb_argss))  where   (mb_argss, ret_offs) = mapAndUnzip get_cont blocks 
GHC/Cmm/Lexer.hs view
@@ -1,7 +1,7 @@ {-# OPTIONS_GHC -fno-warn-unused-binds -fno-warn-missing-signatures #-} {-# LANGUAGE CPP #-} {-# LANGUAGE MagicHash #-}-{-# LINE 13 "_build/source-dist/ghc-9.12.4-src/ghc-9.12.4/compiler/GHC/Cmm/Lexer.x" #-}+{-# LINE 13 "_build/source-dist/ghc-9.14.1-src/ghc-9.14.1/compiler/GHC/Cmm/Lexer.x" #-} module GHC.Cmm.Lexer (    CmmToken(..), cmmlex,   ) where@@ -831,7 +831,7 @@         -- match when checking the right context, just         -- the first match will do. #endif-{-# LINE 144 "_build/source-dist/ghc-9.12.4-src/ghc-9.12.4/compiler/GHC/Cmm/Lexer.x" #-}+{-# LINE 144 "_build/source-dist/ghc-9.14.1-src/ghc-9.14.1/compiler/GHC/Cmm/Lexer.x" #-} data CmmToken   = CmmT_SpecChar  Char   | CmmT_DotDot
GHC/Cmm/Lint.hs view
@@ -102,9 +102,11 @@   platform <- getPlatform   tys <- mapM lintCmmExpr args   lintShiftOp op (zip args tys)-  if map (typeWidth . cmmExprType platform) args == machOpArgReps platform op-        then cmmCheckMachOp op args tys-        else cmmLintMachOpErr expr (map (cmmExprType platform) args) (machOpArgReps platform op)+  let machop_arg_widths = machOpArgReps platform op+      arg_tys           = map (cmmExprType platform) args+  if map typeWidth arg_tys == machop_arg_widths+    then cmmCheckMachOp op args tys+    else cmmLintMachOpErr expr arg_tys machop_arg_widths lintCmmExpr (CmmRegOff reg offset)   = do let rep = typeWidth (cmmRegType reg)        lintCmmExpr (CmmMachOp (MO_Add rep)@@ -180,14 +182,13 @@             return ()    CmmUnsafeForeignCall target _formals actuals -> do-            lintTarget target             let lintArg expr = do                   -- Arguments can't mention caller-saved                   -- registers. See Note [Register parameter passing].                   mayNotMentionCallerSavedRegs (text "foreign call argument") expr                   lintCmmExpr expr--            mapM_ lintArg actuals+            arg_tys <- mapM lintArg actuals+            lintTarget arg_tys target   lintCmmLast :: LabelSet -> CmmNode O C -> CmmLint ()@@ -213,7 +214,6 @@           maybe (return ()) checkTarget cont    CmmForeignCall tgt _ args succ _ _ _ -> do-          lintTarget tgt           let lintArg expr = do                 -- Arguments can't mention caller-saved                 -- registers. See Note [Register@@ -223,19 +223,24 @@                 -- places in caller-saved registers.                 mayNotMentionCallerSavedRegs (text "foreign call argument") expr                 lintCmmExpr expr-          mapM_ lintArg args+          arg_tys <- mapM lintArg args+          lintTarget arg_tys tgt           checkTarget succ  where   checkTarget id      | setMember id labels = return ()      | otherwise = cmmLintErr (text "Branch to nonexistent id" <+> ppr id) -lintTarget :: ForeignTarget -> CmmLint ()-lintTarget (ForeignTarget e _) = do+lintTarget :: [CmmType] -> ForeignTarget -> CmmLint ()+lintTarget _arg_tys (ForeignTarget e _) = do     mayNotMentionCallerSavedRegs (text "foreign target") e     _ <- lintCmmExpr e     return ()-lintTarget (PrimTarget {})     = return ()+lintTarget arg_tys (PrimTarget mop) = do+  platform <- getPlatform+  let machop_arg_tys = callishMachOpArgTys platform mop+  unless (and $ zipWith cmmCompatType arg_tys machop_arg_tys) $+    cmmLintCallishMachOpErr mop arg_tys machop_arg_tys  -- | As noted in Note [Register parameter passing], the arguments and -- 'ForeignTarget' of a foreign call mustn't mention@@ -285,6 +290,13 @@                    nest 2 (pdoc platform expr) $$                       (text "op is expecting: " <+> ppr opExpectsRep) $$                       (text "arguments provide: " <+> ppr argsRep))++cmmLintCallishMachOpErr :: CallishMachOp -> [CmmType] -> [CmmType] -> CmmLint a+cmmLintCallishMachOpErr mop argTys mopTys+     = cmmLintErr (text "in Callish MachOp application: " $$+                   nest 2 (text $ show mop) $$+                      (text "op is expecting: " <+> ppr mopTys) $$+                      (text "arguments provide: " <+> ppr argTys))  cmmLintAssignErr :: CmmNode e x -> CmmType -> CmmType -> CmmLint a cmmLintAssignErr stmt e_ty r_ty
GHC/Cmm/Liveness.hs view
@@ -57,7 +57,7 @@   where     entry = g_entry graph     check facts =-        noLiveOnEntry entry (expectJust "check" $ mapLookup entry facts) facts+        noLiveOnEntry entry (expectJust $ mapLookup entry facts) facts  cmmGlobalLiveness :: Platform -> CmmGraph -> BlockEntryLiveness GlobalRegUse cmmGlobalLiveness platform graph =@@ -120,7 +120,7 @@   where     entry = g_entry graph     check facts =-        noLiveOnEntryL entry (expectJust "check" $ mapLookup entry facts) facts+        noLiveOnEntryL entry (expectJust $ mapLookup entry facts) facts  -- | On entry to the procedure, there had better not be any LocalReg's live-in. noLiveOnEntryL :: BlockId -> LRegSet -> a -> a@@ -154,5 +154,4 @@     let joined = gen_killL platform xNode $! joinOutFacts liveLatticeL xNode fBase         !result = foldNodesBwdOO (gen_killL platform) middle joined     in mapSingleton (entryLabel eNode) result- 
GHC/Cmm/MachOp.hs view
@@ -1,7 +1,5 @@ {-# LANGUAGE LambdaCase #-} -{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-}- module GHC.Cmm.MachOp     ( MachOp(..)     , pprMachOp, isCommutableMachOp, isAssociativeMachOp@@ -24,6 +22,7 @@     , CallishMachOp(..), callishMachOpHints     , pprCallishMachOp     , machOpMemcpyishAlign+    , callishMachOpArgTys      -- Atomic read-modify-write     , MemoryOrdering(..)@@ -39,7 +38,10 @@ import GHC.Platform import GHC.Cmm.Type import GHC.Utils.Outputable+import GHC.Utils.Misc (expectNonEmpty) +import Data.List.NonEmpty (NonEmpty (..))+ ----------------------------------------------------------------------------- --              MachOp -----------------------------------------------------------------------------@@ -168,16 +170,8 @@   | MO_V_Add Length Width   | MO_V_Sub Length Width   | MO_V_Mul Length Width--  -- Signed vector multiply/divide-  | MO_VS_Quot Length Width-  | MO_VS_Rem  Length Width   | MO_VS_Neg  Length Width -  -- Unsigned vector multiply/divide-  | MO_VU_Quot Length Width-  | MO_VU_Rem  Length Width-   -- Vector shuffles   | MO_V_Shuffle  Length Width [Int]   | MO_VF_Shuffle Length Width [Int]@@ -513,14 +507,10 @@     MO_V_Sub l w        -> cmmVec l (cmmBits w)     MO_V_Mul l w        -> cmmVec l (cmmBits w) -    MO_VS_Quot l w      -> cmmVec l (cmmBits w)-    MO_VS_Rem  l w      -> cmmVec l (cmmBits w)     MO_VS_Neg  l w      -> cmmVec l (cmmBits w)     MO_VS_Min  l w      -> cmmVec l (cmmBits w)     MO_VS_Max  l w      -> cmmVec l (cmmBits w) -    MO_VU_Quot l w      -> cmmVec l (cmmBits w)-    MO_VU_Rem  l w      -> cmmVec l (cmmBits w)     MO_VU_Min  l w      -> cmmVec l (cmmBits w)     MO_VU_Max  l w      -> cmmVec l (cmmBits w) @@ -542,7 +532,7 @@     MO_RelaxedRead w    -> cmmBits w     MO_AlignmentCheck _ _ -> ty1   where-    (ty1:_) = tys+    ty1:|_ = expectNonEmpty tys  comparisonResultRep :: Platform -> CmmType comparisonResultRep = bWord  -- is it?@@ -630,14 +620,10 @@     MO_V_Sub l w        -> [vecwidth l w, vecwidth l w]     MO_V_Mul l w        -> [vecwidth l w, vecwidth l w] -    MO_VS_Quot l w      -> [vecwidth l w, vecwidth l w]-    MO_VS_Rem  l w      -> [vecwidth l w, vecwidth l w]     MO_VS_Neg  l w      -> [vecwidth l w]     MO_VS_Min  l w      -> [vecwidth l w, vecwidth l w]     MO_VS_Max  l w      -> [vecwidth l w, vecwidth l w] -    MO_VU_Quot l w      -> [vecwidth l w, vecwidth l w]-    MO_VU_Rem  l w      -> [vecwidth l w, vecwidth l w]     MO_VU_Min  l w      -> [vecwidth l w, vecwidth l w]     MO_VU_Max  l w      -> [vecwidth l w, vecwidth l w] @@ -751,6 +737,20 @@   | MO_SubIntC   Width   | MO_U_Mul2    Width +  -- Signed vector divide+  | MO_VS_Quot Length Width+  | MO_VS_Rem  Length Width++  -- Unsigned vector divide+  | MO_VU_Quot Length Width+  | MO_VU_Rem  Length Width++  -- Int64X2/Word64X2 min/max+  | MO_I64X2_Min+  | MO_I64X2_Max+  | MO_W64X2_Min+  | MO_W64X2_Max+   | MO_Touch         -- Keep variables live (when using interior pointers)    -- Prefetch@@ -845,3 +845,144 @@   MO_Memmove align -> Just align   MO_Memcmp  align -> Just align   _                -> Nothing++-- | Like 'machOpArgReps', but for 'CallishMachOp'.+--+-- Used only in Cmm lint.+callishMachOpArgTys :: Platform -> CallishMachOp -> [CmmType]+callishMachOpArgTys platform = \case+  MO_F64_Pwr -> [f64, f64]+  MO_F64_Sin -> [f64]+  MO_F64_Cos -> [f64]+  MO_F64_Tan -> [f64]+  MO_F64_Sinh -> [f64]+  MO_F64_Cosh -> [f64]+  MO_F64_Tanh -> [f64]+  MO_F64_Asin -> [f64]+  MO_F64_Acos -> [f64]+  MO_F64_Atan -> [f64]+  MO_F64_Asinh -> [f64]+  MO_F64_Acosh -> [f64]+  MO_F64_Atanh -> [f64]+  MO_F64_Log -> [f64]+  MO_F64_Log1P -> [f64]+  MO_F64_Exp -> [f64]+  MO_F64_ExpM1 -> [f64]+  MO_F64_Fabs -> [f64]+  MO_F64_Sqrt -> [f64]+  MO_F32_Pwr -> [f32, f32]+  MO_F32_Sin -> [f32]+  MO_F32_Cos -> [f32]+  MO_F32_Tan -> [f32]+  MO_F32_Sinh -> [f32]+  MO_F32_Cosh -> [f32]+  MO_F32_Tanh -> [f32]+  MO_F32_Asin -> [f32]+  MO_F32_Acos -> [f32]+  MO_F32_Atan -> [f32]+  MO_F32_Asinh -> [f32]+  MO_F32_Acosh -> [f32]+  MO_F32_Atanh -> [f32]+  MO_F32_Log -> [f32]+  MO_F32_Log1P -> [f32]+  MO_F32_Exp -> [f32]+  MO_F32_ExpM1 -> [f32]+  MO_F32_Fabs -> [f32]+  MO_F32_Sqrt -> [f32]+  MO_I64_ToI -> [b64]+  MO_I64_FromI -> [bWord platform]+  MO_W64_ToW -> [b64]+  MO_W64_FromW -> [bWord platform]+  MO_x64_Neg -> [b64]+  MO_x64_Add -> [b64]+  MO_x64_Sub -> [b64]+  MO_x64_Mul -> [b64]+  MO_I64_Quot -> [b64,b64]+  MO_I64_Rem -> [b64,b64]+  MO_W64_Quot -> [b64,b64]+  MO_W64_Rem -> [b64,b64]+  MO_x64_And -> [b64,b64]+  MO_x64_Or -> [b64,b64]+  MO_x64_Xor -> [b64,b64]+  MO_x64_Not -> [b64]+  MO_x64_Shl -> [b64,b64]+  MO_I64_Shr -> [b64,b64]+  MO_W64_Shr -> [b64,b64]+  MO_x64_Eq -> [b64,b64]+  MO_x64_Ne -> [b64,b64]+  MO_I64_Ge -> [b64,b64]+  MO_I64_Gt -> [b64,b64]+  MO_I64_Le -> [b64,b64]+  MO_I64_Lt -> [b64,b64]+  MO_W64_Ge -> [b64,b64]+  MO_W64_Gt -> [b64,b64]+  MO_W64_Le -> [b64,b64]+  MO_W64_Lt -> [b64,b64]+  MO_UF_Conv _w -> [bWord platform] -- Word to Float/Double+  MO_S_Mul2    w -> [cmmBits w, cmmBits w]+  MO_S_QuotRem w -> [cmmBits w, cmmBits w]+  MO_U_QuotRem w -> [cmmBits w, cmmBits w]+  MO_U_QuotRem2 w -> [cmmBits w, cmmBits w]+  MO_Add2      w -> [cmmBits w, cmmBits w]+  MO_AddWordC  w -> [cmmBits w, cmmBits w]+  MO_SubWordC  w -> [cmmBits w, cmmBits w]+  MO_AddIntC   w -> [cmmBits w, cmmBits w]+  MO_SubIntC   w -> [cmmBits w, cmmBits w]+  MO_U_Mul2    w -> [cmmBits w, cmmBits w]+  MO_VS_Quot l w -> [cmmVec l (cmmBits w), cmmVec l (cmmBits w)]+  MO_VS_Rem  l w -> [cmmVec l (cmmBits w), cmmVec l (cmmBits w)]+  MO_VU_Quot l w -> [cmmVec l (cmmBits w), cmmVec l (cmmBits w)]+  MO_VU_Rem  l w -> [cmmVec l (cmmBits w), cmmVec l (cmmBits w)]+  MO_I64X2_Min -> [cmmVec 2 (cmmBits W64), cmmVec 2 (cmmBits W64)]+  MO_I64X2_Max -> [cmmVec 2 (cmmBits W64), cmmVec 2 (cmmBits W64)]+  MO_W64X2_Min -> [cmmVec 2 (cmmBits W64), cmmVec 2 (cmmBits W64)]+  MO_W64X2_Max -> [cmmVec 2 (cmmBits W64), cmmVec 2 (cmmBits W64)]+  MO_Touch -> [gcWord platform]+  MO_Prefetch_Data _n -> [addr]+  MO_Memcpy _align -> [addr, addr, bWord platform]+  MO_Memset _align ->+    [ addr+    , bWord platform -- byte to set: supplied as an int, converted to a byte+    , bWord platform]+  MO_Memmove _align -> [addr, addr, bWord platform]+  MO_Memcmp _align -> [addr, addr, bWord platform]+  MO_PopCnt w ->+    case w of+      W64 -> [cmmBits W64]+      _   -> [bWord platform]+  MO_Pdep w ->+    case w of+      W64 -> [cmmBits W64, cmmBits W64]+      _   -> [bWord platform, bWord platform]+  MO_Pext w ->+    case w of+      W64 -> [cmmBits W64, cmmBits W64]+      _   -> [bWord platform, bWord platform]+  MO_Clz w ->+    case w of+      W64 -> [cmmBits W64]+      _   -> [bWord platform]+  MO_Ctz w ->+    case w of+      W64 -> [cmmBits W64]+      _   -> [bWord platform]+  MO_BSwap w ->+    case w of+      W64 -> [cmmBits W64]+      _   -> [bWord platform]+  MO_BRev w ->+    case w of+      W64 -> [cmmBits W64]+      _   -> [bWord platform]+  MO_AcquireFence -> []+  MO_ReleaseFence -> []+  MO_SeqCstFence -> []+  MO_AtomicRMW w _op -> [addr, cmmBits w]+  MO_AtomicRead _w _mem_ordering -> [addr]+  MO_AtomicWrite w _mem_ordering -> [addr, cmmBits w]+  MO_Cmpxchg w -> [addr, cmmBits w, cmmBits w]+  MO_Xchg w -> [addr, cmmBits w]+  MO_SuspendThread -> []+  MO_ResumeThread -> []+  where+    addr = bWord platform
GHC/Cmm/Opt.hs view
@@ -174,9 +174,9 @@         MO_S_Lt _ -> Just $! CmmLit (CmmInt (if x_s <  y_s then 1 else 0) (wordWidth platform))         MO_S_Le _ -> Just $! CmmLit (CmmInt (if x_s <= y_s then 1 else 0) (wordWidth platform)) -        MO_Add r -> Just $! CmmLit (CmmInt (x + y) r)-        MO_Sub r -> Just $! CmmLit (CmmInt (x - y) r)-        MO_Mul r -> Just $! CmmLit (CmmInt (x * y) r)+        MO_Add r -> Just $! CmmLit (CmmInt (narrowU r $ x + y) r)+        MO_Sub r -> Just $! CmmLit (CmmInt (narrowS r $ x - y) r)+        MO_Mul r -> Just $! CmmLit (CmmInt (narrowU r $ x * y) r)         MO_U_Quot r | y /= 0 -> Just $! CmmLit (CmmInt (x_u `quot` y_u) r)         MO_U_Rem  r | y /= 0 -> Just $! CmmLit (CmmInt (x_u `rem`  y_u) r)         MO_S_Quot r | y /= 0 -> Just $! CmmLit (CmmInt (x_s `quot` y_s) r)@@ -186,7 +186,7 @@         MO_Or    r -> Just $! CmmLit (CmmInt (x .|. y) r)         MO_Xor   r -> Just $! CmmLit (CmmInt (x `xor` y) r) -        MO_Shl   r -> Just $! CmmLit (CmmInt (x   `shiftL` fromIntegral y) r)+        MO_Shl   r -> Just $! CmmLit (CmmInt (narrowU r $ x   `shiftL` fromIntegral y) r)         MO_U_Shr r -> Just $! CmmLit (CmmInt (x_u `shiftR` fromIntegral y) r)         MO_S_Shr r -> Just $! CmmLit (CmmInt (x_s `shiftR` fromIntegral y) r) 
GHC/Cmm/ProcPoint.hs view
@@ -263,7 +263,7 @@    let liveness = cmmGlobalLiveness platform g   let ppLiveness pp = filter (isArgReg . globalRegUse_reg) $ regSetToList $-                        expectJust "ppLiveness" $ mapLookup pp liveness+                        expectJust $ mapLookup pp liveness   graphEnv <- return $ foldlGraphBlocks add_block mapEmpty g    -- Build a map from proc point BlockId to pairs of:@@ -325,7 +325,7 @@         (jumpEnv, jumpBlocks) <-            foldM add_jump_block (mapEmpty, []) needed_jumps             -- update the entry block-        let b = expectJust "block in env" $ mapLookup ppId blockEnv+        let b = expectJust $ mapLookup ppId blockEnv             blockEnv' = mapInsert ppId b blockEnv             -- replace branches to procpoints with branches to jumps             blockEnv'' = toBlockMap $ replaceBranches jumpEnv $ ofBlockMap ppId blockEnv'@@ -343,7 +343,7 @@                                stack_info = stack_info})                      top_l live g'           | otherwise-          = case expectJust "pp label" $ mapLookup bid procLabels of+          = case expectJust $ mapLookup bid procLabels of               (lbl, Just info_lbl)                  -> CmmProc (TopInfo { info_tbls = mapSingleton (g_entry g) (mkEmptyContInfoTable info_lbl)                                      , stack_info=stack_info})@@ -377,8 +377,8 @@           foldl' add_block_num (0::Int, mapEmpty :: LabelMap Int)                 (revPostorder g)   let sort_fn (bid, _) (bid', _) =-        compare (expectJust "block_order" $ mapLookup bid  block_order)-                (expectJust "block_order" $ mapLookup bid' block_order)+        compare (expectJust $ mapLookup bid  block_order)+                (expectJust $ mapLookup bid' block_order)    return $ map to_proc $ sortBy sort_fn $ mapToList graphEnv 
GHC/Cmm/Sink.hs view
@@ -26,74 +26,76 @@  import GHC.Exts (inline) ----------------------------------------------------------------------------------{- Note [Sinking and inlining]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-Sinking is an optimisation pass that- (a) moves assignments closer to their uses, to reduce register pressure- (b) pushes assignments into a single branch of a conditional if possible- (c) inlines assignments to registers that are mentioned only once- (d) discards dead assignments--This tightens up lots of register-heavy code.  It is particularly-helpful in the Cmm generated by the Stg->Cmm code generator, in-which every function starts with a copyIn sequence like:--   x1 = R1-   x2 = Sp[8]-   x3 = Sp[16]-   if (Sp - 32 < SpLim) then L1 else L2--we really want to push the x1..x3 assignments into the L2 branch.--Algorithm:-- * Start by doing liveness analysis.-- * Keep a list of assignments A; earlier ones may refer to later ones.-   Currently we only sink assignments to local registers, because we don't-   have liveness information about global registers.-- * Walk forwards through the graph, look at each node N:--   * If it is a dead assignment, i.e. assignment to a register that is-     not used after N, discard it.--   * Try to inline based on current list of assignments-     * If any assignments in A (1) occur only once in N, and (2) are-       not live after N, inline the assignment and remove it-       from A.--     * If an assignment in A is cheap (RHS is local register), then-       inline the assignment and keep it in A in case it is used afterwards.--     * Otherwise don't inline.--   * If N is an assignment to a local register, pick up the assignment-     and add it to A.--   * If N is not an assignment to a local register:-     * remove any assignments from A that conflict with N, and-       place them before N in the current block.  We call this-       "dropping" the assignments.-       (See Note [When does an assignment conflict?] for what it means for-        A to conflict with N.)--     * do this recursively, dropping dependent assignments--   * At an exit node:-     * drop any assignments that are live on more than one successor-       and are not trivial-     * if any successor has more than one predecessor (a join-point),-       drop everything live in that successor. Since we only propagate-       assignments that are not dead at the successor, we will therefore-       eliminate all assignments dead at this point. Thus analysis of a-       join-point will always begin with an empty list of assignments.+-- -----------------------------------------------------------------------------+-- Sinking and inlining -As a result of above algorithm, sinking deletes some dead assignments-(transitively, even).  This isn't as good as removeDeadAssignments,-but it's much cheaper.--}+-- This is an optimisation pass that+--  (a) moves assignments closer to their uses, to reduce register pressure+--  (b) pushes assignments into a single branch of a conditional if possible+--  (c) inlines assignments to registers that are mentioned only once+--  (d) discards dead assignments+--+-- This tightens up lots of register-heavy code.  It is particularly+-- helpful in the Cmm generated by the Stg->Cmm code generator, in+-- which every function starts with a copyIn sequence like:+--+--    x1 = R1+--    x2 = Sp[8]+--    x3 = Sp[16]+--    if (Sp - 32 < SpLim) then L1 else L2+--+-- we really want to push the x1..x3 assignments into the L2 branch.+--+-- Algorithm:+--+--  * Start by doing liveness analysis.+--+--  * Keep a list of assignments A; earlier ones may refer to later ones.+--    Currently we only sink assignments to local registers, because we don't+--    have liveness information about global registers.+--+--  * Walk forwards through the graph, look at each node N:+--+--    * If it is a dead assignment, i.e. assignment to a register that is+--      not used after N, discard it.+--+--    * Try to inline based on current list of assignments+--      * If any assignments in A (1) occur only once in N, and (2) are+--        not live after N, inline the assignment and remove it+--        from A.+--+--      * If an assignment in A is cheap (RHS is local register), then+--        inline the assignment and keep it in A in case it is used afterwards.+--+--      * Otherwise don't inline.+--+--    * If N is assignment to a local register pick up the assignment+--      and add it to A.+--+--    * If N is not an assignment to a local register:+--      * remove any assignments from A that conflict with N, and+--        place them before N in the current block.  We call this+--        "dropping" the assignments.+--+--      * An assignment conflicts with N if it:+--        - assigns to a register mentioned in N+--        - mentions a register assigned by N+--        - reads from memory written by N+--      * do this recursively, dropping dependent assignments+--+--    * At an exit node:+--      * drop any assignments that are live on more than one successor+--        and are not trivial+--      * if any successor has more than one predecessor (a join-point),+--        drop everything live in that successor. Since we only propagate+--        assignments that are not dead at the successor, we will therefore+--        eliminate all assignments dead at this point. Thus analysis of a+--        join-point will always begin with an empty list of assignments.+--+--+-- As a result of above algorithm, sinking deletes some dead assignments+-- (transitively, even).  This isn't as good as removeDeadAssignments,+-- but it's much cheaper.  -- ----------------------------------------------------------------------------- -- things that we aren't optimising very well yet.@@ -646,171 +648,110 @@  -- ----------------------------------------------------------------------------- -{- Note [When does an assignment conflict?]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-An assignment 'A' conflicts with a statement 'N' if any of the following-conditions are satisfied:--  (C1) 'A' assigns to a register mentioned in 'N'-  (C2) 'A' mentions a register assigned by 'N'-  (C3) 'A' reads from memory written by 'N'--In such a situation, it is not safe to commute 'A' past 'N'. For example,-it is not safe to commute--  A: r = 1-  N: s = r--because 'r' may be undefined or hold a different value before 'A'.--Remarks:--  (C3) includes all foreign calls, as they may modify the heap/stack.--  (C1) includes the following two situations:--    (C1a) 'N' defines the LHS register in the assignment 'A', for example:--      A: r = <expr>-      N: r = <other_expr>--    (C1b) 'N' defines a register used in the RHS of 'A', for example:--      A: r = s-      N: s = <expr>--    (C1c) 'suspendThread' clobbers every global register not backed by a-          real register, as noted in #19237.--Forgetting (C1a) led to bug #26550, in which we incorrectly commuted--  A: _c1rB::Fx2V128 = <0.0 :: W64, 0.0 :: W64>-  N: _c1rB::Fx2V128 = %MO_VF_Insert_2_W64(<0.0 :: W64,0.0 :: W64>,%MO_F_Add_W64(F64[R1 + 7], 3.0 :: W64),0 :: W32)---}- -- | @conflicts (r,e) node@ is @False@ if and only if the assignment -- @r = e@ can be safely commuted past statement @node@.------ See Note [When does an assignment conflict?]. conflicts :: Platform -> Assignment -> CmmNode O x -> Bool-conflicts platform assig@(r, rhs, addr) node+conflicts platform (r, rhs, addr) node -  -- (C1) node defines registers that are either the assigned register or-  -- are used by the rhs of the assignment.-  -- This catches assignments and all three kinds of calls.-  -- See Note [Sinking and calls]-  | globalRegistersConflict platform rhs   node                     = True-  | localRegistersConflict  platform assig node                     = True+  -- (1) node defines registers used by rhs of assignment. This catches+  -- assignments and all three kinds of calls. See Note [Sinking and calls]+  | globalRegistersConflict platform rhs node                       = True+  | localRegistersConflict  platform rhs node                       = True -  -- (C2) node uses register defined by assignment+  -- (2) node uses register defined by assignment   | foldRegsUsed platform (\b r' -> r == r' || b) False node        = True -  -- (C3) Node writes to memory that is read by the assignment.--  -- (a) a store to an address conflicts with a read of the same memory+  -- (3) a store to an address conflicts with a read of the same memory   | CmmStore addr' e _ <- node   , memConflicts addr (loadAddr platform addr' (cmmExprWidth platform e)) = True -  -- (b) an assignment to Hp/Sp conflicts with a heap/stack read respectively-  | CmmAssign (CmmGlobal (GlobalRegUse Hp _)) _ <- node-  , memConflicts addr HeapMem-  = True-  | CmmAssign (CmmGlobal (GlobalRegUse Sp _)) _ <- node-  , memConflicts addr StackMem-  = True+  -- (4) an assignment to Hp/Sp conflicts with a heap/stack read respectively+  | HeapMem    <- addr, CmmAssign (CmmGlobal (GlobalRegUse Hp _)) _ <- node        = True+  | StackMem   <- addr, CmmAssign (CmmGlobal (GlobalRegUse Sp _)) _ <- node        = True+  | SpMem{}    <- addr, CmmAssign (CmmGlobal (GlobalRegUse Sp _)) _ <- node        = True -  -- (c) foreign calls clobber heap: see Note [Foreign calls clobber heap]+  -- (5) foreign calls clobber heap: see Note [Foreign calls clobber heap]   | CmmUnsafeForeignCall{} <- node, memConflicts addr AnyMem      = True -  -- (d) native calls clobber any memory-  | CmmCall{} <- node, memConflicts addr AnyMem                   = True--  -- (C1c) suspendThread clobbers every global register not backed by a real-  -- register. (It also clobbers heap and stack, but this is handled by (C3)(c) above.)+  -- (6) suspendThread clobbers every global register not backed by a real+  -- register. It also clobbers heap and stack but this is handled by (5)   | CmmUnsafeForeignCall (PrimTarget MO_SuspendThread) _ _ <- node   , foldRegsUsed platform (\b g -> globalRegMaybe platform g == Nothing || b) False rhs   = True +  -- (7) native calls clobber any memory+  | CmmCall{} <- node, memConflicts addr AnyMem                   = True++  -- (8) otherwise, no conflict   | otherwise = False  {- Note [Inlining foldRegsDefd]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-foldRegsDefd is, after optimization, *not* a small function so-it's only marked INLINEABLE, but not INLINE.+   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~+   foldRegsDefd is, after optimization, *not* a small function so+   it's only marked INLINEABLE, but not INLINE. -However in some specific cases we call it *very* often making it-important to avoid the overhead of allocating the folding function.+   However in some specific cases we call it *very* often making it+   important to avoid the overhead of allocating the folding function. -So we simply force inlining via the magic inline function.-For T3294 this improves allocation with -O by ~1%.+   So we simply force inlining via the magic inline function.+   For T3294 this improves allocation with -O by ~1%.+ -} --- | Returns @True@ if @node@ defines any global registers that are used in the--- Cmm expression.------ See (C1) in Note [When does an assignment conflict?].+-- Returns True if node defines any global registers that are used in the+-- Cmm expression globalRegistersConflict :: Platform -> CmmExpr -> CmmNode e x -> Bool globalRegistersConflict platform expr node =    -- See Note [Inlining foldRegsDefd]    inline foldRegsDefd platform (\b r -> b || globalRegUsedIn platform (globalRegUse_reg r) expr)                 False node-    -- NB: no need to worry about (C1a), as the LHS of an assignment is always-    -- a local register, never a global register. --- | Given an assignment @local_reg := expr@, return @True@ if @node@ defines any--- local registers mentioned in the assignment.------ See (C1) in Note [When does an assignment conflict?].-localRegistersConflict :: Platform -> Assignment -> CmmNode e x -> Bool-localRegistersConflict platform (r, expr, _) node =+-- Returns True if node defines any local registers that are used in the+-- Cmm expression+localRegistersConflict :: Platform -> CmmExpr -> CmmNode e x -> Bool+localRegistersConflict platform expr node =     -- See Note [Inlining foldRegsDefd]-    inline foldRegsDefd platform-      (\b r' ->-           b-        || r' == r -- (C1a)-        || regUsedIn platform (CmmLocal r') expr -- (C1b)-      )-      False node--{- Note [Sinking and calls]-~~~~~~~~~~~~~~~~~~~~~~~~~~~-We have three kinds of calls: normal (CmmCall), safe foreign (CmmForeignCall)-and unsafe foreign (CmmUnsafeForeignCall). We perform sinking pass after-stack layout (see Note [Sinking after stack layout]) which leads to two-invariants related to calls:--  a) during stack layout phase all safe foreign calls are turned into-     unsafe foreign calls (see Note [Lower safe foreign calls]). This-     means that we will never encounter CmmForeignCall node when running-     sinking after stack layout--  b) stack layout saves all variables live across a call on the stack-     just before making a call (remember we are not sinking assignments to-     stack):--      L1:-         x = R1-         P64[Sp - 16] = L2-         P64[Sp - 8]  = x-         Sp = Sp - 16-         call f() returns L2-      L2:--     We will attempt to sink { x = R1 } but we will detect conflict with-     { P64[Sp - 8]  = x } and hence we will drop { x = R1 } without even-     checking whether it conflicts with { call f() }. In this way we will-     never need to check any assignment conflicts with CmmCall. Remember-     that we still need to check for potential memory conflicts.+    inline foldRegsDefd platform (\b r -> b || regUsedIn platform (CmmLocal  r) expr)+                 False node -So the result is that we only need to worry about CmmUnsafeForeignCall nodes-when checking conflicts (see Note [Unsafe foreign calls clobber caller-save registers]).-This assumption holds only when we do sinking after stack layout. If we run-it before stack layout we need to check for possible conflicts with all three-kinds of calls. Our `conflicts` function does that by using a generic-foldRegsDefd and foldRegsUsed functions defined in DefinerOfRegs and-UserOfRegs typeclasses.--}+-- Note [Sinking and calls]+-- ~~~~~~~~~~~~~~~~~~~~~~~~+-- We have three kinds of calls: normal (CmmCall), safe foreign (CmmForeignCall)+-- and unsafe foreign (CmmUnsafeForeignCall). We perform sinking pass after+-- stack layout (see Note [Sinking after stack layout]) which leads to two+-- invariants related to calls:+--+--   a) during stack layout phase all safe foreign calls are turned into+--      unsafe foreign calls (see Note [Lower safe foreign calls]). This+--      means that we will never encounter CmmForeignCall node when running+--      sinking after stack layout+--+--   b) stack layout saves all variables live across a call on the stack+--      just before making a call (remember we are not sinking assignments to+--      stack):+--+--       L1:+--          x = R1+--          P64[Sp - 16] = L2+--          P64[Sp - 8]  = x+--          Sp = Sp - 16+--          call f() returns L2+--       L2:+--+--      We will attempt to sink { x = R1 } but we will detect conflict with+--      { P64[Sp - 8]  = x } and hence we will drop { x = R1 } without even+--      checking whether it conflicts with { call f() }. In this way we will+--      never need to check any assignment conflicts with CmmCall. Remember+--      that we still need to check for potential memory conflicts.+--+-- So the result is that we only need to worry about CmmUnsafeForeignCall nodes+-- when checking conflicts (see Note [Unsafe foreign calls clobber caller-save registers]).+-- This assumption holds only when we do sinking after stack layout. If we run+-- it before stack layout we need to check for possible conflicts with all three+-- kinds of calls. Our `conflicts` function does that by using a generic+-- foldRegsDefd and foldRegsUsed functions defined in DefinerOfRegs and+-- UserOfRegs typeclasses.+--  -- An abstraction of memory read or written. data AbsMem
GHC/Cmm/Type.hs view
@@ -57,12 +57,14 @@   deriving Show  data CmmCat                -- "Category" (not exported)-   = GcPtrCat              -- GC pointer-   | BitsCat               -- Non-pointer-   | FloatCat              -- Float-   | VecCat Length CmmCat  -- Vector+   = GcPtrCat              -- ^ GC pointer+   | BitsCat               -- ^ Integer (including non-GC pointer addresses)+                           --+                           -- Makes no distinction between signed and unsigned integers,+                           -- see Note [Signed vs unsigned] in GHC.Cmm.Type.+   | FloatCat              -- ^ Float+   | VecCat Length CmmCat  -- ^ Vector    deriving( Eq, Show )-        -- See Note [Signed vs unsigned] at the end  instance Outputable CmmType where   ppr (CmmType cat wid) = ppr cat <> ppr (widthInBits wid)
GHC/Cmm/Utils.hs view
@@ -1,8 +1,6 @@ {-# LANGUAGE GADTs #-} {-# LANGUAGE LambdaCase #-} -{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-}- ----------------------------------------------------------------------------- -- -- Cmm utilities.@@ -83,6 +81,7 @@  import Data.ByteString (ByteString) import qualified Data.ByteString as BS+import Data.Foldable (toList) import GHC.Cmm.Dataflow.Graph import GHC.Cmm.Dataflow.Label import GHC.Cmm.Dataflow.Block@@ -520,14 +519,12 @@  -- | like 'toBlockList', but the entry block always comes first toBlockListEntryFirst :: CmmGraph -> [CmmBlock]-toBlockListEntryFirst g-  | mapNull m  = []-  | otherwise  = entry_block : others+toBlockListEntryFirst g = do+    entry_block <- toList $ mapLookup entry_id m+    entry_block : filter ((/= entry_id) . entryLabel) (mapElems m)   where     m = toBlockMap g     entry_id = g_entry g-    Just entry_block = mapLookup entry_id m-    others = filter ((/= entry_id) . entryLabel) (mapElems m)  -- | Like 'toBlockListEntryFirst', but we strive to ensure that we order blocks -- so that the false case of a conditional jumps to the next block in the output@@ -538,13 +535,10 @@ -- of successors returned for CmmCondBranch by the NonLocal instance for CmmNode -- defined in "GHC.Cmm.Node". -GBM toBlockListEntryFirstFalseFallthrough :: CmmGraph -> [CmmBlock]-toBlockListEntryFirstFalseFallthrough g-  | mapNull m  = []-  | otherwise  = dfs setEmpty [entry_block]+toBlockListEntryFirstFalseFallthrough g = dfs setEmpty $ toList $ mapLookup entry_id m   where     m = toBlockMap g     entry_id = g_entry g-    Just entry_block = mapLookup entry_id m      dfs :: LabelSet -> [CmmBlock] -> [CmmBlock]     dfs _ [] = []
GHC/CmmToAsm.hs view
@@ -68,6 +68,7 @@ import qualified GHC.CmmToAsm.AArch64 as AArch64 import qualified GHC.CmmToAsm.Wasm as Wasm32 import qualified GHC.CmmToAsm.RV64  as RV64+import qualified GHC.CmmToAsm.LA64 as LA64  import GHC.CmmToAsm.Reg.Liveness import qualified GHC.CmmToAsm.Reg.Linear                as Linear@@ -151,7 +152,7 @@       ArchMipseb    -> panic "nativeCodeGen: No NCG for mipseb"       ArchMipsel    -> panic "nativeCodeGen: No NCG for mipsel"       ArchRISCV64   -> nCG' (RV64.ncgRV64 config)-      ArchLoongArch64->panic "nativeCodeGen: No NCG for LoongArch64"+      ArchLoongArch64 -> nCG' (LA64.ncgLA64 config)       ArchUnknown   -> panic "nativeCodeGen: No NCG for unknown arch"       ArchJavaScript-> panic "nativeCodeGen: No NCG for JavaScript"       ArchWasm32    -> Wasm32.ncgWasm config logger platform ts modLoc h cmms
GHC/CmmToAsm/AArch64/CodeGen.hs view
@@ -1,5 +1,6 @@ {-# language GADTs, LambdaCase #-} {-# LANGUAGE OverloadedStrings #-}+ module GHC.CmmToAsm.AArch64.CodeGen (       cmmTopCodeGen     , generateJumpTableForInstr@@ -23,7 +24,7 @@ import GHC.CmmToAsm.Monad    ( NatM, getNewRegNat    , getPicBaseMaybeNat, getPlatform, getConfig-   , getDebugBlock, getFileId, getThisModuleNat+   , getDebugBlock, getFileId, getNewLabelNat, getThisModuleNat    ) -- import GHC.CmmToAsm.Instr import GHC.CmmToAsm.PIC@@ -50,7 +51,7 @@ import GHC.Data.OrdList import GHC.Utils.Outputable -import Control.Monad    ( mapAndUnzipM, foldM )+import Control.Monad    ( mapAndUnzipM ) import GHC.Float  import GHC.Types.Basic@@ -209,43 +210,83 @@ -- ----------------------------------------------------------------------------- -- Generating a table-branch --- TODO jump tables would be a lot faster, but we'll use bare bones for now.--- this is usually done by sticking the jump table ids into an instruction--- and then have the @generateJumpTableForInstr@ callback produce the jump--- table as a static.------ See Ticket 19912------ data SwitchTargets =---    SwitchTargets---        Bool                       -- Signed values---        (Integer, Integer)         -- Range---        (Maybe Label)              -- Default value---        (M.Map Integer Label)      -- The branches------ Non Jumptable plan:--- xE <- expr+-- | Generate jump to jump table target ---genSwitch :: CmmExpr -> SwitchTargets -> NatM InstrBlock-genSwitch expr targets = do -- pprPanic "genSwitch" (ppr expr)-  (reg, format, code) <- getSomeReg expr-  let w = formatToWidth format-  let mkbranch acc (key, bid) = do-        (keyReg, _format, code) <- getSomeReg (CmmLit (CmmInt key w))-        return $ code `appOL`-                 toOL [ CMP (OpReg w reg) (OpReg w keyReg)-                      , BCOND EQ (TBlock bid)-                      ] `appOL` acc-      def_code = case switchTargetsDefault targets of-        Just bid -> unitOL (B (TBlock bid))-        Nothing  -> nilOL--  switch_code <- foldM mkbranch nilOL (switchTargetsCases targets)-  return $ code `appOL` switch_code `appOL` def_code+-- The index into the jump table is calulated by evaluating @expr@. The+-- corresponding table entry contains the relative address to jump to (relative+-- to the jump table's first entry / the table's own label).+genSwitch :: NCGConfig -> CmmExpr -> SwitchTargets -> NatM InstrBlock+genSwitch config expr targets = do+  (reg, fmt1, e_code) <- getSomeReg indexExpr+  let fmt = II64+  targetReg <- getNewRegNat fmt+  lbl <- getNewLabelNat+  dynRef <- cmmMakeDynamicReference config DataReference lbl+  (tableReg, fmt2, t_code) <- getSomeReg dynRef+  let code =+        toOL+          [ COMMENT (text "indexExpr" <+> (text . show) indexExpr),+            COMMENT (text "dynRef" <+> (text . show) dynRef)+          ]+          `appOL` e_code+          `appOL` t_code+          `appOL` toOL+            [ COMMENT (ftext "Jump table for switch"),+              -- index to offset into the table (relative to tableReg)+              annExpr expr (LSL (OpReg (formatToWidth fmt1) reg) (OpReg (formatToWidth fmt1) reg) (OpImm (ImmInt 3))),+              -- calculate table entry address+              ADD (OpReg W64 targetReg) (OpReg (formatToWidth fmt1) reg) (OpReg (formatToWidth fmt2) tableReg),+              -- load table entry (relative offset from tableReg (first entry) to target label)+              LDR II64 (OpReg W64 targetReg) (OpAddr (AddrRegImm targetReg (ImmInt 0))),+              -- calculate absolute address of the target label+              ADD (OpReg W64 targetReg) (OpReg W64 targetReg) (OpReg W64 tableReg),+              -- prepare jump to target label+              J_TBL ids (Just lbl) targetReg+            ]+  return code+  where+    -- See Note [Sub-word subtlety during jump-table indexing] in+    -- GHC.CmmToAsm.X86.CodeGen for why we must first offset, then widen.+    indexExpr0 = cmmOffset platform expr offset+    -- We widen to a native-width register to sanitize the high bits+    indexExpr =+      CmmMachOp+        (MO_UU_Conv expr_w (platformWordWidth platform))+        [indexExpr0]+    expr_w = cmmExprWidth platform expr+    (offset, ids) = switchTargetsToTable targets+    platform = ncgPlatform config --- We don't do jump tables for now, see Ticket 19912-generateJumpTableForInstr :: NCGConfig -> Instr-  -> Maybe (NatCmmDecl RawCmmStatics Instr)+-- | Generate jump table data (if required)+--+-- The idea is to emit one table entry per case. The entry is the relative+-- address of the block to jump to (relative to the table's first entry /+-- table's own label.) The calculation itself is done by the linker.+generateJumpTableForInstr ::+  NCGConfig ->+  Instr ->+  Maybe (NatCmmDecl RawCmmStatics Instr)+generateJumpTableForInstr config (J_TBL ids (Just lbl) _) =+  let jumpTable =+        map jumpTableEntryRel ids+        where+          jumpTableEntryRel Nothing =+            CmmStaticLit (CmmInt 0 (ncgWordWidth config))+          jumpTableEntryRel (Just blockid) =+            CmmStaticLit+              ( CmmLabelDiffOff+                  blockLabel+                  lbl+                  0+                  (ncgWordWidth config)+              )+            where+              blockLabel = blockLbl blockid+      sectionType = case platformOS (ncgPlatform config) of+        -- Aarch64 Windows platform requires LLVM 20 to support .rodata+        OSMinGW32 -> Text+        _         -> ReadOnlyData+   in Just (CmmData (Section sectionType lbl) (CmmStaticsRaw lbl jumpTable)) generateJumpTableForInstr _ _ = Nothing  -- -----------------------------------------------------------------------------@@ -266,6 +307,7 @@ stmtToInstrs stmt = do   -- traceM $ "-- -------------------------- stmtToInstrs -------------------------- --\n"   --     ++ showSDocUnsafe (ppr stmt)+  config <- getConfig   platform <- getPlatform   case stmt of     CmmUnsafeForeignCall target result_regs args@@ -294,7 +336,7 @@       CmmCondBranch arg true false _prediction ->           genCondBranch true false arg -      CmmSwitch arg ids -> genSwitch arg ids+      CmmSwitch arg ids -> genSwitch config arg ids        CmmCall { cml_target = arg } -> genJump arg @@ -339,12 +381,6 @@         -- ones which map to a real machine register on this         -- platform.  Hence if it's not mapped to a registers something         -- went wrong earlier in the pipeline.--- | Convert a BlockId to some CmmStatic data--- TODO: Add JumpTable Logic, see Ticket 19912--- jumpTableEntry :: NCGConfig -> Maybe BlockId -> CmmStatic--- jumpTableEntry config Nothing   = CmmStaticLit (CmmInt 0 (ncgWordWidth config))--- jumpTableEntry _ (Just blockid) = CmmStaticLit (CmmLabel blockLabel)---     where blockLabel = blockLbl blockid  -- ----------------------------------------------------------------------------- -- General things for putting together code sequences@@ -796,11 +832,7 @@         MO_V_Add {} -> notUnary         MO_V_Sub {} -> notUnary         MO_V_Mul {} -> notUnary-        MO_VS_Quot {} -> notUnary-        MO_VS_Rem {} -> notUnary         MO_VS_Neg {} -> notUnary-        MO_VU_Quot {} -> notUnary-        MO_VU_Rem {} -> notUnary         MO_V_Shuffle {} -> notUnary         MO_VF_Shuffle  {} -> notUnary         MO_VF_Insert {} -> notUnary@@ -1189,11 +1221,7 @@         MO_V_Add {} -> vectorsNeedLlvm         MO_V_Sub {} -> vectorsNeedLlvm         MO_V_Mul {} -> vectorsNeedLlvm-        MO_VS_Quot {} -> vectorsNeedLlvm-        MO_VS_Rem {} -> vectorsNeedLlvm         MO_VS_Neg {} -> vectorsNeedLlvm-        MO_VU_Quot {} -> vectorsNeedLlvm-        MO_VU_Rem {} -> vectorsNeedLlvm         MO_VF_Extract {} -> vectorsNeedLlvm         MO_VF_Add {} -> vectorsNeedLlvm         MO_VF_Sub {} -> vectorsNeedLlvm@@ -2121,7 +2149,7 @@         -- Conversion         MO_UF_Conv w        -> mkCCall (word2FloatLabel w) -        -- Arithmatic+        -- Arithmetic         -- These are not supported on X86, so I doubt they are used much.         MO_S_QuotRem  _w -> unsupported mop         MO_U_QuotRem  _w -> unsupported mop@@ -2131,6 +2159,16 @@         MO_SubWordC   _w -> unsupported mop         MO_AddIntC    _w -> unsupported mop         MO_SubIntC    _w -> unsupported mop++        -- Vector+        MO_VS_Quot {} -> unsupported mop+        MO_VS_Rem {} -> unsupported mop+        MO_VU_Quot {} -> unsupported mop+        MO_VU_Rem {} -> unsupported mop+        MO_I64X2_Min -> unsupported mop+        MO_I64X2_Max -> unsupported mop+        MO_W64X2_Min -> unsupported mop+        MO_W64X2_Max -> unsupported mop          -- Memory Ordering         -- Set flags according to their C pendants (stdatomic.h):
GHC/CmmToAsm/AArch64/Instr.hs view
@@ -29,7 +29,7 @@  import GHC.Utils.Panic -import Data.Maybe (fromMaybe)+import Data.Maybe (fromMaybe, catMaybes)  import GHC.Stack @@ -120,6 +120,7 @@   ORR dst src1 src2        -> usage (regOp src1 ++ regOp src2, regOp dst)   -- 4. Branch Instructions ----------------------------------------------------   J t                      -> usage (regTarget t, [])+  J_TBL _ _ t              -> usage ([t], [])   B t                      -> usage (regTarget t, [])   BCOND _ t                -> usage (regTarget t, [])   BL t ps                  -> usage (regTarget t ++ ps, callerSavedRegisters)@@ -210,7 +211,7 @@ -- | <---- argument passing -------------> | <-- callee saved (lower 64 bits) ---> | <--------------------------------------- caller saved ----------------------> | -- | <------ free registers -------------> | F1 | F2 | F3 | F4 | D1 | D2 | D3 | D4 | <------ free registers -----------------------------------------------------> | -- '---------------------------------------------------------------------------------------------------------------------------------------------------------------'--- IR: Indirect result location register, IP: Intra-procedure register, PL: Platform register, FP: Frame pointer, LR: Link register, SP: Stack pointer+-- IR: Indirect result location register, IP: Intra-procedure register, PL: Platform register (See Note [Aarch64 Register x18 at Darwin and Windows]), FP: Frame pointer, LR: Link register, SP: Stack pointer -- BR: Base, SL: SpLim -- -- TODO: The zero register is currently mapped to -1 but should get it's own separate number.@@ -275,10 +276,11 @@     ORR o1 o2 o3   -> ORR  (patchOp o1) (patchOp o2) (patchOp o3)      -- 4. Branch Instructions ---------------------------------------------------    J t            -> J (patchTarget t)-    B t            -> B (patchTarget t)-    BL t rs        -> BL (patchTarget t) rs-    BCOND c t      -> BCOND c (patchTarget t)+    J t               -> J (patchTarget t)+    J_TBL ids mbLbl t -> J_TBL ids mbLbl (env t)+    B t               -> B (patchTarget t)+    BL t rs           -> BL (patchTarget t) rs+    BCOND c t         -> BCOND c (patchTarget t)      -- 5. Atomic Instructions --------------------------------------------------     -- 6. Conditional Instructions ---------------------------------------------@@ -332,6 +334,7 @@     CBZ{} -> True     CBNZ{} -> True     J{} -> True+    J_TBL{} -> True     B{} -> True     BL{} -> True     BCOND{} -> True@@ -345,6 +348,7 @@ jumpDestsOfInstr (CBZ _ t) = [ id | TBlock id <- [t]] jumpDestsOfInstr (CBNZ _ t) = [ id | TBlock id <- [t]] jumpDestsOfInstr (J t) = [id | TBlock id <- [t]]+jumpDestsOfInstr (J_TBL ids _mbLbl _r) = catMaybes ids jumpDestsOfInstr (B t) = [id | TBlock id <- [t]] jumpDestsOfInstr (BL t _) = [ id | TBlock id <- [t]] jumpDestsOfInstr (BCOND _ t) = [ id | TBlock id <- [t]]@@ -353,6 +357,11 @@ canFallthroughTo :: Instr -> BlockId -> Bool canFallthroughTo (ANN _ i) bid = canFallthroughTo i bid canFallthroughTo (J (TBlock target)) bid = bid == target+canFallthroughTo (J_TBL targets _ _) bid = all isTargetBid targets+  where+    isTargetBid target = case target of+      Nothing -> True+      Just target -> target == bid canFallthroughTo (B (TBlock target)) bid = bid == target canFallthroughTo _ _ = False @@ -366,6 +375,7 @@         CBZ r (TBlock bid) -> CBZ r (TBlock (patchF bid))         CBNZ r (TBlock bid) -> CBNZ r (TBlock (patchF bid))         J (TBlock bid) -> J (TBlock (patchF bid))+        J_TBL ids mbLbl r -> J_TBL (map (fmap patchF) ids) mbLbl r         B (TBlock bid) -> B (TBlock (patchF bid))         BL (TBlock bid) ps -> BL (TBlock (patchF bid)) ps         BCOND c (TBlock bid) -> BCOND c (TBlock (patchF bid))@@ -668,6 +678,7 @@     | CBNZ Operand Target -- if op /= 0, then branch.     -- Branching.     | J Target            -- like B, but only generated from genJump. Used to distinguish genJumps from others.+    | J_TBL [Maybe BlockId] (Maybe CLabel) Reg -- A jump instruction with data for switch/jump tables     | B Target            -- unconditional branching b/br. (To a blockid, label or register)     | BL Target [Reg] -- branch and link (e.g. set x30 to next pc, and branch)     | BCOND Cond Target   -- branch with condition. b.<cond>@@ -758,6 +769,7 @@       CBZ{} -> "CBZ"       CBNZ{} -> "CBNZ"       J{} -> "J"+      J_TBL {} -> "J_TBL"       B{} -> "B"       BL{} -> "BL"       BCOND{} -> "BCOND"
GHC/CmmToAsm/AArch64/Ppr.hs view
@@ -1,5 +1,4 @@ {-# OPTIONS_GHC -fno-warn-orphans #-}-{-# LANGUAGE CPP #-}  module GHC.CmmToAsm.AArch64.Ppr (pprNatCmmDecl, pprInstr, pprBasicBlock) where @@ -20,7 +19,6 @@  import GHC.Cmm.BlockId import GHC.Cmm.CLabel-import GHC.Cmm.InitFini  import GHC.Types.Unique ( pprUniqueAlways, getUnique ) import GHC.Platform@@ -30,7 +28,9 @@  pprNatCmmDecl :: IsDoc doc => NCGConfig -> NatCmmDecl RawCmmStatics Instr -> doc pprNatCmmDecl config (CmmData section dats) =-  pprSectionAlign config section $$ pprDatas config dats+  let platform = ncgPlatform config+  in+  pprSectionAlign config section $$ pprDatas platform dats  pprNatCmmDecl config proc@(CmmProc top_info lbl _ (ListGraph blocks)) =   let platform = ncgPlatform config@@ -42,7 +42,9 @@         pprSectionAlign config (Section Text lbl) $$         -- do not         -- pprProcAlignment config $$-        pprLabel platform lbl $$ -- blocks guaranteed not null, so label needed+        (if lbl /= blockLbl (blockId (head blocks)) -- blocks can have clashed names+          then pprLabel platform lbl -- blocks guaranteed not null, so label needed+          else empty) $$         vcat (map (pprBasicBlock platform with_dwarf top_info) blocks) $$         (if ncgDwarfEnabled config          then line (pprAsmLabel platform (mkAsmTempEndLabel lbl) <> char ':') else empty) $$@@ -91,20 +93,9 @@ pprSectionAlign :: IsDoc doc => NCGConfig -> Section -> doc pprSectionAlign _config (Section (OtherSection _) _) =      panic "AArch64.Ppr.pprSectionAlign: unknown section"-pprSectionAlign config sec@(Section seg suffix) =+pprSectionAlign config sec@(Section seg _) =     line (pprSectionHeader config sec)-    $$ coffSplitSectionComdatKey     $$ pprAlignForSection (ncgPlatform config) seg-  where-    platform = ncgPlatform config-    -- See Note [Split sections on COFF objects]-    coffSplitSectionComdatKey-      | OSMinGW32 <- platformOS platform-      , ncgSplitSections config-      , Nothing <- isInitOrFiniSection seg-      = line (pprCOFFComdatKey platform suffix <> colon)-      | otherwise-      = empty  -- | Output the ELF .size directive. pprSizeDecl :: IsDoc doc => Platform -> CLabel -> doc@@ -147,26 +138,20 @@       (l@LOCATION{} : _) -> pprInstr platform l       _other             -> empty -pprDatas :: IsDoc doc => NCGConfig -> RawCmmStatics -> doc+pprDatas :: IsDoc doc => Platform -> RawCmmStatics -> doc -- See Note [emit-time elimination of static indirections] in "GHC.Cmm.CLabel".-pprDatas config (CmmStaticsRaw alias [CmmStaticLit (CmmLabel lbl), CmmStaticLit ind, _, _])+pprDatas platform (CmmStaticsRaw alias [CmmStaticLit (CmmLabel lbl), CmmStaticLit ind, _, _])   | lbl == mkIndStaticInfoLabel   , let labelInd (CmmLabelOff l _) = Just l         labelInd (CmmLabel l) = Just l         labelInd _ = Nothing   , Just ind' <- labelInd ind   , alias `mayRedirectTo` ind'-  -- See Note [Split sections on COFF objects]-  , not $ platformOS platform == OSMinGW32 && ncgSplitSections config   = pprGloblDecl platform alias     $$ line (text ".equiv" <+> pprAsmLabel platform alias <> comma <> pprAsmLabel platform ind')-    where-      platform = ncgPlatform config -pprDatas config (CmmStaticsRaw lbl dats)+pprDatas platform (CmmStaticsRaw lbl dats)   = vcat (pprLabel platform lbl : map (pprData platform) dats)-    where-      platform = ncgPlatform config  pprData :: IsDoc doc => Platform -> CmmStatic -> doc pprData _platform (CmmString str) = line (pprString str)@@ -441,6 +426,7 @@    -- 4. Branch Instructions ----------------------------------------------------   J t            -> pprInstr platform (B t)+  J_TBL _ _ r    -> pprInstr platform (B (TReg r))   B (TBlock bid) -> line $ text "\tb" <+> pprAsmLabel platform (mkLocalBlockLabel (getUnique bid))   B (TLabel lbl) -> line $ text "\tb" <+> pprAsmLabel platform lbl   B (TReg r)     -> line $ text "\tbr" <+> pprReg W64 r@@ -476,63 +462,51 @@   STR _f o1 o2 -> op2 (text "\tstr") o1 o2   STLR _f o1 o2 -> op2 (text "\tstlr") o1 o2 -#if defined(darwin_HOST_OS)   LDR _f o1 (OpImm (ImmIndex lbl' off)) | Just (_info, lbl) <- dynamicLinkerLabelInfo lbl' ->-    op_adrp o1 (pprAsmLabel platform lbl <> text "@gotpage") $$-    op_ldr o1 (pprAsmLabel platform lbl <> text "@gotpageoff") $$-    op_add o1 (char '#' <> int off) -- TODO: check that off is in 12bits.--  LDR _f o1 (OpImm (ImmIndex lbl off)) | isForeignLabel lbl ->-    op_adrp o1 (pprAsmLabel platform lbl <> text "@gotpage") $$-    op_ldr o1 (pprAsmLabel platform lbl <> text "@gotpageoff") $$-    op_add o1 (char '#' <> int off) -- TODO: check that off is in 12bits.--  LDR _f o1 (OpImm (ImmIndex lbl off)) ->-    op_adrp o1 (pprAsmLabel platform lbl <> text "@page") $$-    op_add o1 (pprAsmLabel platform lbl <> text "@pageoff") $$-    op_add o1 (char '#' <> int off) -- TODO: check that off is in 12bits.--  LDR _f o1 (OpImm (ImmCLbl lbl')) | Just (_info, lbl) <- dynamicLinkerLabelInfo lbl' ->-    op_adrp o1 (pprAsmLabel platform lbl <> text "@gotpage") $$-    op_ldr o1 (pprAsmLabel platform lbl <> text "@gotpageoff")--  LDR _f o1 (OpImm (ImmCLbl lbl)) | isForeignLabel lbl ->-    op_adrp o1 (pprAsmLabel platform lbl <> text "@gotpage") $$-    op_ldr o1 (pprAsmLabel platform lbl <> text "@gotpageoff")--  LDR _f o1 (OpImm (ImmCLbl lbl)) ->-    op_adrp o1 (pprAsmLabel platform lbl <> text "@page") $$-    op_add o1 (pprAsmLabel platform lbl <> text "@pageoff")--#else-  LDR _f o1 (OpImm (ImmIndex lbl' off)) | Just (_info, lbl) <- dynamicLinkerLabelInfo lbl' ->-    op_adrp o1 (text ":got:" <> pprAsmLabel platform lbl) $$-    op_ldr o1 (text ":got_lo12:" <> pprAsmLabel platform lbl) $$-    op_add o1 (char '#' <> int off) -- TODO: check that off is in 12bits.+    let (adrp', ldr') = op_adrp_reloc_dynamic $ pprAsmLabel platform lbl in+    op_adrp o1 (adrp') $$+    op_ldr o1 (ldr') $$+    op_add o1 (check_off off)    LDR _f o1 (OpImm (ImmIndex lbl off)) | isForeignLabel lbl ->-    op_adrp o1 (text ":got:" <> pprAsmLabel platform lbl) $$-    op_ldr o1 (text ":got_lo12:" <> pprAsmLabel platform lbl) $$-    op_add o1 (char '#' <> int off) -- TODO: check that off is in 12bits.+    case platformOS platform of+      OSMinGW32 ->+        let (adrp', add') = op_adrp_reloc_local $ pprAsmLabel platform lbl in+        op_adrp o1 (adrp') $$+        op_add o1 add' $$+        op_add o1 (check_off off)+      _ ->+        let (adrp', ldr') = op_adrp_reloc_dynamic $ pprAsmLabel platform lbl in+        op_adrp o1 (adrp') $$+        op_ldr o1 (ldr') $$+        op_add o1 (check_off off)    LDR _f o1 (OpImm (ImmIndex lbl off)) ->-    op_adrp o1 (pprAsmLabel platform lbl) $$-    op_add o1 (text ":lo12:" <> pprAsmLabel platform lbl) $$-    op_add o1 (char '#' <> int off) -- TODO: check that off is in 12bits.+    let (adrp', add') = op_adrp_reloc_local $ pprAsmLabel platform lbl in+    op_adrp o1 (adrp') $$+    op_add o1 (add') $$+    op_add o1 (check_off off)    LDR _f o1 (OpImm (ImmCLbl lbl')) | Just (_info, lbl) <- dynamicLinkerLabelInfo lbl' ->-    op_adrp o1 (text ":got:" <> pprAsmLabel platform lbl) $$-    op_ldr o1 (text ":got_lo12:" <> pprAsmLabel platform lbl)+    let (adrp', ldr') = op_adrp_reloc_dynamic $ pprAsmLabel platform lbl in+    op_adrp o1 (adrp') $$+    op_ldr o1 (ldr')    LDR _f o1 (OpImm (ImmCLbl lbl)) | isForeignLabel lbl ->-    op_adrp o1 (text ":got:" <> pprAsmLabel platform lbl) $$-    op_ldr o1 (text ":got_lo12:" <> pprAsmLabel platform lbl)+    case platformOS platform of+      OSMinGW32 ->+        let (adrp', add') = op_adrp_reloc_local $ pprAsmLabel platform lbl in+        op_adrp o1 (adrp') $$+        op_add o1 add'+      _ ->+        let (adrp', ldr') = op_adrp_reloc_dynamic $ pprAsmLabel platform lbl in+        op_adrp o1 (adrp') $$+        op_ldr o1 (ldr')    LDR _f o1 (OpImm (ImmCLbl lbl)) ->-    op_adrp o1 (pprAsmLabel platform lbl) $$-    op_add o1 (text ":lo12:" <> pprAsmLabel platform lbl)--#endif+    let (adrp', ldr') = op_adrp_reloc_local $ pprAsmLabel platform lbl in+    op_adrp o1 adrp' $$+    op_add o1 ldr'    LDR _f o1@(OpReg W8 (RegReal (RealRegSingle i))) o2 | i < 32 ->     op2 (text "\tldrb") o1 o2@@ -567,6 +541,21 @@        op_ldr o1 rest      = line $ text "\tldr" <+> pprOp platform o1 <> comma <+> text "[" <> pprOp platform o1 <> comma <+> rest <> text "]"        op_adrp o1 rest     = line $ text "\tadrp" <+> pprOp platform o1 <> comma <+> rest        op_add o1 rest      = line $ text "\tadd" <+> pprOp platform o1 <> comma <+> pprOp platform o1 <> comma <+> rest++       op_adrp_reloc_dynamic asm_lbl = case platformOS platform of+          OSDarwin -> (asm_lbl <> text "@gotpage", asm_lbl <> text "@gotpageoff")+          OSLinux -> (text ":got:" <> asm_lbl, text ":got_lo12:" <> asm_lbl)+          OSMinGW32 -> (text "__imp_" <> asm_lbl, text ":lo12:__imp_" <> asm_lbl)+          os' -> pgmError $ "GHC.CmmToAsm.AArch64.Ppr.op_adrp_reloc_dynamic : " ++ show os' ++ " is unsuppported by relocations"++       op_adrp_reloc_local asm_lbl = case platformOS platform of+          OSDarwin -> (asm_lbl <> text "@page", asm_lbl <> text "@pageoff")+          OSLinux -> (asm_lbl, text ":lo12:" <> asm_lbl)+          OSMinGW32 -> (asm_lbl, text ":lo12:" <> asm_lbl)+          os' -> pgmError $ "GHC.CmmToAsm.AArch64.Ppr.op_adrp_reloc_local : " ++ show os' ++ " is unsuppported by relocations"++       check_off off = if off >= 0 && off <= 4095 then char '#' <> int off else+         pgmError $ "GHC.CmmToAsm.AArch64.Ppr.check_off : " ++ show off ++ " is out of 12 bit"  pprBcond :: IsLine doc => Cond -> doc pprBcond c = text "b." <> pprCond c
GHC/CmmToAsm/BlockLayout.hs view
@@ -508,8 +508,8 @@               union cFrom new_point             merge edges chains           where-            cFrom = expectJust "mergeChains:chainMap:from" $ mapLookup from chains-            cTo = expectJust "mergeChains:chainMap:to"   $ mapLookup to   chains+            cFrom = expectJust $ mapLookup from chains+            cTo = expectJust $ mapLookup to   chains   -- See Note [Chain based CFG serialization] for the general idea.@@ -757,7 +757,7 @@             --pprTraceIt "placedBlocks" $             -- ++ [] is still kinda expensive             if null unplaced then blockList else blockList ++ unplaced-        getBlock bid = expectJust "Block placement" $ mapLookup bid blockMap+        getBlock bid = expectJust $ mapLookup bid blockMap     in         --Assert we placed all blocks given as input         assert (all (\bid -> mapMember bid blockMap) placedBlocks) $
GHC/CmmToAsm/CFG.hs view
@@ -311,8 +311,8 @@         cuts_vars <- traverse (\p -> (p,) <$> fresh (Just p)) (concatMap (\(a, b) -> [a] ++ maybe [] (:[]) b) cuts_list)         let cuts_map = mapFromList cuts_vars :: LabelMap (Point s (Maybe BlockId))         -- Then unify according to the rewrites in the cuts map-        mapM_ (\(from, to) -> expectJust "shortcutWeightMap" (mapLookup from cuts_map)-                              `union` expectJust "shortcutWeightMap" (maybe (Just null) (flip mapLookup cuts_map) to) ) cuts_list+        mapM_ (\(from, to) -> expectJust (mapLookup from cuts_map)+                              `union` expectJust (maybe (Just null) (flip mapLookup cuts_map) to) ) cuts_list         -- Then recover the unique representative, which is the result of following         -- the chain to the end.         mapM find cuts_map@@ -416,13 +416,10 @@     = Nothing  getEdgeWeight :: CFG -> BlockId -> BlockId -> EdgeWeight-getEdgeWeight cfg from to =-    edgeWeight $ expectJust "Edgeweight for nonexisting block" $-                 getEdgeInfo from to cfg+getEdgeWeight cfg from to = edgeWeight $ expectJust $ getEdgeInfo from to cfg  getTransitionSource :: BlockId -> BlockId -> CFG -> TransitionSource-getTransitionSource from to cfg = transitionSource $ expectJust "Source info for nonexisting block" $-                        getEdgeInfo from to cfg+getTransitionSource from to cfg = transitionSource $ expectJust $ getEdgeInfo from to cfg  reverseEdges :: CFG -> CFG reverseEdges cfg = mapFoldlWithKey (\cfg from toMap -> go (addNode cfg from) from toMap) mapEmpty cfg@@ -600,7 +597,7 @@  -} -- | Generate weights for a Cmm proc based on some simple heuristics.-getCfgProc :: Platform -> Weights -> RawCmmDecl -> CFG+getCfgProc :: Platform -> Weights -> GenCmmDecl d h CmmGraph -> CFG getCfgProc _        _       (CmmData {}) = mapEmpty getCfgProc platform weights (CmmProc _info _lab _live graph) = getCfg platform weights graph @@ -1004,7 +1001,7 @@     blockMapping = listArray (0,mapSize vertexMapping - 1) revOrder :: Array Int BlockId     -- Map from blockId to indices starting at zero     toVertex :: BlockId -> Int-    toVertex   blockId  = expectJust "mkGlobalWeights" $ mapLookup blockId vertexMapping+    toVertex   blockId  = expectJust $ mapLookup blockId vertexMapping     -- Map from indices starting at zero to blockIds     fromVertex :: Int -> BlockId     fromVertex vertex   = blockMapping ! vertex
GHC/CmmToAsm/Dwarf/Constants.hs view
@@ -241,6 +241,7 @@   ArchPPC_64 _ -> fromIntegral $ toRegNo r   ArchAArch64  -> fromIntegral $ toRegNo r   ArchRISCV64  -> fromIntegral $ toRegNo r+  ArchLoongArch64  -> fromIntegral $ toRegNo r   _other -> error "dwarfRegNo: Unsupported platform or unknown register!"  -- | Virtual register number to use for return address.@@ -255,4 +256,5 @@     ArchPPC_64 ELF_V2 -> 65 -- lr (link register)     ArchAArch64 -> 30     ArchRISCV64 -> 1 -- ra (return address)+    ArchLoongArch64 -> 1 -- ra (return address)     _other     -> error "dwarfReturnRegNo: Unsupported platform!"
GHC/CmmToAsm/Dwarf/Types.hs view
@@ -150,14 +150,14 @@ pprDwarfInfo :: IsDoc doc => Platform -> Bool -> DwarfInfo -> doc pprDwarfInfo platform haveSrc d   = case d of-      DwarfCompileUnit {}  -> hasChildren-      DwarfSubprogram {}   -> hasChildren-      DwarfBlock {}        -> hasChildren-      DwarfSrcNote {}      -> noChildren+      DwarfCompileUnit {dwChildren = kids} -> hasChildren kids+      DwarfSubprogram  {dwChildren = kids} -> hasChildren kids+      DwarfBlock       {dwChildren = kids} -> hasChildren kids+      DwarfSrcNote {}                      -> noChildren   where-    hasChildren =+    hasChildren kids =         pprDwarfInfoOpen platform haveSrc d $$-        vcat (map (pprDwarfInfo platform haveSrc) (dwChildren d)) $$+        vcat (map (pprDwarfInfo platform haveSrc) kids) $$         pprDwarfInfoClose     noChildren = pprDwarfInfoOpen platform haveSrc d {-# SPECIALIZE pprDwarfInfo :: Platform -> Bool -> DwarfInfo -> SDoc #-}
+ GHC/CmmToAsm/LA64.hs view
@@ -0,0 +1,60 @@+{-# OPTIONS_GHC -fno-warn-orphans #-}++-- | Native code generator for LoongArch64 architectures+module GHC.CmmToAsm.LA64 ( ncgLA64 ) where++import GHC.Prelude++import GHC.CmmToAsm.Config+import GHC.CmmToAsm.Instr+import GHC.CmmToAsm.Monad+import GHC.CmmToAsm.Types+import GHC.Utils.Outputable (ftext)++import qualified GHC.CmmToAsm.LA64.CodeGen  as LA64+import qualified GHC.CmmToAsm.LA64.Instr    as LA64+import qualified GHC.CmmToAsm.LA64.Ppr      as LA64+import qualified GHC.CmmToAsm.LA64.RegInfo  as LA64+import qualified GHC.CmmToAsm.LA64.Regs     as LA64++ncgLA64 :: NCGConfig -> NcgImpl RawCmmStatics LA64.Instr LA64.JumpDest+ncgLA64 config =+  NcgImpl+    { ncgConfig                 = config,+      cmmTopCodeGen             = LA64.cmmTopCodeGen,+      generateJumpTableForInstr = LA64.generateJumpTableForInstr config,+      getJumpDestBlockId        = LA64.getJumpDestBlockId,+      canShortcut               = LA64.canShortcut,+      shortcutStatics           = LA64.shortcutStatics,+      shortcutJump              = LA64.shortcutJump,+      pprNatCmmDeclS            = LA64.pprNatCmmDecl config,+      pprNatCmmDeclH            = LA64.pprNatCmmDecl config,+      maxSpillSlots             = LA64.maxSpillSlots config,+      allocatableRegs           = LA64.allocatableRegs platform,+      ncgAllocMoreStack         = LA64.allocMoreStack platform,+      ncgMakeFarBranches        = LA64.makeFarBranches,+      extractUnwindPoints       = const [],+      invertCondBranches        = \_ _ -> id+    }+  where+    platform = ncgPlatform config++-- | `Instruction` instance for LA64+instance Instruction LA64.Instr where+  regUsageOfInstr       = LA64.regUsageOfInstr+  patchRegsOfInstr _    = LA64.patchRegsOfInstr+  isJumpishInstr        = LA64.isJumpishInstr+  canFallthroughTo      = LA64.canFallthroughTo+  jumpDestsOfInstr      = LA64.jumpDestsOfInstr+  patchJumpInstr        = LA64.patchJumpInstr+  mkSpillInstr          = LA64.mkSpillInstr+  mkLoadInstr           = LA64.mkLoadInstr+  takeDeltaInstr        = LA64.takeDeltaInstr+  isMetaInstr           = LA64.isMetaInstr+  mkRegRegMoveInstr _ _ = LA64.mkRegRegMoveInstr+  takeRegRegMoveInstr _ = LA64.takeRegRegMoveInstr+  mkJumpInstr           = LA64.mkJumpInstr+  mkStackAllocInstr     = LA64.mkStackAllocInstr+  mkStackDeallocInstr   = LA64.mkStackDeallocInstr+  mkComment             = pure . LA64.COMMENT . ftext+  pprInstr              = LA64.pprInstr
+ GHC/CmmToAsm/LA64/CodeGen.hs view
@@ -0,0 +1,2236 @@+{-# language GADTs #-}+{-# language LambdaCase #-}+{-# LANGUAGE BangPatterns #-}+{-# LANGUAGE BinaryLiterals #-}+{-# LANGUAGE OverloadedStrings #-}+module GHC.CmmToAsm.LA64.CodeGen (+      cmmTopCodeGen+    , generateJumpTableForInstr+    , makeFarBranches+)++where++import Data.Maybe+import Data.Word+import GHC.Cmm+import GHC.Cmm.BlockId+import GHC.Cmm.CLabel+import GHC.Cmm.Dataflow.Block+import GHC.Cmm.Dataflow.Graph+import GHC.Cmm.DebugBlock+import GHC.Cmm.Switch+import GHC.Cmm.Utils+import GHC.CmmToAsm.CPrim+import GHC.CmmToAsm.Config+import GHC.CmmToAsm.Format+import GHC.CmmToAsm.Monad+  ( NatM,+    getConfig,+    getDebugBlock,+    getFileId,+    getNewLabelNat,+    getNewRegNat,+    getPicBaseMaybeNat,+    getPlatform+  )+import GHC.CmmToAsm.PIC+import GHC.CmmToAsm.LA64.Cond+import GHC.CmmToAsm.LA64.Instr+import GHC.CmmToAsm.LA64.Regs+import GHC.CmmToAsm.Types+import GHC.Data.FastString+import GHC.Data.OrdList+import GHC.Float+import GHC.Platform+import GHC.Platform.Reg+import GHC.Platform.Regs+import GHC.Prelude hiding (EQ)+import GHC.Types.Basic+import GHC.Types.ForeignCall+import GHC.Types.SrcLoc (srcSpanFile, srcSpanStartCol, srcSpanStartLine)+import GHC.Types.Tickish (GenTickish (..))+import GHC.Utils.Constants (debugIsOn)+import GHC.Utils.Misc+import GHC.Utils.Outputable+import GHC.Utils.Panic+import GHC.Utils.Monad+import Control.Monad+import GHC.Cmm.Dataflow.Label+import GHC.Types.Unique.DSM++-- [General layout of an NCG]+cmmTopCodeGen ::+  RawCmmDecl ->+  NatM [NatCmmDecl RawCmmStatics Instr]+-- Thus we'll have to deal with either CmmProc ...+cmmTopCodeGen _cmm@(CmmProc info lab live graph) = do+  picBaseMb <- getPicBaseMaybeNat+  when (isJust picBaseMb) $ panic "LA64.cmmTopCodeGen: Unexpected PIC base register"++  let blocks = toBlockListEntryFirst graph+  (nat_blocks, statics) <- mapAndUnzipM basicBlockCodeGen blocks++  let proc = CmmProc info lab live (ListGraph $ concat nat_blocks)+      tops = proc : concat statics++  pure tops++-- ... or CmmData.+cmmTopCodeGen (CmmData sec dat) = pure [CmmData sec dat] -- no translation, we just use CmmStatic++basicBlockCodeGen ::+  Block CmmNode C C ->+  NatM+    ( [NatBasicBlock Instr],+      [NatCmmDecl RawCmmStatics Instr]+    )+basicBlockCodeGen block = do+  config <- getConfig+  let (_, nodes, tail) = blockSplit block+      id = entryLabel block+      stmts = blockToList nodes++      header_comment_instr+        | debugIsOn =+            unitOL+              $ MULTILINE_COMMENT+                ( text "-- --------------------------- basicBlockCodeGen --------------------------- --\n"+                    $+$ withPprStyle defaultDumpStyle (pdoc (ncgPlatform config) block)+                )+        | otherwise = nilOL++  -- Generate location directive `.loc` (DWARF debug location info)+  loc_instrs <- genLocInstrs++  -- Generate other instructions+  mid_instrs <- stmtsToInstrs stmts+  (!tail_instrs) <- stmtToInstrs tail++  let instrs = header_comment_instr `appOL` loc_instrs `appOL` mid_instrs `appOL` tail_instrs++      -- TODO: Then x86 backend runs @verifyBasicBlock@ here. How important it is to+      -- have a valid CFG is an open question: This and the AArch64 and PPC NCGs+      -- work fine without it.++      -- Code generation may introduce new basic block boundaries, which are+      -- indicated by the NEWBLOCK instruction. We must split up the instruction+      -- stream into basic blocks again. Also, we extract LDATAs here too.+      (top, other_blocks, statics) = foldrOL mkBlocks ([], [], []) instrs++  return (BasicBlock id top : other_blocks, statics)+  where+    genLocInstrs :: NatM (OrdList Instr)+    genLocInstrs = do+      dbg <- getDebugBlock (entryLabel block)+      case dblSourceTick =<< dbg of+        Just (SourceNote span name) ->+          do+            fileId <- getFileId (srcSpanFile span)+            let line = srcSpanStartLine span; col = srcSpanStartCol span+            pure $ unitOL $ LOCATION fileId line col name+        _ -> pure nilOL++mkBlocks ::+  Instr ->+  ([Instr], [GenBasicBlock Instr], [GenCmmDecl RawCmmStatics h g]) ->+  ([Instr], [GenBasicBlock Instr], [GenCmmDecl RawCmmStatics h g])+mkBlocks (NEWBLOCK id) (instrs, blocks, statics) =+  ([], BasicBlock id instrs : blocks, statics)+mkBlocks (LDATA sec dat) (instrs, blocks, statics) =+  (instrs, blocks, CmmData sec dat : statics)+mkBlocks instr (instrs, blocks, statics) =+  (instr : instrs, blocks, statics)++-- -----------------------------------------------------------------------------+-- | Utilities++-- | Annotate an `Instr` with a `SDoc` comment+ann :: SDoc -> Instr -> Instr+ann doc instr {- debugIsOn -} = ANN doc instr+{-# INLINE ann #-}++-- Using pprExpr will hide the AST, @ANN@ will end up in the assembly with+-- -dppr-debug.  The idea is that we can trivially see how a cmm expression+-- ended up producing the assembly we see.  By having the verbatim AST printed+-- we can simply check the patterns that were matched to arrive at the assembly+-- we generated.+--+-- pprExpr will hide a lot of noise of the underlying data structure and print+-- the expression into something that can be easily read by a human. However+-- going back to the exact CmmExpr representation can be laborious and adds+-- indirections to find the matches that lead to the assembly.+--+-- An improvement oculd be to have+--+--    (pprExpr genericPlatform e) <> parens (text. show e)+--+-- to have the best of both worlds.+--+-- Note: debugIsOn is too restrictive, it only works for debug compilers.+-- However, we do not only want to inspect this for debug compilers. Ideally+-- we'd have a check for -dppr-debug here already, such that we don't even+-- generate the ANN expressions. However, as they are lazy, they shouldn't be+-- forced until we actually force them, and without -dppr-debug they should+-- never end up being forced.+annExpr :: CmmExpr -> Instr -> Instr+annExpr e {- debugIsOn -} = ANN (text . show $ e)+-- annExpr e instr {- debugIsOn -} = ANN (pprExpr genericPlatform e) instr+-- annExpr _ instr = instr+{-# INLINE annExpr #-}++-- -----------------------------------------------------------------------------+-- Generating a table-branch+-- The index into the jump table is calulated by evaluating @expr@. The+-- corresponding table entry contains the address to jump to.+genSwitch :: NCGConfig -> CmmExpr -> SwitchTargets -> NatM InstrBlock+genSwitch config expr targets = do+  (reg, fmt1, e_code) <- getSomeReg indexExpr+  targetReg <- getNewRegNat II64+  lbl <- getNewLabelNat+  dynRef <- cmmMakeDynamicReference config DataReference lbl+  (tableReg, fmt2, t_code) <- getSomeReg $ dynRef+  let code =+        toOL [ COMMENT (text "indexExpr" <+> (text . show) indexExpr)+             , COMMENT (text "dynRef" <+> (text . show) dynRef)+             ]+          `appOL` e_code+          `appOL` t_code+          `appOL` toOL+            [+              COMMENT (ftext "Jump table for switch"),+              -- index to offset into the table (relative to tableReg)+              annExpr expr (SLL (OpReg W64 reg) (OpReg (formatToWidth fmt1) reg) (OpImm (ImmInt 3))),+              -- calculate table entry address+              ADD (OpReg W64 targetReg) (OpReg W64 reg) (OpReg (formatToWidth fmt2) tableReg),+              -- load table entry (relative offset from tableReg (first entry) to target label)+              LDU II64 (OpReg W64 targetReg) (OpAddr (AddrRegImm targetReg (ImmInt 0))),+              -- calculate absolute address of the target label+              ADD (OpReg W64 targetReg) (OpReg W64 targetReg) (OpReg W64 tableReg),+              -- prepare jump to target label+              J_TBL bids (Just lbl) targetReg+            ]+  return code+  where+    platform = ncgPlatform config+    expr_w = cmmExprWidth platform expr+    indexExpr0 = cmmOffset platform expr offset+    -- Widen to a native-width register(addressing modes)+    indexExpr = CmmMachOp+        (MO_UU_Conv expr_w (platformWordWidth platform))+        [indexExpr0]+    (offset, bids) = switchTargetsToTable targets+++-- Generate jump table data (if required)+--+-- Relies on PIC relocations. The idea is to emit one table entry per case. The+-- entry is the label of the block to jump to. This will be relocated to be the+-- address of the jump target.+generateJumpTableForInstr ::+  NCGConfig ->+  Instr ->+  Maybe (NatCmmDecl RawCmmStatics Instr)+generateJumpTableForInstr config (J_TBL ids (Just lbl) _) =+  let jumpTable =+        map jumpTableEntryRel ids+        where+          jumpTableEntryRel Nothing =+            CmmStaticLit (CmmInt 0 (ncgWordWidth config))+          jumpTableEntryRel (Just blockid) =+            CmmStaticLit+              ( CmmLabelDiffOff+                  blockLabel+                  lbl+                  0+                  (ncgWordWidth config)+              )+            where+              blockLabel = blockLbl blockid+   in Just (CmmData (Section ReadOnlyData lbl) (CmmStaticsRaw lbl jumpTable))+generateJumpTableForInstr _ _ = Nothing++-- -----------------------------------------------------------------------------+-- Top-level of the instruction selector+stmtsToInstrs ::+  -- | Cmm Statements+  [CmmNode O O] ->+  -- | Resulting instruction+  NatM InstrBlock+stmtsToInstrs stmts = concatOL <$> mapM stmtToInstrs stmts++stmtToInstrs ::+  CmmNode e x ->+  -- | Resulting instructions+  NatM InstrBlock++stmtToInstrs stmt = do+  config <- getConfig+  platform <- getPlatform+  case stmt of+    CmmUnsafeForeignCall target result_regs args+      -> genCCall target result_regs args++    CmmComment s   -> return (unitOL (COMMENT (ftext s)))+    CmmTick {}     -> return nilOL++    CmmAssign reg src+      | isFloatType ty         -> assignReg_FltCode format reg src+      | otherwise              -> assignReg_IntCode format reg src+        where ty = cmmRegType reg+              format = cmmTypeFormat ty++    CmmStore addr src _alignment+      | isFloatType ty         -> assignMem_FltCode format addr src+      | otherwise              -> assignMem_IntCode format addr src+        where ty = cmmExprType platform src+              format = cmmTypeFormat ty++    CmmBranch id          -> genBranch id++    --We try to arrange blocks such that the likely branch is the fallthrough+    --in GHC.Cmm.ContFlowOpt. So we can assume the condition is likely false here.+    CmmCondBranch arg true false _prediction ->+        genCondBranch true false arg++    CmmSwitch arg ids -> genSwitch config arg ids++    CmmCall { cml_target = arg } -> genJump arg++    CmmUnwind _regs -> pure nilOL++    _ ->  pprPanic "stmtToInstrs: statement should have been cps'd away" (pdoc platform stmt)++-- | 'InstrBlock's are the insn sequences generated by the insn selectors.+--  They are really trees of insns to facilitate fast appending, where a+--  left-to-right traversal yields the insns in the correct order.+type InstrBlock =+  OrdList Instr++-- | Register's passed up the tree.+--  If the stix code forces the register to live in a pre-decided machine+--  register, it comes out as @Fixed@; otherwise, it comes out as @Any@, and the+--  parent can decide which register to put it in.+data Register+  = Fixed Format Reg InstrBlock+  | Any Format (Reg -> InstrBlock)++-- | Sometimes we need to change the Format of a register. Primarily during+--  conversion.+swizzleRegisterRep :: Format -> Register -> Register+swizzleRegisterRep format' (Fixed _ reg code) = Fixed format' reg code+swizzleRegisterRep format' (Any _ codefn) = Any format' codefn++-- | Grab a `Reg` for a `CmmReg`+getRegisterReg :: Platform -> CmmReg -> Reg++getRegisterReg _ (CmmLocal (LocalReg u pk))+  = RegVirtual $ mkVirtualReg u (cmmTypeFormat pk)++getRegisterReg platform (CmmGlobal mid)+  = case globalRegMaybe platform (globalRegUse_reg mid) of+        Just reg -> RegReal reg+        Nothing  -> pprPanic "getRegisterReg-memory" (ppr $ CmmGlobal mid)++-- General things for putting together code sequences++-- | Compute an expression into any register+getSomeReg :: CmmExpr -> NatM (Reg, Format, InstrBlock)+getSomeReg expr = do+  r <- getRegister expr+  case r of+    Any rep code -> do+        tmp <- getNewRegNat rep+        return (tmp, rep, code tmp)+    Fixed rep reg code ->+        return (reg, rep, code)++-- | Compute an expression into any floating-point register++-- | Compute an expression into floating point register+--  If the initial expression is not a floating-point expression, finally move+--  the result into a floating-point register.+getFloatReg :: HasCallStack => CmmExpr -> NatM (Reg, Format, InstrBlock)+getFloatReg expr = do+  r <- getRegister expr+  case r of+    Any rep code | isFloatFormat rep -> do+      tmp <- getNewRegNat rep+      return (tmp, rep, code tmp)+    Any II32 code -> do+      tmp <- getNewRegNat FF32+      return (tmp, FF32, code tmp)+    Any II64 code -> do+      tmp <- getNewRegNat FF64+      return (tmp, FF64, code tmp)+    Any _w _code -> do+      config <- getConfig+      pprPanic "can't do getFloatReg on" (pdoc (ncgPlatform config) expr)+    -- can't do much for fixed.+    Fixed rep reg code ->+      return (reg, rep, code)++-- | Map `CmmLit` to `OpImm`+litToImm' :: CmmLit -> Operand+litToImm' = OpImm . litToImm++-- Handling PIC on LA64+-- Commonly, `PIC` means of `position independent code`, that to say, the execution+-- of code does not be influenced by Load_address. Through PC-Relative addressing+-- or GOT addressing, both can be used to implement `PIC`.+--+-- For LoongArch's common compiler(GCC, Clang), they generate PIC code by default+-- without condition. The command option `-fPIC` dicates to generate code for+-- shared-library. If not just specified for shared-library, another option `-fPIE`+-- was be created.+--+-- Like RV64, LA64 does not have a special PIC register, the general approach is to+-- simply do PC-relative addressing or go through the GOT. There is assembly support+-- for both.+--+-- LA64 assembly has many `la*` (load address) pseudo-instructions, that allows+-- loading a symbols's address into a register. These instructions is desugared into+-- different addressing modes. See following:+--+-- la        rd, label + addend  -> Load global symbol+-- la.global rd, label + addend  -> Same as `la`+-- la.local  rd, label + addend  -> Load local symbol+-- la.pcrel  rd, label + addend+-- la.got    rd, label+-- la.abs    rd, label + addend+--+-- `la` is alias of `la.global`. Commonly recommended use `la.local` and `la.global`.+--+-- PC-relative addressing:+--   pcalau12i $a0, %pc_hi20(a)+--   addi.d    $a0, $a0, %pc_lo12(a)+--+-- GOT addressing:+--   pcalau12i $a0, %got_pc_hi20(global_a)+--   ld.d      $a0, $a0, %got_pc_lo12(global_a)+--+-- PIC can be enabled/disabled through:+--  .option pic+--+-- CmmGlobal @PicBaseReg@'s are generated in @GHC.CmmToAsm.PIC@ in the+-- @cmmMakePicReference@.  This is in turn called from @cmmMakeDynamicReference@+-- also in @Cmm.CmmToAsm.PIC@ from where it is also exported.  There are two+-- callsites for this. One is in this module to produce the @target@ in @genCCall@+-- the other is in @GHC.CmmToAsm@ in @cmmExprNative@.+--+-- Conceptually we do not want any special PicBaseReg to be used on LA64. If+-- we want to distinguish between symbol loading, we need to address this through+-- the way we load it, not through a register.++-- Compute a `CmmExpr` into a `Register`+getRegister :: CmmExpr -> NatM Register+getRegister e = do+  config <- getConfig+  getRegister' config (ncgPlatform config) e++-- Signed arithmetic on LoongArch64+--+-- Handling signed arithmetic on sub-word-size values on LA64 is a bit tricky+-- as Cmm's type system does not capture signedness. While 32- and 64-bit+-- values are fairly easy to handle due to LA64's 32- and 64-bit instructions+-- with responding register, 8- and 16-bit values require quite some care.+--+-- For LoongArch64, EXT.W.[B/H] will sign-extend 8- and 16-bit to 64-bit.+-- However, it is best to use EXT instruction only if the input and+-- output data widths are fully determined.+--+-- We handle 16-and 8-bit values by using the following two steps:+--  1. Sign- or Zero-extending operands.+--  2. Truncate results as necessary.+--+-- For simplicity we maintain the invariant that a register containing a+-- sub-word-size value always contains the zero-extended form of that value+-- in between operations.++getRegister' :: NCGConfig -> Platform -> CmmExpr -> NatM Register++-- OPTIMIZATION WARNING: CmmExpr rewrites++-- Generic case.+getRegister' config plat expr =+  case expr of+    CmmReg (CmmGlobal (GlobalRegUse PicBaseReg _)) ->+      pprPanic "getRegisterReg-memory" (ppr PicBaseReg)++    CmmLit lit ->+      case lit of+        CmmInt 0 w -> pure $ Fixed (intFormat w) zeroReg nilOL+        CmmInt i w -> do+          -- narrowU is important: Negative immediates may be+          -- sign-extended on load!+          let imm = OpImm . ImmInteger $ narrowU w i+          return (Any (intFormat w) (\dst -> unitOL $ annExpr expr (MOV (OpReg w dst) imm)))++        CmmFloat 0 w -> do+          let op = litToImm' lit+          pure (Any (floatFormat w) (\dst -> unitOL $ annExpr expr (MOV (OpReg w dst) op)))++        CmmFloat _f W8  -> pprPanic "getRegister' (CmmLit:CmmFloat), no support for bytes" (pdoc plat expr)+        CmmFloat _f W16 -> pprPanic "getRegister' (CmmLit:CmmFloat), no support for halfs" (pdoc plat expr)++        CmmFloat f W32 -> do+          let word = castFloatToWord32 (fromRational f) :: Word32+          tmp <- getNewRegNat (intFormat W32)+          return (Any (floatFormat W32) (\dst -> toOL [ annExpr expr+                                                      $ MOV (OpReg W32 tmp) (OpImm (ImmInteger (fromIntegral word)))+                                                      , MOV (OpReg W32 dst) (OpReg W32 tmp)+                                                      ]))+        CmmFloat f W64 -> do+          let word = castDoubleToWord64 (fromRational f) :: Word64+          tmp <- getNewRegNat (intFormat W64)+          return (Any (floatFormat W64) (\dst -> toOL [ annExpr expr+                                                      $ MOV (OpReg W64 tmp) (OpImm (ImmInteger (fromIntegral word)))+                                                      , MOV (OpReg W64 dst) (OpReg W64 tmp)+                                                      ]))++        CmmFloat _f _w -> pprPanic "getRegister' (CmmLit:CmmFloat), unsupported float lit" (pdoc plat expr)+        CmmVec _lits -> pprPanic "getRegister' (CmmLit:CmmVec): " (pdoc plat expr)++        CmmLabel lbl -> do+          let op = OpImm (ImmCLbl lbl)+              rep = cmmLitType plat lit+              format = cmmTypeFormat rep+          return (Any format (\dst -> unitOL $ annExpr expr (LD format (OpReg (formatToWidth format) dst) op)))++        CmmLabelOff lbl off | isNbitEncodeable 12 (fromIntegral off) -> do+          let op = OpImm (ImmIndex lbl off)+              rep = cmmLitType plat lit+              format = cmmTypeFormat rep+          return (Any format (\dst -> unitOL $ LD format (OpReg (formatToWidth format) dst) op))++        CmmLabelOff lbl off -> do+          let op = litToImm' (CmmLabel lbl)+              rep = cmmLitType plat lit+              format = cmmTypeFormat rep+              width = typeWidth rep+          (off_r, _off_format, off_code) <- getSomeReg $ CmmLit (CmmInt (fromIntegral off) width)+          return (Any format (\dst -> off_code `snocOL`+                                                LD format (OpReg (formatToWidth format) dst) op `snocOL`+                                                ADD (OpReg W64 dst) (OpReg width dst) (OpReg width off_r)+                             ))++        CmmLabelDiffOff {} -> pprPanic "getRegister' (CmmLit:CmmLabelOff): " (pdoc plat expr)+        CmmBlock _ -> pprPanic "getRegister' (CmmLit:CmmLabelOff): " (pdoc plat expr)+        CmmHighStackMark -> pprPanic "getRegister' (CmmLit:CmmLabelOff): " (pdoc plat expr)++    CmmLoad mem rep _ -> do+      let format = cmmTypeFormat rep+          width = typeWidth rep+      Amode addr addr_code <- getAmode plat width mem+      case width of+        w | w `elem` [W8, W16, W32, W64] ->+            -- Load without sign-extension.+            pure (Any format (\dst ->+              addr_code `snocOL`+              LDU format (OpReg width dst) (OpAddr addr))+                              )+        _ -> pprPanic ("Unknown width to load: " ++ show width) (pdoc plat expr)++    CmmStackSlot _ _  -> pprPanic "getRegister' (CmmStackSlot): " (pdoc plat expr)++    CmmReg reg -> return (Fixed (cmmTypeFormat (cmmRegType reg))+                                (getRegisterReg plat reg)+                                nilOL+                         )++    CmmRegOff reg off | isNbitEncodeable 12 (fromIntegral off) -> do+      getRegister' config plat+        $ CmmMachOp (MO_Add width) [CmmReg reg, CmmLit (CmmInt (fromIntegral off) width)]+      where+        width = typeWidth (cmmRegType reg)+    CmmRegOff reg off -> do+      (off_r, _off_format, off_code) <- getSomeReg $ CmmLit (CmmInt (fromIntegral off) width)+      (reg, _format, code) <- getSomeReg $ CmmReg reg+      return $ Any (intFormat width) ( \dst ->+                                        off_code `appOL`+                                        code `snocOL`+                                        ADD (OpReg W64 dst) (OpReg width reg) (OpReg width off_r)+                                     )+      where+        width = typeWidth (cmmRegType reg)++    -- Handle MO_RelaxedRead as a normal CmmLoad, to allow+    -- non-trivial addressing modes to be used.+    CmmMachOp (MO_RelaxedRead w) [e] ->+      getRegister (CmmLoad e (cmmBits w) NaturallyAligned)++    -- for MachOps, see GHC.Cmm.MachOp+    -- For CmmMachOp, see GHC.Cmm.Expr+    CmmMachOp op [e] -> do+      (reg, format, code) <- getSomeReg e+      case op of+        MO_Not w -> return $ Any (intFormat w) $ \dst ->+          code `appOL`+          -- pseudo instruction `not dst rd` is `nor dst, r0, rd`+          truncateReg (formatToWidth format) W64 reg `snocOL`+          -- At this point an 8- or 16-bit value would be zero-extended+          -- to 64-bits. Truncate back down the final width.+          ann (text "not") (NOR (OpReg W64 dst) (OpReg W64 reg) zero) `appOL`+          truncateReg W64 w dst++        MO_S_Neg w -> negate code w reg+        MO_F_Neg w -> return $ Any (floatFormat w) (\dst -> code `snocOL` FNEG (OpReg w dst) (OpReg w reg))++        -- Floating convertion oprations+        -- Float -> Float+        MO_FF_Conv from to -> return $ Any (floatFormat to) (\dst -> code `snocOL` FCVT (OpReg to dst) (OpReg from reg))++        -- Signed int -> Float+        MO_SF_Round from to -> return $ Any (floatFormat to) (\dst -> code `snocOL` SCVTF (OpReg to dst) (OpReg from reg))++        -- Float -> Signed int+        MO_FS_Truncate from to | from == W32 -> do+            tmp <- getNewRegNat FF32+            return $ Any (intFormat to) (\dst -> code `snocOL` FCVTZS (OpReg to dst) (OpReg from tmp) (OpReg from reg))++        MO_FS_Truncate from to | from == W64-> do+            tmp <- getNewRegNat FF64+            return $ Any (intFormat to) (\dst -> code `snocOL` FCVTZS (OpReg to dst) (OpReg from tmp) (OpReg from reg))++        -- unsigned int -> unsigned int+        MO_UU_Conv from to -> return $ Any (intFormat to) (\dst ->+          code `snocOL` BSTRPICK II64 (OpReg W64 dst) (OpReg W64 reg) (OpImm (ImmInt (widthToInt (min from to) - 1))) (OpImm (ImmInt 0))+                                                          )++        -- Signed int -> Signed int+        MO_SS_Conv from to -> ss_conv from to reg code++        -- int -> int+        MO_XX_Conv _from to -> swizzleRegisterRep (intFormat to) <$> getRegister e++        MO_WF_Bitcast w    -> return $ Any (floatFormat w)  (\dst -> code `snocOL` MOV (OpReg w dst) (OpReg w reg))+        MO_FW_Bitcast w    -> return $ Any (intFormat w)    (\dst -> code `snocOL` MOV (OpReg w dst) (OpReg w reg))++        x -> pprPanic ("getRegister' (monadic CmmMachOp): " ++ show x) (pdoc plat expr)+      where+        -- In the case of 32- or 16- or 8-bit values we need to sign-extend to 64-bits+        negate code w reg+          | w `elem` [W8, W16] = do+            return $ Any (intFormat w) $ \dst ->+                code `snocOL`+                EXT (OpReg W64 reg) (OpReg w reg) `snocOL`+                NEG (OpReg W64 dst) (OpReg W64 reg) `appOL`+                truncateReg W64 w dst+          | otherwise = do+            return $ Any (intFormat w) $ \dst ->+                code `snocOL`+                NEG (OpReg W64 dst) (OpReg w reg)++        ss_conv from to reg code+          | from `elem` [W8, W16] || to `elem` [W8, W16] = do+            return $ Any (intFormat to) $ \dst ->+                code `snocOL`+                EXT (OpReg W64 dst) (OpReg (min from to) reg) `appOL`+                -- At this point an 8- or 16-bit value would be sign-extended+                -- to 64-bits. Truncate back down the final width.+                truncateReg W64 to dst+          | from == W32 && to == W64 = do+            return $ Any (intFormat to) $ \dst ->+                code `snocOL`+                SLL (OpReg to dst) (OpReg from reg) (OpImm (ImmInt 0))+          | from == to = do+            return $ Any (intFormat from) $ \dst ->+                 code `snocOL` MOV (OpReg from dst) (OpReg from reg)+          | otherwise = do+            return $ Any (intFormat to) $ \dst ->+                code `appOL`+                signExtend from W64 reg dst `appOL`+                truncateReg W64 to dst+++-- Dyadic machops:+    --+    -- The general idea is:+    -- compute x<i> <- x+    -- compute x<j> <- y+    -- OP x<r>, x<i>, x<j>+    --+    -- TODO: for now we'll only implement the 64bit versions. And rely on the+    --      fallthrough to alert us if things go wrong!+    -- OPTIMIZATION WARNING: Dyadic CmmMachOp destructuring+    -- 0. TODO This should not exist! Rewrite: Reg +- 0 -> Reg+    CmmMachOp (MO_Add _) [expr'@(CmmReg (CmmGlobal _r)), CmmLit (CmmInt 0 _)] -> getRegister' config plat expr'+    CmmMachOp (MO_Sub _) [expr'@(CmmReg (CmmGlobal _r)), CmmLit (CmmInt 0 _)] -> getRegister' config plat expr'++    CmmMachOp (MO_Add w) [x, CmmLit (CmmInt n _)] | fitsInNbits 12 (fromIntegral n) -> do+      if w `elem` [W8, W16]+        then do+          (reg_x, _format_x, code_x) <- getSomeReg x+          return $ Any (intFormat w) (\dst ->+                                        code_x `snocOL`+                                        annExpr expr (EXT (OpReg W64 reg_x) (OpReg w reg_x)) `snocOL`+                                        ADD (OpReg W64 dst) (OpReg W64 reg_x) (OpImm (ImmInteger n))+                                     )+        else do+          (reg_x, _format_x, code_x) <- getSomeReg x+          return $ Any (intFormat w) (\dst -> code_x `snocOL` annExpr expr (ADD (OpReg W64 dst) (OpReg w reg_x) (OpImm (ImmInteger n))))++    CmmMachOp (MO_Sub w) [x, CmmLit (CmmInt n _)] | fitsInNbits 12 (fromIntegral n) -> do+      if w `elem` [W8, W16]+        then do+          (reg_x, _format_x, code_x) <- getSomeReg x+          return $ Any (intFormat w) (\dst ->+                                        code_x `snocOL`+                                        annExpr expr (EXT (OpReg W64 reg_x) (OpReg w reg_x)) `snocOL`+                                        SUB (OpReg W64 dst) (OpReg W64 reg_x) (OpImm (ImmInteger n))+                                     )+        else do+          (reg_x, _format_x, code_x) <- getSomeReg x+          return $ Any (intFormat w) (\dst -> code_x `snocOL` annExpr expr (SUB (OpReg W64 dst) (OpReg w reg_x) (OpImm (ImmInteger n))))++    CmmMachOp (MO_U_Quot w) [x, y]+      | w `elem` [W8, W16] -> do+        (reg_x, _format_x, code_x) <- getSomeReg x+        (reg_y, _format_y, code_y) <- getSomeReg y+        return $ Any (intFormat w) (\dst ->+                                      code_x `appOL`+                                      code_y `appOL`+                                      truncateReg w W64 reg_x `appOL`+                                      truncateReg w W64 reg_y `snocOL`+                                      annExpr expr (DIVU (OpReg W64 dst) (OpReg W64 reg_x) (OpReg W64 reg_y))+                                   )++    -- 2. Shifts.+    CmmMachOp (MO_Shl w) [x, y] ->+      case y of+        CmmLit (CmmInt n _) | w `elem` [W8, W16], 0 <= n, n < fromIntegral (widthInBits w) -> do+          (reg_x, _format_x, code_x) <- getSomeReg x+          return $ Any (intFormat w) (\dst ->+                                        code_x `snocOL`+                                        annExpr expr (EXT (OpReg W64 reg_x) (OpReg w reg_x)) `snocOL`+                                        SLL (OpReg W64 dst) (OpReg W64 reg_x) (OpImm (ImmInteger n))+                                     )+        CmmLit (CmmInt n _) | 0 <= n, n < fromIntegral (widthInBits w) -> do+          (reg_x, _format_x, code_x) <- getSomeReg x+          return $ Any (intFormat w) (\dst -> code_x `snocOL` annExpr expr (SLL (OpReg W64 dst) (OpReg w reg_x) (OpImm (ImmInteger n))))++        _ | w `elem` [W8, W16] -> do+          (reg_x, _format_x, code_x) <- getSomeReg x+          (reg_y, _format_y, code_y) <- getSomeReg y+          return $ Any (intFormat w) (\dst ->+                                        code_x `appOL`+                                        code_y `snocOL`+                                        annExpr expr (EXT (OpReg W64 reg_x) (OpReg w reg_x)) `snocOL`+                                        EXT (OpReg W64 reg_y) (OpReg w reg_y) `snocOL`+                                        SLL (OpReg W64 dst) (OpReg W64 reg_x) (OpReg W64 reg_y)+                                     )+        _ -> do+          (reg_x, _format_x, code_x) <- getSomeReg x+          (reg_y, _format_y, code_y) <- getSomeReg y+          return $ Any (intFormat w) (\dst ->+                                        code_x `appOL`+                                        code_y `snocOL`+                                        annExpr expr (SLL (OpReg W64 dst) (OpReg w reg_x) (OpReg w reg_y))+                                     )++    -- MO_S_Shr: signed-shift-right+    CmmMachOp (MO_S_Shr w) [x, y] ->+      case y of+        CmmLit (CmmInt n _) | w `elem` [W8, W16], 0 <= n, n < fromIntegral (widthInBits w) -> do+          (reg_x, _format_x, code_x) <- getSomeReg x+          return $ Any (intFormat w)  (\dst ->+                                        code_x `snocOL`+                                        annExpr expr (EXT (OpReg W64 reg_x) (OpReg w reg_x)) `snocOL`+                                        SRA (OpReg W64 dst) (OpReg W64 reg_x) (OpImm (ImmInteger n))+                                      )+        CmmLit (CmmInt n _) | 0 <= n, n < fromIntegral (widthInBits w) -> do+          (reg_x, _format_x, code_x) <- getSomeReg x+          return $ Any (intFormat w) (\dst -> code_x `snocOL` annExpr expr (SRA (OpReg W64 dst) (OpReg w reg_x) (OpImm (ImmInteger n))))++        _ | w `elem` [W8, W16] -> do+          (reg_x, _format_x, code_x) <- getSomeReg x+          (reg_y, _format_y, code_y) <- getSomeReg y+          return $ Any (intFormat w) (\dst ->+                                        code_x `appOL`+                                        code_y `snocOL`+                                        annExpr expr (EXT (OpReg W64 reg_x) (OpReg w reg_x)) `snocOL`+                                        EXT (OpReg W64 reg_y) (OpReg w reg_y) `snocOL`+                                        SRA (OpReg W64 dst) (OpReg W64 reg_x) (OpReg W64 reg_y)+                                     )+        _ -> do+          (reg_x, _format_x, code_x) <- getSomeReg x+          (reg_y, _format_y, code_y) <- getSomeReg y+          return $ Any (intFormat w) (\dst ->+                                        code_x `appOL`+                                        code_y `snocOL`+                                        annExpr expr (SRA (OpReg W64 dst) (OpReg w reg_x) (OpReg w reg_y))+                                     )++    -- MO_U_Shr: unsigned-shift-right+    CmmMachOp (MO_U_Shr w) [x, y] ->+      case y of+        CmmLit (CmmInt n _) | w `elem` [W8, W16], 0 <= n, n < fromIntegral (widthInBits w) -> do+          (reg_x, _format_x, code_x) <- getSomeReg x+          return $ Any (intFormat w) (\dst ->+                                        code_x `appOL`+                                        truncateReg w W64 reg_x `snocOL`+                                        annExpr expr (SRL (OpReg W64 dst) (OpReg W64 reg_x) (OpImm (ImmInteger n)))+                                     )+        CmmLit (CmmInt n _) | 0 <= n, n < fromIntegral (widthInBits w) -> do+          (reg_x, _format_x, code_x) <- getSomeReg x+          return $ Any (intFormat w) (\dst -> code_x `snocOL` annExpr expr (SRL (OpReg W64 dst) (OpReg w reg_x) (OpImm (ImmInteger n))))++        _ | w `elem` [W8, W16] -> do+          (reg_x, _format_x, code_x) <- getSomeReg x+          (reg_y, _format_y, code_y) <- getSomeReg y+          return $ Any (intFormat w) (\dst ->+                                        code_x `appOL`+                                        code_y `appOL`+                                        truncateReg w W64 reg_x `appOL`+                                        truncateReg w W64 reg_y `snocOL`+                                        annExpr expr (SRL (OpReg W64 dst) (OpReg W64 reg_x) (OpReg W64 reg_y))+                                     )+        _ -> do+          (reg_x, _format_x, code_x) <- getSomeReg x+          (reg_y, _format_y, code_y) <- getSomeReg y+          return $ Any (intFormat w) (\dst ->+                                        code_x `appOL`+                                        code_y `snocOL`+                                        annExpr expr (SRL (OpReg W64 dst) (OpReg w reg_x) (OpReg w reg_y))+                                     )++    -- 3. Logic &&, ||+    -- andi Instr's Imm-operand is zero-extended.+    CmmMachOp (MO_And w) [x, y] ->+      case y of+        CmmLit (CmmInt n _) | w `elem` [W8, W16, W32], (n :: Integer) >= 0, (n :: Integer) <= 4095 -> do+          (reg_x, _format_x, code_x) <- getSomeReg x+          return $ Any (intFormat w) (\dst ->+                                        code_x `appOL`+                                        truncateReg w W64 reg_x `snocOL`+                                        annExpr expr (AND (OpReg W64 dst) (OpReg W64 reg_x) (OpImm (ImmInteger n)))+                                     )++        CmmLit (CmmInt n _) | (n :: Integer) >= 0, (n :: Integer) <= 4095 -> do+          (reg_x, _format_x, code_x) <- getSomeReg x+          return $ Any (intFormat w) (\dst -> code_x `snocOL` annExpr expr (AND (OpReg W64 dst) (OpReg w reg_x) (OpImm (ImmInteger n))))++        CmmLit (CmmInt n _) | w `elem` [W8, W16, W32] -> do+          (reg_x, _format_x, code_x) <- getSomeReg x+          tmp <- getNewRegNat II64+          return $ Any (intFormat w) (\dst ->+                                       code_x `appOL`+                                       truncateReg w W64 reg_x `snocOL`+                                       annExpr expr (MOV (OpReg W64 tmp) (OpImm (ImmInteger n))) `snocOL`+                                       AND (OpReg W64 dst) (OpReg W64 reg_x) (OpReg W64 tmp)+                                     )++        CmmLit (CmmInt n _) -> do+          (reg_x, _format_x, code_x) <- getSomeReg x+          tmp <- getNewRegNat II64+          return $ Any (intFormat w) (\dst ->+                                        code_x `snocOL`+                                        annExpr expr (MOV (OpReg W64 tmp) (OpImm (ImmInteger  n))) `snocOL`+                                        AND (OpReg W64 dst) (OpReg W64 reg_x) (OpReg W64 tmp)+                                     )++        _ | w `elem` [W8, W16, W32] -> do+          (reg_x, _format_x, code_x) <- getSomeReg x+          (reg_y, _format_y, code_y) <- getSomeReg y+          return $ Any (intFormat w) (\dst ->+                                        code_x `appOL`+                                        code_y `appOL`+                                        truncateReg w W64 reg_x `appOL`+                                        truncateReg w W64 reg_y `snocOL`+                                        annExpr expr (AND (OpReg W64 dst) (OpReg W64 reg_x) (OpReg W64 reg_y))+                                     )++        _ -> do+          (reg_x, _format_x, code_x) <- getSomeReg x+          (reg_y, _format_y, code_y) <- getSomeReg y+          return $ Any (intFormat w) (\dst ->+                                        code_x `appOL`+                                        code_y `snocOL`+                                        annExpr expr (AND (OpReg W64 dst) (OpReg w reg_x) (OpReg w reg_y))+                                     )++    -- ori Instr's Imm-operand is zero-extended.+    CmmMachOp (MO_Or w) [x, y] ->+      case y of+        CmmLit (CmmInt n _) | w `elem` [W8, W16, W32], (n :: Integer) >= 0, (n :: Integer) <= 4095 -> do+          (reg_x, _format_x, code_x) <- getSomeReg x+          return $ Any (intFormat w) (\dst ->+                                        code_x `appOL`+                                        truncateReg w W64 reg_x `snocOL`+                                        annExpr expr (OR (OpReg W64 dst) (OpReg W64 reg_x) (OpImm (ImmInteger n)))+                                     )++        CmmLit (CmmInt n _) | (n :: Integer) >= 0, (n :: Integer) <= 4095 -> do+          (reg_x, _format_x, code_x) <- getSomeReg x+          return $ Any (intFormat w) (\dst -> code_x `snocOL` annExpr expr (OR (OpReg W64 dst) (OpReg w reg_x) (OpImm (ImmInteger n))))++        CmmLit (CmmInt n _) | w `elem` [W8, W16, W32] -> do+          (reg_x, _format_x, code_x) <- getSomeReg x+          tmp <- getNewRegNat II64+          return $ Any (intFormat w) (\dst ->+                                       code_x `appOL`+                                       truncateReg w W64 reg_x `snocOL`+                                       annExpr expr (MOV (OpReg W64 tmp) (OpImm (ImmInteger n))) `snocOL`+                                       OR (OpReg W64 dst) (OpReg W64 reg_x) (OpReg W64 tmp)+                                     )++        CmmLit (CmmInt n _) -> do+          (reg_x, _format_x, code_x) <- getSomeReg x+          tmp <- getNewRegNat II64+          return $ Any (intFormat w) (\dst ->+                                        code_x `snocOL`+                                        annExpr expr (MOV (OpReg W64 tmp) (OpImm (ImmInteger  n))) `snocOL`+                                        OR (OpReg W64 dst) (OpReg W64 reg_x) (OpReg W64 tmp)+                                     )++        _ | w `elem` [W8, W16, W32] -> do+          (reg_x, _format_x, code_x) <- getSomeReg x+          (reg_y, _format_y, code_y) <- getSomeReg y+          return $ Any (intFormat w) (\dst ->+                                        code_x `appOL`+                                        code_y `appOL`+                                        truncateReg w W64 reg_x `appOL`+                                        truncateReg w W64 reg_y `snocOL`+                                        annExpr expr (OR (OpReg W64 dst) (OpReg W64 reg_x) (OpReg W64 reg_y))+                                     )++        _ -> do+          (reg_x, _format_x, code_x) <- getSomeReg x+          (reg_y, _format_y, code_y) <- getSomeReg y+          return $ Any (intFormat w) (\dst ->+                                        code_x `appOL`+                                        code_y `snocOL`+                                        annExpr expr (OR (OpReg W64 dst) (OpReg w reg_x) (OpReg w reg_y))+                                     )++    -- xori Instr's Imm-operand is zero-extended.+    CmmMachOp (MO_Xor w) [x, y] ->+      case y of+        CmmLit (CmmInt n _) | w `elem` [W8, W16, W32], (n :: Integer) >= 0, (n :: Integer) <= 4095 -> do+          (reg_x, _format_x, code_x) <- getSomeReg x+          return $ Any (intFormat w) (\dst ->+                                        code_x `appOL`+                                        truncateReg w W64 reg_x `snocOL`+                                        annExpr expr (XOR (OpReg W64 dst) (OpReg W64 reg_x) (OpImm (ImmInteger n)))+                                     )++        CmmLit (CmmInt n _) | (n :: Integer) >= 0, (n :: Integer) <= 4095 -> do+          (reg_x, _format_x, code_x) <- getSomeReg x+          return $ Any (intFormat w) (\dst -> code_x `snocOL` annExpr expr (XOR (OpReg W64 dst) (OpReg w reg_x) (OpImm (ImmInteger n))))++        CmmLit (CmmInt n _) | w `elem` [W8, W16, W32] -> do+          (reg_x, _format_x, code_x) <- getSomeReg x+          tmp <- getNewRegNat II64+          return $ Any (intFormat w) (\dst ->+                                       code_x `appOL`+                                       truncateReg w W64 reg_x `snocOL`+                                       annExpr expr (MOV (OpReg W64 tmp) (OpImm (ImmInteger n))) `snocOL`+                                       XOR (OpReg W64 dst) (OpReg W64 reg_x) (OpReg W64 tmp)+                                     )++        CmmLit (CmmInt n _) -> do+          (reg_x, _format_x, code_x) <- getSomeReg x+          tmp <- getNewRegNat II64+          return $ Any (intFormat w) (\dst ->+                                        code_x `snocOL`+                                        annExpr expr (MOV (OpReg W64 tmp) (OpImm (ImmInteger  n))) `snocOL`+                                        XOR (OpReg W64 dst) (OpReg w reg_x) (OpReg W64 tmp)+                                     )++        _ | w `elem` [W8, W16, W32] -> do+          (reg_x, _format_x, code_x) <- getSomeReg x+          (reg_y, _format_y, code_y) <- getSomeReg y+          return $ Any (intFormat w) (\dst ->+                                        code_x `appOL`+                                        code_y `appOL`+                                        truncateReg w W64 reg_x `appOL`+                                        truncateReg w W64 reg_y `snocOL`+                                        annExpr expr (XOR (OpReg W64 dst) (OpReg W64 reg_x) (OpReg W64 reg_y))+                                     )++        _ -> do+          (reg_x, _format_x, code_x) <- getSomeReg x+          (reg_y, _format_y, code_y) <- getSomeReg y+          return $ Any (intFormat w) (\dst ->+                                        code_x `appOL`+                                        code_y `snocOL`+                                        annExpr expr (XOR (OpReg W64 dst) (OpReg W64 reg_x) (OpReg W64 reg_y))+                                     )++    -- CSET commands register operand being W64.+    CmmMachOp (MO_Eq w) [x, y]+      | w `elem` [W8, W16, W32] -> do+        (reg_x, _format_x, code_x) <- getSomeReg x+        (reg_y, _format_y, code_y) <- getSomeReg y+        return $ Any (intFormat w) ( \dst ->+                                      code_x `appOL`+                                      code_y `appOL`+                                      signExtend w W64 reg_x reg_x `appOL`+                                      signExtend w W64 reg_y reg_y `snocOL`+                                      annExpr expr (CSET EQ (OpReg W64 dst) (OpReg W64 reg_x) (OpReg W64 reg_y))+                                   )+       | otherwise -> do+        (reg_x, _format_x, code_x) <- getSomeReg x+        (reg_y, _format_y, code_y) <- getSomeReg y+        return $ Any (intFormat w) ( \dst ->+                                      code_x `appOL`+                                      code_y `snocOL`+                                      annExpr expr (CSET EQ (OpReg W64 dst) (OpReg W64 reg_x) (OpReg W64 reg_y))+                                   )++    CmmMachOp (MO_Ne w) [x, y]+      | w `elem` [W8, W16, W32] -> do+        (reg_x, _format_x, code_x) <- getSomeReg x+        (reg_y, _format_y, code_y) <- getSomeReg y+        return $ Any (intFormat w) ( \dst ->+                                      code_x `appOL`+                                      code_y `appOL`+                                      signExtend w W64 reg_x reg_x `appOL`+                                      signExtend w W64 reg_y reg_y `snocOL`+                                      annExpr expr (CSET NE (OpReg W64 dst) (OpReg W64 reg_x) (OpReg W64 reg_y))+                                   )+      | otherwise -> do+        (reg_x, _format_x, code_x) <- getSomeReg x+        (reg_y, _format_y, code_y) <- getSomeReg y+        return $ Any (intFormat w) ( \dst ->+                                      code_x `appOL`+                                      code_y `snocOL`+                                      annExpr expr (CSET NE (OpReg W64 dst) (OpReg W64 reg_x) (OpReg W64 reg_y))+                                   )++    CmmMachOp (MO_S_Lt w) [x, CmmLit (CmmInt n _)]+      | w `elem` [W8, W16, W32]+      , fitsInNbits 12 (fromIntegral n) -> do+        (reg_x, _format_x, code_x) <- getSomeReg x+        return $ Any (intFormat w) ( \dst ->+                                      code_x `appOL`+                                      signExtend w W64 reg_x reg_x `snocOL`+                                      annExpr expr (SSLT (OpReg W64 dst) (OpReg W64 reg_x) (OpImm (ImmInteger n)))+                                   )+      | fitsInNbits 12 (fromIntegral n) -> do+        (reg_x, _format_x, code_x) <- getSomeReg x+        return $ Any (intFormat w) ( \dst -> code_x `snocOL` annExpr expr (SSLT (OpReg W64 dst) (OpReg W64 reg_x) (OpImm (ImmInteger n))))++    CmmMachOp (MO_U_Lt w) [x, CmmLit (CmmInt n _)]+      | w `elem` [W8, W16, W32]+      , fitsInNbits 12 (fromIntegral n) -> do+        (reg_x, _format_x, code_x) <- getSomeReg x+        return $ Any (intFormat w) ( \dst ->+                                      code_x `appOL`+                                      truncateReg w W64 reg_x `snocOL`+                                      annExpr expr (SSLTU (OpReg W64 dst) (OpReg W64 reg_x) (OpImm (ImmInteger n)))+                                   )+      | fitsInNbits 12 (fromIntegral n) -> do+        (reg_x, _format_x, code_x) <- getSomeReg x+        return $ Any (intFormat w) ( \dst -> code_x `snocOL` annExpr expr (SSLTU (OpReg W64 dst) (OpReg W64 reg_x) (OpImm (ImmInteger  n))))++    CmmMachOp (MO_S_Lt w) [x, y]+      | w `elem` [W8, W16, W32] -> do+        (reg_x, _format_x, code_x) <- getSomeReg x+        (reg_y, _format_y, code_y) <- getSomeReg y+        return $ Any (intFormat w) ( \dst ->+                                      code_x `appOL`+                                      code_y `appOL`+                                      signExtend w W64 reg_x reg_x `appOL`+                                      signExtend w W64 reg_y reg_y `snocOL`+                                      annExpr expr (CSET SLT (OpReg W64 dst) (OpReg W64 reg_x) (OpReg W64 reg_y))+                                   )+      | otherwise -> do+        (reg_x, _format_x, code_x) <- getSomeReg x+        (reg_y, _format_y, code_y) <- getSomeReg y+        return $ Any (intFormat w) ( \dst ->+                                      code_x `appOL`+                                      code_y `snocOL`+                                      annExpr expr (CSET SLT (OpReg W64 dst) (OpReg W64 reg_x) (OpReg W64 reg_y))+                                   )++    CmmMachOp (MO_S_Le w) [x, y]+      | w `elem` [W8, W16, W32] -> do+        (reg_x, _format_x, code_x) <- getSomeReg x+        (reg_y, _format_y, code_y) <- getSomeReg y+        return $ Any (intFormat w) ( \dst ->+                                      code_x `appOL`+                                      code_y `appOL`+                                      signExtend w W64 reg_x reg_x `appOL`+                                      signExtend w W64 reg_y reg_y `snocOL`+                                      annExpr expr (CSET SLE (OpReg W64 dst) (OpReg W64 reg_x) (OpReg W64 reg_y))+                                   )+      | otherwise -> do+        (reg_x, _format_x, code_x) <- getSomeReg x+        (reg_y, _format_y, code_y) <- getSomeReg y+        return $ Any (intFormat w) ( \dst ->+                                      code_x `appOL`+                                      code_y `snocOL`+                                      annExpr expr (CSET SLE (OpReg W64 dst) (OpReg W64 reg_x) (OpReg W64 reg_y))+                                   )++    CmmMachOp (MO_S_Ge w) [x, y]+      | w `elem` [W8, W16, W32] -> do+        (reg_x, _format_x, code_x) <- getSomeReg x+        (reg_y, _format_y, code_y) <- getSomeReg y+        return $ Any (intFormat w) ( \dst ->+                                      code_x `appOL`+                                      code_y `appOL`+                                      signExtend w W64 reg_x reg_x `appOL`+                                      signExtend w W64 reg_y reg_y `snocOL`+                                      annExpr expr (CSET SGE (OpReg W64 dst) (OpReg W64 reg_x) (OpReg W64 reg_y))+                                   )+      | otherwise -> do+        (reg_x, _format_x, code_x) <- getSomeReg x+        (reg_y, _format_y, code_y) <- getSomeReg y+        return $ Any (intFormat w) ( \dst ->+                                      code_x `appOL`+                                      code_y `snocOL`+                                      annExpr expr (CSET SGE (OpReg W64 dst) (OpReg W64 reg_x) (OpReg W64 reg_y))+                                   )++    CmmMachOp (MO_S_Gt w) [x, y]+      | w `elem` [W8, W16, W32] -> do+        (reg_x, _format_x, code_x) <- getSomeReg x+        (reg_y, _format_y, code_y) <- getSomeReg y+        return $ Any (intFormat w) ( \dst ->+                                      code_x `appOL`+                                      code_y `appOL`+                                      signExtend w W64 reg_x reg_x `appOL`+                                      signExtend w W64 reg_y reg_y `snocOL`+                                      annExpr expr (CSET SGT (OpReg W64 dst) (OpReg W64 reg_x) (OpReg W64 reg_y))+                                   )+      | otherwise -> do+        (reg_x, _format_x, code_x) <- getSomeReg x+        (reg_y, _format_y, code_y) <- getSomeReg y+        return $ Any (intFormat w) ( \dst ->+                                      code_x `appOL`+                                      code_y `snocOL`+                                      annExpr expr (CSET SGT (OpReg W64 dst) (OpReg W64 reg_x) (OpReg W64 reg_y))+                                   )++    CmmMachOp (MO_U_Lt w) [x, y]+      | w `elem` [W8, W16, W32] -> do+        (reg_x, _format_x, code_x) <- getSomeReg x+        (reg_y, _format_y, code_y) <- getSomeReg y+        return $ Any (intFormat w) ( \dst ->+                                      code_x `appOL`+                                      code_y `appOL`+                                      truncateReg w W64 reg_x `appOL`+                                      truncateReg w W64 reg_y `snocOL`+                                      annExpr expr (CSET ULT (OpReg W64 dst) (OpReg W64 reg_x) (OpReg W64 reg_y))+                                   )+      | otherwise -> do+        (reg_x, _format_x, code_x) <- getSomeReg x+        (reg_y, _format_y, code_y) <- getSomeReg y+        return $ Any (intFormat w) ( \dst ->+                                      code_x `appOL`+                                      code_y `snocOL`+                                      annExpr expr (CSET ULT (OpReg W64 dst) (OpReg W64 reg_x) (OpReg W64 reg_y))+                                   )++    CmmMachOp (MO_U_Le w) [x, y]+      | w `elem` [W8, W16, W32] -> do+        (reg_x, _format_x, code_x) <- getSomeReg x+        (reg_y, _format_y, code_y) <- getSomeReg y+        return $ Any (intFormat w) ( \dst ->+                                      code_x `appOL`+                                      code_y `appOL`+                                      truncateReg w W64 reg_x `appOL`+                                      truncateReg w W64 reg_y `snocOL`+                                      annExpr expr (CSET ULE (OpReg W64 dst) (OpReg W64 reg_x) (OpReg W64 reg_y))+                                   )+      | otherwise -> do+        (reg_x, _format_x, code_x) <- getSomeReg x+        (reg_y, _format_y, code_y) <- getSomeReg y+        return $ Any (intFormat w) ( \dst ->+                                      code_x `appOL`+                                      code_y `snocOL`+                                      annExpr expr (CSET ULE (OpReg W64 dst) (OpReg W64 reg_x) (OpReg W64 reg_y))+                                   )++    CmmMachOp (MO_U_Ge w) [x, y]+      | w `elem` [W8, W16, W32] -> do+        (reg_x, _format_x, code_x) <- getSomeReg x+        (reg_y, _format_y, code_y) <- getSomeReg y+        return $ Any (intFormat w) ( \dst ->+                                      code_x `appOL`+                                      code_y `appOL`+                                      truncateReg w W64 reg_x `appOL`+                                      truncateReg w W64 reg_y `snocOL`+                                      annExpr expr (CSET UGE (OpReg W64 dst) (OpReg W64 reg_x) (OpReg W64 reg_y))+                                   )+      | otherwise -> do+        (reg_x, _format_x, code_x) <- getSomeReg x+        (reg_y, _format_y, code_y) <- getSomeReg y+        return $ Any (intFormat w) ( \dst ->+                                      code_x `appOL`+                                      code_y `snocOL`+                                      annExpr expr (CSET UGE (OpReg W64 dst) (OpReg W64 reg_x) (OpReg W64 reg_y))+                                   )++    CmmMachOp (MO_U_Gt w) [x, y]+      | w `elem` [W8, W16, W32] -> do+        (reg_x, _format_x, code_x) <- getSomeReg x+        (reg_y, _format_y, code_y) <- getSomeReg y+        return $ Any (intFormat w) ( \dst ->+                                      code_x `appOL`+                                      code_y `appOL`+                                      truncateReg w W64 reg_x `appOL`+                                      truncateReg w W64 reg_y `snocOL`+                                      annExpr expr (CSET UGT (OpReg W64 dst) (OpReg W64 reg_x) (OpReg W64 reg_y))+                                   )+      | otherwise -> do+        (reg_x, _format_x, code_x) <- getSomeReg x+        (reg_y, _format_y, code_y) <- getSomeReg y+        return $ Any (intFormat w) ( \dst ->+                                      code_x `appOL`+                                      code_y `snocOL`+                                      annExpr expr (CSET UGT (OpReg W64 dst) (OpReg W64 reg_x) (OpReg W64 reg_y))+                                   )+++    -- Generic binary case.+    CmmMachOp op [x, y] -> do+      let+          -- A (potentially signed) integer operation.+          -- In the case of 8-, 16- and 32-bit signed arithmetic we must first+          -- sign-extend all arguments to 64-bits.+          -- TODO: can be simplified.+          intOp is_signed w op = do+              -- compute x<m> <- x+              -- compute x<o> <- y+              -- <OP> x<n>, x<m>, x<o>+              (reg_x, format_x, code_x) <- getSomeReg x+              (reg_y, format_y, code_y) <- getSomeReg y+              massertPpr (isIntFormat format_x && isIntFormat format_y) $ text "intOp: non-int"+              let w' = W64+              -- This is the width of the registers on which the operation+              -- should be performed.+              if not is_signed+                then return $ Any (intFormat w) $ \dst ->+                      code_x `appOL`+                      code_y `appOL`+                      -- zero-extend both operands+                      truncateReg (formatToWidth format_x) w' reg_x `appOL`+                      truncateReg (formatToWidth format_y) w' reg_y `snocOL`+                      op (OpReg w' dst) (OpReg w' reg_x) (OpReg w' reg_y) `appOL`+                      truncateReg w' w dst -- truncate back to the operand's original width+                else return $ Any (intFormat w) $ \dst ->+                      code_x `appOL`+                      code_y `appOL`+                      -- sign-extend both operands+                      signExtend (formatToWidth format_x) W64 reg_x reg_x `appOL`+                      signExtend (formatToWidth format_x) W64 reg_y reg_y `snocOL`+                      op (OpReg w' dst) (OpReg w' reg_x) (OpReg w' reg_y) `appOL`+                      truncateReg w' w dst -- truncate back to the operand's original width++          floatOp w op = do+            (reg_fx, format_x, code_fx) <- getFloatReg x+            (reg_fy, format_y, code_fy) <- getFloatReg y+            massertPpr (isFloatFormat format_x && isFloatFormat format_y) $ text "floatOp: non-float"+            return $ Any (floatFormat w) (\dst -> code_fx `appOL` code_fy `appOL` op (OpReg w dst) (OpReg w reg_fx) (OpReg w reg_fy))++          -- need a special one for conditionals, as they return ints+          floatCond w op = do+            (reg_fx, format_x, code_fx) <- getFloatReg x+            (reg_fy, format_y, code_fy) <- getFloatReg y+            massertPpr (isFloatFormat format_x && isFloatFormat format_y) $ text "floatCond: non-float"+            return $ Any (intFormat w) (\dst -> code_fx `appOL` code_fy `appOL` op (OpReg w dst) (OpReg w reg_fx) (OpReg w reg_fy))++      case op of+        -- Integer operations+        -- Add/Sub should only be Integer Options.+        MO_Add w -> intOp False w (\d x y ->  annExpr expr (ADD d x y))+        MO_Sub w -> intOp False w (\d x y ->  annExpr expr (SUB d x y))++        -- Signed multiply/divide/remain+        MO_Mul w          -> intOp True w (\d x y -> annExpr expr (MUL d x y))+        MO_S_MulMayOflo w -> do_mul_may_oflo w x y++        MO_S_Quot w  -> intOp True w (\d x y -> annExpr expr (DIV d x y))+        MO_S_Rem w   -> intOp True w (\d x y -> annExpr expr (MOD d x y))++        -- Unsigned divide/remain+        MO_U_Quot w  -> intOp False w (\d x y -> annExpr expr (DIVU d x y))+        MO_U_Rem w   -> intOp False w (\d x y -> annExpr expr (MODU d x y))++        -- Floating point arithmetic+        MO_F_Add w   -> floatOp w (\d x y -> unitOL $ annExpr expr (ADD d x y))+        MO_F_Sub w   -> floatOp w (\d x y -> unitOL $ annExpr expr (SUB d x y))+        MO_F_Mul w   -> floatOp w (\d x y -> unitOL $ annExpr expr (MUL d x y))+        MO_F_Quot w  -> floatOp w (\d x y -> unitOL $ annExpr expr (DIV d x y))+        MO_F_Min w   -> floatOp w (\d x y -> unitOL $ annExpr expr (FMIN d x y))+        MO_F_Max w   -> floatOp w (\d x y -> unitOL $ annExpr expr (FMAX d x y))++        -- Floating point comparison+        MO_F_Eq w    -> floatCond w (\d x y -> unitOL $ annExpr expr (CSET EQ d x y))+        MO_F_Ne w    -> floatCond w (\d x y -> unitOL $ annExpr expr (CSET NE d x y))+        MO_F_Ge w    -> floatCond w (\d x y -> unitOL $ annExpr expr (CSET FGE d x y))+        MO_F_Le w    -> floatCond w (\d x y -> unitOL $ annExpr expr (CSET FLE d x y))+        MO_F_Gt w    -> floatCond w (\d x y -> unitOL $ annExpr expr (CSET FGT d x y))+        MO_F_Lt w    -> floatCond w (\d x y -> unitOL $ annExpr expr (CSET FLT d x y))++        op -> pprPanic "getRegister' (unhandled dyadic CmmMachOp): " $ pprMachOp op <+> text "in" <+> pdoc plat expr++    -- Generic ternary case.+    CmmMachOp op [x, y, z] ->+      case op of++        -- Floating-point fused multiply-add operations+        MO_FMA var l w+          | l == 1+          -> case var of+            FMAdd  -> float3Op w (\d n m a -> unitOL $ FMA FMAdd  d n m a)+            FMSub  -> float3Op w (\d n m a -> unitOL $ FMA FMSub d n m a)+            FNMAdd -> float3Op w (\d n m a -> unitOL $ FMA FNMSub  d n m a)+            FNMSub -> float3Op w (\d n m a -> unitOL $ FMA FNMAdd d n m a)+          | otherwise+          -> sorry "The RISCV64 backend does not (yet) support vectors."++        _ -> pprPanic "getRegister' (unhandled ternary CmmMachOp): " $ (pprMachOp op) <+> text "in" <+> (pdoc plat expr)++      where+          float3Op w op = do+            (reg_fx, format_x, code_fx) <- getFloatReg x+            (reg_fy, format_y, code_fy) <- getFloatReg y+            (reg_fz, format_z, code_fz) <- getFloatReg z+            massertPpr (isFloatFormat format_x && isFloatFormat format_y && isFloatFormat format_z) $+              text "float3Op: non-float"+            pure $+              Any (floatFormat w) $ \ dst ->+                code_fx `appOL`+                code_fy `appOL`+                code_fz `appOL`+                op (OpReg w dst) (OpReg w reg_fx) (OpReg w reg_fy) (OpReg w reg_fz)++    CmmMachOp _op _xs+      -> pprPanic "getRegister' (variadic CmmMachOp): " (pdoc plat expr)++  where+    -- N.B. MUL does not set the overflow flag.+    -- Return 0 when the operation cannot overflow, /= 0 otherwise+    do_mul_may_oflo :: Width -> CmmExpr -> CmmExpr -> NatM Register+    do_mul_may_oflo W64 x y = do+      (reg_x, _format_x, code_x) <- getSomeReg x+      (reg_y, _format_y, code_y) <- getSomeReg y+      lo <- getNewRegNat II64+      hi <- getNewRegNat II64+      return $ Any (intFormat W64) (\dst ->+        code_x `appOL`+        code_y `snocOL`+        MULH (OpReg W64 hi) (OpReg W64 reg_x)  (OpReg W64 reg_y) `snocOL`+        MUL  (OpReg W64 lo) (OpReg W64 reg_x)  (OpReg W64 reg_y) `snocOL`+        SRA  (OpReg W64 lo) (OpReg W64 lo)     (OpImm (ImmInt 63)) `snocOL`+        CSET NE (OpReg W64 dst) (OpReg W64 hi)  (OpReg W64 lo)+                                 )++    do_mul_may_oflo W32 x y = do+        (reg_x, _format_x, code_x) <- getSomeReg x+        (reg_y, _format_y, code_y) <- getSomeReg y+        tmp1 <- getNewRegNat II64+        tmp2 <- getNewRegNat II64+        return $ Any (intFormat W32) (\dst ->+            code_x `appOL`+            code_y `snocOL`+            MULW (OpReg W64 tmp1) (OpReg W64 reg_x) (OpReg W64 reg_y) `snocOL`+            ADD (OpReg W64 tmp2) (OpReg W32 tmp1) (OpImm (ImmInt 0)) `snocOL`+            CSET NE (OpReg W64 dst) (OpReg W64 tmp1)  (OpReg W64 tmp2)+                                     )++    -- General case+    do_mul_may_oflo w x y = do+      -- Assert: 8bit * 8bit cannot overflow 16bit, and so on.+      (reg_x, format_x, code_x) <- getSomeReg x+      (reg_y, format_y, code_y) <- getSomeReg y+      tmp1 <- getNewRegNat II64+      tmp2 <- getNewRegNat II64+      let width_x = formatToWidth format_x+          width_y = formatToWidth format_y+          extend dst src =+            case w of+              W8  -> SLL (OpReg W64 dst) (OpReg W32 src) (OpImm (ImmInt 0))+              W16 -> SLL (OpReg W64 dst) (OpReg W32 src) (OpImm (ImmInt 0))+              _   -> panic "Must be in [W8, W16, W32]!"+          extract width dst src =+            case width of+              W8  -> EXT (OpReg W64 dst) (OpReg W8 src)+              W16 -> EXT (OpReg W64 dst) (OpReg W16 src)+              W32 -> SLL (OpReg W64 dst) (OpReg W32 src) (OpImm (ImmInt 0))+              _   -> panic "Must be in [W8, W16, W32]!"++      case w of+        w | (width_x < w) && (width_y < w) ->+          return $ Any (intFormat w) ( \dst ->+            unitOL $ annExpr expr (MOV (OpReg w dst) (OpImm (ImmInt 0)))+                                     )+        w | w <= W32 && width_x <= W32 && width_y <= W32 ->+            return $ Any (intFormat W32) (\dst ->+                code_x `appOL`+                code_y `appOL`+                -- signExtend [W8, W16] register to W64 and then SLL+                -- nil for W32+                signExtend (formatToWidth format_x) W64 reg_x reg_x `appOL`+                signExtend (formatToWidth format_y) W64 reg_y reg_y `snocOL`+                extend reg_x reg_x `snocOL`+                extend reg_y reg_y `snocOL`+                -- 64-bits MUL+                MUL (OpReg W64 tmp1) (OpReg W64 reg_x) (OpReg W64 reg_y) `snocOL`+                -- extract valid result via result's width+                -- slli.w for W32, otherwise ext.w.[b, h]+                extract w tmp2 tmp1 `snocOL`+                CSET NE (OpReg W64 dst) (OpReg W64 tmp1)  (OpReg W64 tmp2)+                                        )++        -- Should it be happened?+        _ ->+          return $ Any (intFormat w) ( \dst ->+            unitOL $ annExpr expr (MOV (OpReg w dst) (OpImm (ImmInt 1))))++-- Sign-extend the value in the given register from width @w@+-- up to width @w'@.+-- TODO: Is there room for optimization?+signExtend :: Width -> Width -> Reg -> Reg -> OrdList Instr+signExtend w w' r r'+  | w > w' = pprPanic "Sign-extend Error: not a sign extension, but a truncation." $ ppr w <> text "->" <+> ppr w'+  | w > W64 || w' > W64  = pprPanic "Sign-extend Error: from/to register width greater than 64-bit." $ ppr w <> text "->" <+> ppr w'+  | w == W64 && w' == W64 && r == r' = nilOL+  | w == W32 && w' == W64 = unitOL $ SLL (OpReg W64 r') (OpReg w r) (OpImm (ImmInt 0))+  -- Sign-extend W8 and W16 to W64.+  | w `elem` [W8, W16] = unitOL $ EXT (OpReg W64 r') (OpReg w r)+  | w == w' = unitOL $ MOV (OpReg w' r') (OpReg w r)+  | otherwise = pprPanic "signExtend: Unexpected width: " $ ppr w  <> text "->" <+> ppr w'++-- | Instructions to truncate the value in the given register from width @w@+-- down to width @w'@.+truncateReg :: Width -> Width -> Reg -> OrdList Instr+truncateReg w w' r+  | w > W64 || w' > W64  = pprPanic "Tructate Error: from/to register width greater than 64-bit." $ ppr w <> text "->" <+> ppr w'+  | w == w' = nilOL+  | w /= w' = toOL+    [+      ann+        (text "truncateReg: " <+> ppr r <+> ppr w <> text "->" <> ppr w')+        (BSTRPICK II64 (OpReg w' r) (OpReg w r) (OpImm (ImmInt shift)) (OpImm (ImmInt 0)))+    ]+  | otherwise = pprPanic "truncateReg: Unexpected width: " $ ppr w  <> text "->" <+> ppr w'+  where+    shift = (min (widthInBits w) (widthInBits w')) - 1++--  The 'Amode' type: Memory addressing modes passed up the tree.+data Amode = Amode AddrMode InstrBlock++-- | Provide the value of a `CmmExpr` with an `Amode`+--  N.B. this function should be used to provide operands to load and store+--  instructions with signed 12bit wide immediates (S & I types). For other+--  immediate sizes and formats (e.g. B type uses multiples of 2) this function+--  would need to be adjusted.+getAmode :: Platform+         -> Width     -- ^ width of loaded value+         -> CmmExpr+         -> NatM Amode++-- LD/ST: Immediate can be represented with 12bits+getAmode platform w (CmmRegOff reg off)+  | w <= W64, fitsInNbits 12 (fromIntegral off)+  = return $ Amode (AddrRegImm reg' off') nilOL+    where reg' = getRegisterReg platform reg+          off' = ImmInt off++-- For Stores we often see something like this:+-- CmmStore (CmmMachOp (MO_Add w) [CmmLoad expr, CmmLit (CmmInt n w')]) (expr2)+-- E.g. a CmmStoreOff really. This can be translated to `str $expr2, [$expr, #n ]+-- for `n` in range.+getAmode _platform _ (CmmMachOp (MO_Add _w) [expr, CmmLit (CmmInt off _w')])+  | fitsInNbits 12 (fromIntegral off)+  = do (reg, _format, code) <- getSomeReg expr+       return $ Amode (AddrRegImm reg (ImmInteger off)) code++getAmode _platform _ (CmmMachOp (MO_Sub _w) [expr, CmmLit (CmmInt off _w')])+  | fitsInNbits 12 (fromIntegral (-off))+  = do (reg, _format, code) <- getSomeReg expr+       return $ Amode (AddrRegImm reg (ImmInteger (-off))) code++-- Generic case+getAmode _platform _ expr+  = do (reg, _format, code) <- getSomeReg expr+       return $ Amode (AddrReg reg) code++-- -----------------------------------------------------------------------------+-- Generating assignments++-- Assignments are really at the heart of the whole code generation+-- business.  Almost all top-level nodes of any real importance are+-- assignments, which correspond to loads, stores, or register+-- transfers.  If we're really lucky, some of the register transfers+-- will go away, because we can use the destination register to+-- complete the code generation for the right hand side.  This only+-- fails when the right hand side is forced into a fixed register+-- (e.g. the result of a call).++assignMem_IntCode :: Format -> CmmExpr -> CmmExpr -> NatM InstrBlock+assignReg_IntCode :: Format -> CmmReg  -> CmmExpr -> NatM InstrBlock++assignMem_FltCode :: Format -> CmmExpr -> CmmExpr -> NatM InstrBlock+assignReg_FltCode :: Format -> CmmReg  -> CmmExpr -> NatM InstrBlock++assignMem_IntCode rep addrE srcE+  = do+    (src_reg, _format, code) <- getSomeReg srcE+    platform <- getPlatform+    let w = formatToWidth rep+    Amode addr addr_code <- getAmode platform w addrE+    return $ COMMENT (text "CmmStore" <+> parens (text (show addrE)) <+> parens (text (show srcE)))+            `consOL` (code+            `appOL`   addr_code+            `snocOL`  ST rep (OpReg w src_reg) (OpAddr addr)+                     )++assignReg_IntCode _ reg src+  = do+    platform <- getPlatform+    let dst = getRegisterReg platform reg+    r <- getRegister src+    return $ case r of+      Any _ code              -> COMMENT (text "CmmAssign" <+> parens (text (show reg)) <+> parens (text (show src))) `consOL` code dst+      Fixed format freg fcode -> COMMENT (text "CmmAssign" <+> parens (text (show reg)) <+> parens (text (show src))) `consOL`+                                               (fcode `snocOL`+                                                 MOV (OpReg (formatToWidth format) dst) (OpReg (formatToWidth format) freg)+                                               )++-- Let's treat Floating point stuff+-- as integer code for now. Opaque.+assignMem_FltCode = assignMem_IntCode+assignReg_FltCode = assignReg_IntCode++-- Jumps+genJump :: CmmExpr{-the branch target-} -> NatM InstrBlock+genJump expr = do+  case expr of+    (CmmLit (CmmLabel lbl)) -> do+      return $ unitOL (annExpr expr (TAIL36 (OpReg W64 tmpReg) (TLabel lbl)))+    (CmmLit (CmmBlock bid)) -> do+      return $ unitOL (annExpr expr (TAIL36 (OpReg W64 tmpReg) (TBlock bid)))+    _ -> do+      (target, _format, code) <- getSomeReg expr+      -- I'd like to do more.+      return $ COMMENT (text "genJump for unknow expr: " <+> (text (show expr))) `consOL`+        (code `appOL`+          unitOL (annExpr expr (J (TReg target)))+        )++-- -----------------------------------------------------------------------------+--  Unconditional branches+genBranch :: BlockId -> NatM InstrBlock+genBranch = return . toOL . mkJumpInstr++-- -----------------------------------------------------------------------------+-- Conditional branches+genCondJump+    :: BlockId+    -> CmmExpr+    -> NatM InstrBlock+genCondJump bid expr = do+    case expr of+      -- Optimized == 0 case.+      CmmMachOp (MO_Eq W64) [x, CmmLit (CmmInt 0 _)] -> do+        (reg_x, _format_x, code_x) <- getSomeReg x+        return $+          code_x `snocOL`+          BEQZ (OpReg W64 reg_x) (TBlock bid)+      CmmMachOp (MO_Eq w) [x, CmmLit (CmmInt 0 _)]+        | w `elem` [W8, W16, W32] -> do+        (reg_x, format_x, code_x) <- getSomeReg x+        return $+          code_x `appOL`+          signExtend (formatToWidth format_x) W64 reg_x reg_x `snocOL`+          BEQZ (OpReg W64 reg_x) (TBlock bid)++      -- Optimized /= 0 case.+      CmmMachOp (MO_Ne W64) [x, CmmLit (CmmInt 0 _)] -> do+        (reg_x, _format_x, code_x) <- getSomeReg x+        return $ code_x `snocOL` (annExpr expr (BNEZ (OpReg W64 reg_x) (TBlock bid)))+      CmmMachOp (MO_Ne w) [x, CmmLit (CmmInt 0 _)]+        | w `elem` [W8, W16, W32] -> do+        (reg_x, format_x, code_x) <- getSomeReg x+        return $+          code_x `appOL`+          signExtend (formatToWidth format_x) W64 reg_x reg_x `snocOL`+          BNEZ (OpReg W64 reg_x) (TBlock bid)++      -- Generic case.+      CmmMachOp mop [x, y] -> do+        let ubcond w cmp = do+              (reg_x, format_x, code_x) <- getSomeReg x+              (reg_y, format_y, code_y) <- getSomeReg y+              return $ case w of+                w | w `elem` [W8, W16, W32] ->+                    code_x `appOL`+                    truncateReg (formatToWidth format_x) W64 reg_x  `appOL`+                    code_y `appOL`+                    truncateReg (formatToWidth format_y) W64 reg_y  `snocOL`+                    BCOND1 cmp (OpReg W64 reg_x) (OpReg W64 reg_y) (TBlock bid)+                _ ->+                    code_x `appOL`+                    code_y `snocOL`+                    BCOND1 cmp (OpReg W64 reg_x) (OpReg W64 reg_y) (TBlock bid)++            sbcond w cmp = do+              (reg_x, format_x, code_x) <- getSomeReg x+              (reg_y, format_y, code_y) <- getSomeReg y+              return $ case w of+                w | w `elem` [W8, W16, W32] ->+                  code_x `appOL`+                  signExtend (formatToWidth format_x) W64 reg_x reg_x `appOL`+                  code_y `appOL`+                  signExtend (formatToWidth format_y) W64 reg_y reg_y `snocOL`+                  BCOND1 cmp (OpReg W64 reg_x) (OpReg W64 reg_y) (TBlock bid)+                _ ->+                  code_x `appOL`+                  code_y `snocOL`+                  BCOND1 cmp (OpReg W64 reg_x) (OpReg W64 reg_y) (TBlock bid)++            fbcond w cmp = do+              (reg_fx, _format_fx, code_fx) <- getFloatReg x+              (reg_fy, _format_fy, code_fy) <- getFloatReg y+              rst <- OpReg W64 <$> getNewRegNat II64+              oneReg <- OpReg W64 <$> getNewRegNat II64+              return $+                code_fx `appOL`+                code_fy `snocOL`+                CSET cmp rst (OpReg w reg_fx) (OpReg w reg_fy) `snocOL`+                MOV oneReg (OpImm (ImmInt 1)) `snocOL`+                BCOND1 EQ rst oneReg (TBlock bid)+++        case mop of+          MO_F_Eq w -> fbcond w EQ+          MO_F_Ne w -> fbcond w NE+          MO_F_Gt w -> fbcond w FGT+          MO_F_Ge w -> fbcond w FGE+          MO_F_Lt w -> fbcond w FLT+          MO_F_Le w -> fbcond w FLE+          MO_Eq w   -> sbcond w EQ+          MO_Ne w   -> sbcond w NE+          MO_S_Gt w -> sbcond w SGT+          MO_S_Ge w -> sbcond w SGE+          MO_S_Lt w -> sbcond w SLT+          MO_S_Le w -> sbcond w SLE+          MO_U_Gt w -> ubcond w UGT+          MO_U_Ge w -> ubcond w UGE+          MO_U_Lt w -> ubcond w ULT+          MO_U_Le w -> ubcond w ULE+          _ -> pprPanic "LA64.genCondJump:case mop: " (text $ show expr)++      _ -> pprPanic "LA64.genCondJump: " (text $ show expr)++-- | Generate conditional branching instructions+-- This is basically an "if with else" statement.+genCondBranch ::+  BlockId ->+  BlockId ->+  CmmExpr ->+  NatM InstrBlock+genCondBranch true false expr = do+  b1 <- genCondJump true expr+  b2 <- genBranch false+  return (b1 `appOL` b2)++-- -----------------------------------------------------------------------------+{-+Generating C calls++Generate a call to a C function:++GARs: 8 general-purpose registers $a0 - $a7, where $a0 and $a1 are also used for+integral values.+FARs: 8 floating-point registers $fa0 - $fa7, where $fa0 and $fa1 are also used+for returning values.++An argument is passed using the stack only when no appropriate argument register+is available.++Subroutines should ensure that the initial values of the general-purpose registers+$s0 - $s9 and floating-point registers $fs0 - $fs7 are preserved across the call.++At the entry of a procedure call, the return address of the call site is stored+in $ra. A branch jump to this address should be the last instruction executed in+the called procedure.++The on-stack part of the structure and scalar arguments are aligned to the greater+of the type alignment and GRLEN bits, except when this alignment is larger than+ the 16-byte stack alignment. In this case, the part of the argument should be+16-byte-aligned.++In a procedure call, GARs / FARs are generally only used for passing non-floating+-point / floating-point argument data, respectively. However, the floating-point+member of a structure or union argument, or a vector/floating-point argument+wider than FRLEN may be passed in a GAR.+-}++genCCall+    :: ForeignTarget      -- function to call+    -> [CmmFormal]        -- where to put the result+    -> [CmmActual]        -- arguments (of mixed type)+    -> NatM InstrBlock++-- TODO: Specialize where we can.+-- Generic impl+genCCall target dest_regs arg_regs = do+  case target of+    -- The target :: ForeignTarget call can either+    -- be a foreign procedure with an address expr+    -- and a calling convention.+    ForeignTarget expr _cconv -> do+      (call_target, call_target_code) <- case expr of+        -- if this is a label, let's just directly to it.+        (CmmLit (CmmLabel lbl)) -> pure (TLabel lbl, nilOL)+        -- if it's not a label, let's compute the expression into a+        -- register and jump to that.+        _ -> do+          (reg, _format, reg_code) <- getSomeReg expr+          pure (TReg reg, reg_code)+      -- compute the code and register logic for all arg_regs.+      -- this will give us the format information to match on.+      arg_regs' <- mapM getSomeReg arg_regs++      -- Now this is stupid.  Our Cmm expressions doesn't carry the proper sizes+      -- so while in Cmm we might get W64 incorrectly for an int, that is W32 in+      -- STG; this thenn breaks packing of stack arguments, if we need to pack+      -- for the pcs, e.g. darwinpcs.  Option one would be to fix the Int type+      -- in Cmm proper. Option two, which we choose here is to use extended Hint+      -- information to contain the size information and use that when packing+      -- arguments, spilled onto the stack.+      let (_res_hints, arg_hints) = foreignTargetHints target+          arg_regs'' = zipWith (\(r, f, c) h -> (r,f,h,c)) arg_regs' arg_hints++      (stackSpaceWords, passRegs, passArgumentsCode) <- passArguments allGpArgRegs allFpArgRegs arg_regs'' 0 [] nilOL++      readResultsCode <- readResults allGpArgRegs allFpArgRegs dest_regs [] nilOL++      let moveStackDown 0 = toOL [ PUSH_STACK_FRAME+                                 , DELTA (-16)+                                 ]+          moveStackDown i | odd i = moveStackDown (i + 1)+          moveStackDown i = toOL [ PUSH_STACK_FRAME+                                 , SUB (OpReg W64 (spMachReg)) (OpReg W64 (spMachReg)) (OpImm (ImmInt (8 * i)))+                                 , DELTA (-8 * i - 16)+                                 ]+          moveStackUp 0 = toOL [ POP_STACK_FRAME+                               , DELTA 0+                               ]+          moveStackUp i | odd i = moveStackUp (i + 1)+          moveStackUp i = toOL [ ADD (OpReg W64 (spMachReg)) (OpReg W64 (spMachReg)) (OpImm (ImmInt (8 * i)))+                               , POP_STACK_FRAME+                               , DELTA 0+                               ]++      let code =+            call_target_code -- compute the label (possibly into a register)+              `appOL` moveStackDown (stackSpaceWords)+              `appOL` passArgumentsCode -- put the arguments into x0, ...+              `snocOL` CALL call_target passRegs -- branch and link (C calls aren't tail calls, but return)+              `appOL` readResultsCode -- parse the results into registers+              `appOL` moveStackUp (stackSpaceWords)+      return code++    PrimTarget MO_F32_Fabs+      | [arg_reg] <- arg_regs, [dest_reg] <- dest_regs ->+        unaryFloatOp W32 (\d x -> unitOL $ FABS d x) arg_reg dest_reg+      | otherwise -> panic "mal-formed MO_F32_Fabs"+    PrimTarget MO_F64_Fabs+      | [arg_reg] <- arg_regs, [dest_reg] <- dest_regs ->+        unaryFloatOp W64 (\d x -> unitOL $ FABS d x) arg_reg dest_reg+      | otherwise -> panic "mal-formed MO_F64_Fabs"++    PrimTarget MO_F32_Sqrt+      | [arg_reg] <- arg_regs, [dest_reg] <- dest_regs ->+        unaryFloatOp W32 (\d x -> unitOL $ FSQRT d x) arg_reg dest_reg+      | otherwise -> panic "mal-formed MO_F32_Sqrt"+    PrimTarget MO_F64_Sqrt+      | [arg_reg] <- arg_regs, [dest_reg] <- dest_regs ->+        unaryFloatOp W64 (\d x -> unitOL $ FSQRT d x) arg_reg dest_reg+      | otherwise -> panic "mal-formed MO_F64_Sqrt"++    PrimTarget (MO_Clz w)+      | w `elem` [W32, W64],+      [arg_reg] <- arg_regs,+      [dest_reg] <- dest_regs -> do+      platform <- getPlatform+      (reg_x, _format_x, code_x) <- getSomeReg arg_reg+      let dst_reg = getRegisterReg platform (CmmLocal dest_reg)+      return ( code_x `snocOL`+               CLZ (OpReg w dst_reg) (OpReg w reg_x)+             )+      | w `elem` [W8, W16],+      [arg_reg] <- arg_regs,+      [dest_reg] <- dest_regs -> do+        platform <- getPlatform+        (reg_x, _format_x, code_x) <- getSomeReg arg_reg+        let dst_reg = getRegisterReg platform (CmmLocal dest_reg)+        return ( code_x `appOL` toOL+                 [+                  MOV (OpReg W64 dst_reg) (OpImm (ImmInt 1)),+                  SLL (OpReg W64 dst_reg) (OpReg W64 dst_reg) (OpImm (ImmInt (31-shift))),+                  SLL (OpReg W64 reg_x) (OpReg W64 reg_x) (OpImm (ImmInt (32-shift))),+                  OR (OpReg W64 dst_reg) (OpReg W64 dst_reg) (OpReg W64 reg_x),+                  CLZ (OpReg W64 dst_reg) (OpReg W32 dst_reg)+                 ]+               )+      | otherwise -> unsupported (MO_Clz w)+      where+        shift = widthToInt w++    PrimTarget (MO_Ctz w)+      | w `elem` [W32, W64],+      [arg_reg] <- arg_regs,+      [dest_reg] <- dest_regs -> do+      platform <- getPlatform+      (reg_x, _format_x, code_x) <- getSomeReg arg_reg+      let dst_reg = getRegisterReg platform (CmmLocal dest_reg)+      return ( code_x `snocOL`+               CTZ (OpReg w dst_reg) (OpReg w reg_x)+             )+      | w `elem` [W8, W16],+      [arg_reg] <- arg_regs,+      [dest_reg] <- dest_regs -> do+      platform <- getPlatform+      (reg_x, _format_x, code_x) <- getSomeReg arg_reg+      let dst_reg = getRegisterReg platform (CmmLocal dest_reg)+      return ( code_x `appOL` toOL+               [+                MOV (OpReg W64 dst_reg) (OpImm (ImmInt 1)),+                SLL (OpReg W64 dst_reg) (OpReg W64 dst_reg) (OpImm (ImmInt shift)),+                BSTRPICK II64 (OpReg W64 reg_x) (OpReg W64 reg_x) (OpImm (ImmInt (shift-1))) (OpImm (ImmInt 0)),+                OR  (OpReg W64 dst_reg) (OpReg W64 dst_reg) (OpReg W64 reg_x),+                CTZ (OpReg W64 dst_reg) (OpReg W64 dst_reg)+               ]+             )+      | otherwise -> unsupported (MO_Ctz w)+      where+        shift = (widthToInt w)++    -- mop :: CallishMachOp (see GHC.Cmm.MachOp)+    PrimTarget mop -> do+      -- We'll need config to construct forien targets+      case mop of+        -- 64 bit float ops+        MO_F64_Pwr   -> mkCCall "pow"++        MO_F64_Sin   -> mkCCall "sin"+        MO_F64_Cos   -> mkCCall "cos"+        MO_F64_Tan   -> mkCCall "tan"++        MO_F64_Sinh  -> mkCCall "sinh"+        MO_F64_Cosh  -> mkCCall "cosh"+        MO_F64_Tanh  -> mkCCall "tanh"++        MO_F64_Asin  -> mkCCall "asin"+        MO_F64_Acos  -> mkCCall "acos"+        MO_F64_Atan  -> mkCCall "atan"++        MO_F64_Asinh -> mkCCall "asinh"+        MO_F64_Acosh -> mkCCall "acosh"+        MO_F64_Atanh -> mkCCall "atanh"++        MO_F64_Log   -> mkCCall "log"+        MO_F64_Log1P -> mkCCall "log1p"+        MO_F64_Exp   -> mkCCall "exp"+        MO_F64_ExpM1 -> mkCCall "expm1"++        -- 32 bit float ops+        MO_F32_Pwr   -> mkCCall "powf"++        MO_F32_Sin   -> mkCCall "sinf"+        MO_F32_Cos   -> mkCCall "cosf"+        MO_F32_Tan   -> mkCCall "tanf"+        MO_F32_Sinh  -> mkCCall "sinhf"+        MO_F32_Cosh  -> mkCCall "coshf"+        MO_F32_Tanh  -> mkCCall "tanhf"+        MO_F32_Asin  -> mkCCall "asinf"+        MO_F32_Acos  -> mkCCall "acosf"+        MO_F32_Atan  -> mkCCall "atanf"+        MO_F32_Asinh -> mkCCall "asinhf"+        MO_F32_Acosh -> mkCCall "acoshf"+        MO_F32_Atanh -> mkCCall "atanhf"+        MO_F32_Log   -> mkCCall "logf"+        MO_F32_Log1P -> mkCCall "log1pf"+        MO_F32_Exp   -> mkCCall "expf"+        MO_F32_ExpM1 -> mkCCall "expm1f"++        -- 64-bit primops+        MO_I64_ToI   -> mkCCall "hs_int64ToInt"+        MO_I64_FromI -> mkCCall "hs_intToInt64"+        MO_W64_ToW   -> mkCCall "hs_word64ToWord"+        MO_W64_FromW -> mkCCall "hs_wordToWord64"+        MO_x64_Neg   -> mkCCall "hs_neg64"+        MO_x64_Add   -> mkCCall "hs_add64"+        MO_x64_Sub   -> mkCCall "hs_sub64"+        MO_x64_Mul   -> mkCCall "hs_mul64"+        MO_I64_Quot  -> mkCCall "hs_quotInt64"+        MO_I64_Rem   -> mkCCall "hs_remInt64"+        MO_W64_Quot  -> mkCCall "hs_quotWord64"+        MO_W64_Rem   -> mkCCall "hs_remWord64"+        MO_x64_And   -> mkCCall "hs_and64"+        MO_x64_Or    -> mkCCall "hs_or64"+        MO_x64_Xor   -> mkCCall "hs_xor64"+        MO_x64_Not   -> mkCCall "hs_not64"+        MO_x64_Shl   -> mkCCall "hs_uncheckedShiftL64"+        MO_I64_Shr   -> mkCCall "hs_uncheckedIShiftRA64"+        MO_W64_Shr   -> mkCCall "hs_uncheckedShiftRL64"+        MO_x64_Eq    -> mkCCall "hs_eq64"+        MO_x64_Ne    -> mkCCall "hs_ne64"+        MO_I64_Ge    -> mkCCall "hs_geInt64"+        MO_I64_Gt    -> mkCCall "hs_gtInt64"+        MO_I64_Le    -> mkCCall "hs_leInt64"+        MO_I64_Lt    -> mkCCall "hs_ltInt64"+        MO_W64_Ge    -> mkCCall "hs_geWord64"+        MO_W64_Gt    -> mkCCall "hs_gtWord64"+        MO_W64_Le    -> mkCCall "hs_leWord64"+        MO_W64_Lt    -> mkCCall "hs_ltWord64"++        -- Conversion+        MO_UF_Conv w        -> mkCCall (word2FloatLabel w)++        -- Optional MachOps+        -- These are enabled/disabled by backend flags: GHC.StgToCmm.Config+        MO_S_Mul2     _w -> unsupported mop+        MO_S_QuotRem  _w -> unsupported mop+        MO_U_QuotRem  _w -> unsupported mop+        MO_U_QuotRem2 _w -> unsupported mop+        MO_Add2       _w -> unsupported mop+        MO_AddWordC   _w -> unsupported mop+        MO_SubWordC   _w -> unsupported mop+        MO_AddIntC    _w -> unsupported mop+        MO_SubIntC    _w -> unsupported mop+        MO_U_Mul2     _w -> unsupported mop++        MO_VS_Quot {} -> unsupported mop+        MO_VS_Rem {}  -> unsupported mop+        MO_VU_Quot {} -> unsupported mop+        MO_VU_Rem {}  -> unsupported mop+        MO_I64X2_Min -> unsupported mop+        MO_I64X2_Max -> unsupported mop+        MO_W64X2_Min -> unsupported mop+        MO_W64X2_Max -> unsupported mop++        -- Memory Ordering+        -- A hint value of 0 is mandatory by default, and it indicates a fully functional synchronization barrier.+        -- Only after all previous load/store access operations are completely executed, the DBAR 0 instruction can be executed;+        -- and only after the execution of DBAR 0 is completed, all subsequent load/store access operations can be executed.++        MO_AcquireFence -> pure (unitOL (DBAR Hint0))+        MO_ReleaseFence -> pure (unitOL (DBAR Hint0))+        MO_SeqCstFence  -> pure (unitOL (DBAR Hint0))++        MO_Touch        -> pure nilOL -- Keep variables live (when using interior pointers)+        -- Prefetch+        MO_Prefetch_Data _n -> pure nilOL -- Prefetch hint.++        -- Memory copy/set/move/cmp, with alignment for optimization++        -- TODO Optimize and use e.g. quad registers to move memory around instead+        -- of offloading this to memcpy. For small memcpys we can utilize+        -- the 128bit quad registers in NEON to move block of bytes around.+        -- Might also make sense of small memsets? Use xzr? What's the function+        -- call overhead?+        MO_Memcpy  _align   -> mkCCall "memcpy"+        MO_Memset  _align   -> mkCCall "memset"+        MO_Memmove _align   -> mkCCall "memmove"+        MO_Memcmp  _align   -> mkCCall "memcmp"++        MO_SuspendThread    -> mkCCall "suspendThread"+        MO_ResumeThread     -> mkCCall "resumeThread"++        MO_PopCnt w         -> mkCCall (popCntLabel w)+        MO_Pdep w           -> mkCCall (pdepLabel w)+        MO_Pext w           -> mkCCall (pextLabel w)+        MO_BSwap w          -> mkCCall (bSwapLabel w)+        MO_BRev w           -> mkCCall (bRevLabel w)++    -- or a possibly side-effecting machine operation+        mo@(MO_AtomicRead w ord)+          | [p_reg] <- arg_regs+          , [dst_reg] <- dest_regs -> do+              (p, _fmt_p, code_p) <- getSomeReg p_reg+              platform <- getPlatform+              let instrs = case ord of+                      MemOrderRelaxed -> unitOL $ ann moDescr (LD (intFormat w) (OpReg w dst) (OpAddr $ AddrReg p))++                      MemOrderAcquire -> toOL [+                                                ann moDescr (LD (intFormat w) (OpReg w dst) (OpAddr $ AddrReg p)),+                                                DBAR Hint0+                                              ]+                      MemOrderSeqCst -> toOL [+                                                ann moDescr (DBAR Hint0),+                                                LD (intFormat w) (OpReg w dst) (OpAddr $ AddrReg p),+                                                DBAR Hint0+                                              ]+                      _ -> panic $ "Unexpected MemOrderRelease on an AtomicRead: " ++ show mo+                  dst = getRegisterReg platform (CmmLocal dst_reg)+                  moDescr = (text . show) mo+                  code = code_p `appOL` instrs+              pure code+          | otherwise -> panic "mal-formed AtomicRead"++        mo@(MO_AtomicWrite w ord)+          | [p_reg, val_reg] <- arg_regs -> do+              (p, _fmt_p, code_p) <- getSomeReg p_reg+              (val, fmt_val, code_val) <- getSomeReg val_reg+              let instrs = case ord of+                      MemOrderRelaxed -> unitOL $ ann moDescr (ST fmt_val (OpReg w val) (OpAddr $ AddrReg p))+                      MemOrderRelease -> toOL [+                                                ann moDescr (DBAR Hint0),+                                                ST fmt_val (OpReg w val) (OpAddr $ AddrReg p)+                                              ]+                      MemOrderSeqCst  -> toOL [+                                                ann moDescr (DBAR Hint0),+                                                ST fmt_val (OpReg w val) (OpAddr $ AddrReg p),+                                                DBAR Hint0+                                              ]+                      _ ->  panic $ "Unexpected MemOrderAcquire on an AtomicWrite" ++ show mo+                  moDescr = (text . show) mo+                  code =+                    code_p `appOL`+                    code_val `appOL`+                    instrs+              pure code+          | otherwise -> panic "mal-formed AtomicWrite"++        MO_AtomicRMW w amop -> mkCCall (atomicRMWLabel w amop)+        MO_Cmpxchg w        -> mkCCall (cmpxchgLabel w)+        MO_Xchg w           -> mkCCall (xchgLabel w)++  where+    unsupported :: Show a => a -> b+    unsupported mop = panic ("outOfLineCmmOp: " ++ show mop+                          ++ " not supported here")++    mkCCall :: FastString -> NatM InstrBlock+    mkCCall name = do+      config <- getConfig+      target <-+        cmmMakeDynamicReference config CallReference+          $ mkForeignLabel name ForeignLabelInThisPackage IsFunction+      let cconv = ForeignConvention CCallConv [NoHint] [NoHint] CmmMayReturn+      genCCall (ForeignTarget target cconv) dest_regs arg_regs++    -- Implementiation of the LoongArch ABI calling convention.+    -- https://github.com/loongson/la-abi-specs/blob/release/lapcs.adoc#passing-arguments+    passArguments :: [Reg] -> [Reg] -> [(Reg, Format, ForeignHint, InstrBlock)] -> Int -> [Reg] -> InstrBlock -> NatM (Int, [Reg], InstrBlock)++    -- 1. Base case: no more arguments to pass (left)+    passArguments _ _ [] stackSpaceWords accumRegs accumCode = return (stackSpaceWords, accumRegs, accumCode)++    -- 2. Still have GP regs, and we want to pass an GP argument.+    passArguments (gpReg : gpRegs) fpRegs ((r, format, _hint, code_r) : args) stackSpaceWords accumRegs accumCode | isIntFormat format = do+      let w = formatToWidth format+          ext+            -- Specifically, LoongArch64's ABI requires that the caller+            -- sign-extend arguments which are smaller than 64-bits.+            | w `elem` [W8, W16, W32]+            = case w of+              W8  -> EXT (OpReg W64 gpReg) (OpReg w r)+              W16 -> EXT (OpReg W64 gpReg) (OpReg w r)+              W32 -> SLL (OpReg W64 gpReg) (OpReg w r) (OpImm (ImmInt 0))+              _ -> panic "Unexpected width(Here w < W64)!"+            | otherwise+            = MOV (OpReg w gpReg) (OpReg w r)+          accumCode' = accumCode `appOL`+                          code_r `snocOL`+                          ann (text "Pass gp argument: " <> ppr r) ext++      passArguments gpRegs fpRegs args stackSpaceWords (gpReg : accumRegs) accumCode'++    -- 3. Still have FP regs, and we want to pass an FP argument.+    passArguments gpRegs (fpReg : fpRegs) ((r, format, _hint, code_r) : args) stackSpaceWords accumRegs accumCode | isFloatFormat format = do+      let w = formatToWidth format+          mov = MOV (OpReg w fpReg) (OpReg w r)+          accumCode' = accumCode `appOL`+                       code_r `snocOL`+                       ann (text "Pass fp argument: " <> ppr r) mov++      passArguments gpRegs fpRegs args stackSpaceWords (fpReg : accumRegs) accumCode'++    -- 4. No mor regs left to pass. Must pass on stack.+    passArguments [] [] ((r, format, _hint, code_r) : args) stackSpaceWords accumRegs accumCode = do+      let w = formatToWidth format+          spOffet = 8 * stackSpaceWords+          str = ST format (OpReg w r) (OpAddr (AddrRegImm spMachReg (ImmInt spOffet)))+          stackCode =+            code_r+              `snocOL` (MOV (OpReg w tmpReg) (OpReg w r))+              `appOL` truncateReg w W64 tmpReg+              `snocOL` ann (text "Pass signed argument (size " <> ppr w <> text ") on the stack: " <> ppr tmpReg) str++      passArguments [] [] args (stackSpaceWords + 1) accumRegs (stackCode `appOL` accumCode)++    -- 5. Still have fpRegs left, but want to pass a GP argument. Must be passed on the stack then.+    passArguments [] fpRegs ((r, format, _hint, code_r) : args) stackSpaceWords accumRegs accumCode | isIntFormat format = do+      let w = formatToWidth format+          spOffet = 8 * stackSpaceWords+          str = ST format (OpReg w r) (OpAddr (AddrRegImm spMachReg (ImmInt spOffet)))+          stackCode =+            code_r+              `snocOL` ann (text "Pass argument (size " <> ppr w <> text ") on the stack: " <> ppr r) str++      passArguments [] fpRegs args (stackSpaceWords + 1) accumRegs (stackCode `appOL` accumCode)++   -- 6. Still have gpRegs left, but want to pass a FP argument. Must be passed in gpReg then.+    passArguments (gpReg : gpRegs) [] ((r, format, _hint, code_r) : args) stackSpaceWords accumRegs accumCode | isFloatFormat format = do+      let w = formatToWidth format+          mov = MOV (OpReg w gpReg) (OpReg w r)+          accumCode' = accumCode `appOL`+                       code_r `snocOL`+                       ann (text "Pass fp argument in gpReg: " <> ppr r) mov++      passArguments gpRegs [] args stackSpaceWords (gpReg : accumRegs) accumCode'+++    passArguments _ _ _ _ _ _ = pprPanic "passArguments" (text "invalid state")++    readResults :: [Reg] -> [Reg] -> [LocalReg] -> [Reg] -> InstrBlock -> NatM InstrBlock+    readResults _ _ [] _ accumCode = return accumCode+    readResults [] _ _ _ _ = do+      platform <- getPlatform+      pprPanic "genCCall, out of gp registers when reading results" (pdoc platform target)+    readResults _ [] _ _ _ = do+      platform <- getPlatform+      pprPanic "genCCall, out of fp registers when reading results" (pdoc platform target)+    readResults (gpReg:gpRegs) (fpReg:fpRegs) (dst:dsts) accumRegs accumCode = do+      -- gp/fp reg -> dst+      platform <- getPlatform+      let rep = cmmRegType (CmmLocal dst)+          format = cmmTypeFormat rep+          w = cmmRegWidth (CmmLocal dst)+          r_dst = getRegisterReg platform (CmmLocal dst)+      if isFloatFormat format+        then readResults (gpReg : gpRegs) fpRegs dsts (fpReg : accumRegs) (accumCode `snocOL` MOV (OpReg w r_dst) (OpReg w fpReg))+        else+          readResults gpRegs (fpReg : fpRegs) dsts (gpReg : accumRegs)+            $ accumCode+            `snocOL` MOV (OpReg w r_dst) (OpReg w gpReg)+            `appOL`+            -- truncate, otherwise an unexpectedly big value might be used in upfollowing calculations+            truncateReg W64 w r_dst++    unaryFloatOp w op arg_reg dest_reg = do+      platform <- getPlatform+      (reg_fx, _format_x, code_fx) <- getFloatReg arg_reg+      let dst = getRegisterReg platform (CmmLocal dest_reg)+      let code = code_fx `appOL` op (OpReg w dst) (OpReg w reg_fx)+      pure code++data BlockInRange = InRange | NotInRange BlockId++genCondFarJump :: (MonadGetUnique m) => Cond -> Operand -> Operand -> BlockId -> m InstrBlock+genCondFarJump cond op1 op2 far_target = do+  return $ toOL [ ann (text "Conditional far jump to: " <> ppr far_target)+                $ BCOND cond op1 op2 (TBlock far_target)+                ]++makeFarBranches ::+  Platform ->+  LabelMap RawCmmStatics ->+  [NatBasicBlock Instr] ->+  UniqDSM [NatBasicBlock Instr]++makeFarBranches {- only used when debugging -} _platform statics basic_blocks = do+  -- All offsets/positions are counted in multiples of 4 bytes (the size of LoongArch64 instructions)+  -- That is an offset of 1 represents a 4-byte/one instruction offset.+  let (func_size, lblMap) = foldl' calc_lbl_positions (0, mapEmpty) basic_blocks+  if func_size < max_cond_jump_dist+    then pure basic_blocks+    else do+      (_, blocks) <- mapAccumLM (replace_blk lblMap) 0 basic_blocks+      pure $ concat blocks+  where+    max_cond_jump_dist = 2 ^ (15 :: Int) - 8 :: Int+    -- Currently all inline info tables fit into 64 bytes.+    max_info_size = 16 :: Int+    long_bc_jump_dist = 2 :: Int++    -- Replace out of range conditional jumps with unconditional jumps.+    replace_blk :: LabelMap Int -> Int -> GenBasicBlock Instr -> UniqDSM (Int, [GenBasicBlock Instr])+    replace_blk !m !pos (BasicBlock lbl instrs) = do+      -- Account for a potential info table before the label.+      let !block_pos = pos + infoTblSize_maybe lbl+      (!pos', instrs') <- mapAccumLM (replace_jump m) block_pos instrs+      let instrs'' = concat instrs'+      -- We might have introduced new labels, so split the instructions into basic blocks again if neccesary.+      let (top, split_blocks, no_data) = foldr mkBlocks ([], [], []) instrs''+      -- There should be no data in the instruction stream at this point+      massert (null no_data)++      let final_blocks = BasicBlock lbl top : split_blocks+      pure (pos', final_blocks)++    replace_jump :: LabelMap Int -> Int -> Instr -> UniqDSM (Int, [Instr])+    replace_jump !m !pos instr = do+      case instr of+        ANN ann instr -> do+          replace_jump m pos instr >>= \case+            (idx, instr' : instrs') -> pure (idx, ANN ann instr' : instrs')+            (idx, []) -> pprPanic "replace_jump" (text "empty return list for " <+> ppr idx)++        BCOND1 cond op1 op2 t ->+          case target_in_range m t pos of+            InRange -> pure (pos + 1, [instr])+            NotInRange far_target -> do+              jmp_code <- genCondFarJump cond op1 op2 far_target+              pure (pos + long_bc_jump_dist, fromOL jmp_code)++        _ -> pure (pos + instr_size instr, [instr])++    target_in_range :: LabelMap Int -> Target -> Int -> BlockInRange+    target_in_range m target src =+      case target of+        (TReg{}) -> InRange+        (TBlock bid) -> block_in_range m src bid+        (TLabel clbl)+          | Just bid <- maybeLocalBlockLabel clbl+          -> block_in_range m src bid+          | otherwise+          -> InRange++    block_in_range :: LabelMap Int -> Int -> BlockId -> BlockInRange+    block_in_range m src_pos dest_lbl =+      case mapLookup dest_lbl m of+        Nothing ->+          pprTrace "not in range" (ppr dest_lbl) $ NotInRange dest_lbl+        Just dest_pos ->+          if abs (dest_pos - src_pos) < max_cond_jump_dist+            then InRange+          else NotInRange dest_lbl++    calc_lbl_positions :: (Int, LabelMap Int) -> GenBasicBlock Instr -> (Int, LabelMap Int)+    calc_lbl_positions (pos, m) (BasicBlock lbl instrs) =+      let !pos' = pos + infoTblSize_maybe lbl+       in foldl' instr_pos (pos', mapInsert lbl pos' m) instrs++    instr_pos :: (Int, LabelMap Int) -> Instr -> (Int, LabelMap Int)+    instr_pos (pos, m) instr = (pos + instr_size instr, m)++    infoTblSize_maybe bid =+      case mapLookup bid statics of+        Nothing -> 0 :: Int+        Just _info_static -> max_info_size++    instr_size :: Instr -> Int+    instr_size i = case i of+      COMMENT {} -> 0+      MULTILINE_COMMENT {} -> 0+      ANN _ instr -> instr_size instr+      LOCATION {} -> 0+      DELTA {} -> 0+      -- At this point there should be no NEWBLOCK in the instruction stream (pos, mapInsert bid pos m)+      NEWBLOCK {} -> panic "mkFarBranched - Unexpected"+      LDATA {} -> panic "mkFarBranched - Unexpected"+      PUSH_STACK_FRAME -> 4+      POP_STACK_FRAME -> 4+      CSET {} -> 2+      LD _ _ (OpImm (ImmIndex _ _)) -> 3+      LD _ _ (OpImm (ImmCLbl _)) -> 2+      SCVTF {} -> 2+      FCVTZS {} -> 4+      BCOND {} -> long_bc_jump_dist+      CALL (TReg _) _ -> 1+      CALL {} -> 2+      CALL36 {} -> 2+      TAIL36 {} -> 2+      _ -> 1
+ GHC/CmmToAsm/LA64/Cond.hs view
@@ -0,0 +1,33 @@+module GHC.CmmToAsm.LA64.Cond where++import GHC.Prelude hiding (EQ)++-- | Condition codes.+-- Used in conditional branches and bit setters. According to the available+-- instruction set, some conditions are encoded as their negated opposites. I.e.+-- these are logical things that don't necessarily map 1:1 to hardware/ISA.+-- TODO: Maybe need to simplify or expand?+data Cond+-- ISA condition+  = EQ  -- beq+  | NE  -- bne+  | LT  -- blt+  | GE  -- bge+  | LTU  -- bltu+  | GEU  -- bgeu+  | EQZ  -- beqz+  | NEZ  -- bnez+-- Extra Logical condition+  | SLT -- LT+  | SLE+  | SGE -- GE+  | SGT+  | ULT -- LTU+  | ULE+  | UGE -- GEU+  | UGT+  | FLT+  | FLE+  | FGE+  | FGT+  deriving (Eq, Show)
+ GHC/CmmToAsm/LA64/Instr.hs view
@@ -0,0 +1,1012 @@+{-# OPTIONS_GHC -fno-warn-orphans #-}++module GHC.CmmToAsm.LA64.Instr where++import GHC.Prelude++import GHC.CmmToAsm.LA64.Cond+import GHC.CmmToAsm.LA64.Regs++import GHC.CmmToAsm.Instr (RegUsage(..))+import GHC.CmmToAsm.Format+import GHC.CmmToAsm.Types+import GHC.CmmToAsm.Utils+import GHC.CmmToAsm.Config+import GHC.Platform.Reg++import GHC.Platform.Regs+import GHC.Platform.Reg.Class.Separate+import GHC.Cmm.BlockId+import GHC.Cmm.Dataflow.Label+import GHC.Cmm+import GHC.Cmm.CLabel+import GHC.Utils.Outputable+import GHC.Platform+import GHC.Types.Unique.DSM++import GHC.Utils.Panic+import Data.Maybe+import GHC.Stack+import GHC.Data.FastString (LexicalFastString)++-- | Stack frame header size+-- Each stack frame contains ra and fp -- prologue.+stackFrameHeaderSize :: Int+stackFrameHeaderSize = 2 * spillSlotSize++-- | All registers are 8 byte wide.+spillSlotSize :: Int+spillSlotSize = 8++-- | The number of bytes that the stack pointer should be aligned to.+stackAlign :: Int+stackAlign = 16++-- | The number of spill slots available without allocating more.+maxSpillSlots :: NCGConfig -> Int+maxSpillSlots config+    = (+        (ncgSpillPreallocSize config - stackFrameHeaderSize)+         `div`+         spillSlotSize+      ) - 1++-- | Convert a spill slot number to a *byte* offset.+spillSlotToOffset :: Int -> Int+spillSlotToOffset slot+   = stackFrameHeaderSize + spillSlotSize * slot++instance Outputable RegUsage where+    ppr (RU reads writes) = text "RegUsage(reads:" <+> ppr reads <> comma <+> text "writes:" <+> ppr writes <> char ')'++-- | Get the registers that are being used by this instruction.+-- regUsage doesn't need to do any trickery for jumps and such.+-- Just state precisely the regs read and written by that insn.+-- The consequences of control flow transfers, as far as register+-- allocation goes, are taken care of by the register allocator.+--+-- RegUsage = RU [<read regs>] [<write regs>]+regUsageOfInstr :: Platform -> Instr -> RegUsage+regUsageOfInstr platform instr = case instr of+  -- Pseudo Instructions+  ANN _ i                  -> regUsageOfInstr platform i+  COMMENT{}                -> usage ([], [])+  MULTILINE_COMMENT{}      -> usage ([], [])+  PUSH_STACK_FRAME         -> usage ([], [])+  POP_STACK_FRAME          -> usage ([], [])+  DELTA{}                  -> usage ([], [])+  LOCATION{}               -> usage ([], [])++  -- 1. Arithmetic Instructions ------------------------------------------------+  ADD dst src1 src2        -> usage (regOp src1 ++ regOp src2, regOp dst)+  SUB dst src1 src2        -> usage (regOp src1 ++ regOp src2, regOp dst)+  ALSL dst src1 src2 src3  -> usage (regOp src1 ++ regOp src2 ++ regOp src3, regOp dst)+  ALSLU dst src1 src2 src3 -> usage (regOp src1 ++ regOp src2 ++ regOp src3, regOp dst)+  LU12I dst src1           -> usage (regOp src1, regOp dst)+  LU32I dst src1           -> usage (regOp src1, regOp dst)+  LU52I dst src1 src2      -> usage (regOp src1 ++ regOp src2, regOp dst)+  SSLT dst src1 src2       -> usage (regOp src1 ++ regOp src2, regOp dst)+  SSLTU dst src1 src2      -> usage (regOp src1 ++ regOp src2, regOp dst)+  PCADDI dst src1          -> usage (regOp src1, regOp dst)+  PCADDU12I dst src1       -> usage (regOp src1, regOp dst)+  PCADDU18I dst src1       -> usage (regOp src1, regOp dst)+  PCALAU12I dst src1       -> usage (regOp src1, regOp dst)+  AND dst src1 src2        -> usage (regOp src1 ++ regOp src2, regOp dst)+  OR dst src1 src2         -> usage (regOp src1 ++ regOp src2, regOp dst)+  XOR dst src1 src2        -> usage (regOp src1 ++ regOp src2, regOp dst)+  NOR dst src1 src2        -> usage (regOp src1 ++ regOp src2, regOp dst)+  ANDN dst src1 src2       -> usage (regOp src1 ++ regOp src2, regOp dst)+  ORN dst src1 src2        -> usage (regOp src1 ++ regOp src2, regOp dst)+  MUL dst src1 src2        -> usage (regOp src1 ++ regOp src2, regOp dst)+  MULW dst src1 src2       -> usage (regOp src1 ++ regOp src2, regOp dst)+  MULWU dst src1 src2      -> usage (regOp src1 ++ regOp src2, regOp dst)+  MULH dst src1 src2       -> usage (regOp src1 ++ regOp src2, regOp dst)+  MULHU dst src1 src2      -> usage (regOp src1 ++ regOp src2, regOp dst)+  DIV dst src1 src2        -> usage (regOp src1 ++ regOp src2, regOp dst)+  DIVU dst src1 src2       -> usage (regOp src1 ++ regOp src2, regOp dst)+  MOD dst src1 src2        -> usage (regOp src1 ++ regOp src2, regOp dst)+  MODU dst src1 src2       -> usage (regOp src1 ++ regOp src2, regOp dst)+  -- 2. Bit-shift Instructions ------------------------------------------+  SLL dst src1 src2        -> usage (regOp src1 ++ regOp src2, regOp dst)+  SRL dst src1 src2        -> usage (regOp src1 ++ regOp src2, regOp dst)+  SRA dst src1 src2        -> usage (regOp src1 ++ regOp src2, regOp dst)+  ROTR dst src1 src2       -> usage (regOp src1 ++ regOp src2, regOp dst)+  -- 3. Bit Manipulation Instructions ------------------------------------------+  EXT dst src1             -> usage (regOp src1, regOp dst)+  CLO dst src1             -> usage (regOp src1, regOp dst)+  CLZ dst src1             -> usage (regOp src1, regOp dst)+  CTO dst src1             -> usage (regOp src1, regOp dst)+  CTZ dst src1             -> usage (regOp src1, regOp dst)+  BYTEPICK dst src1 src2 src3 -> usage (regOp src1 ++ regOp src2 ++ regOp src3, regOp dst)+  REVB2H dst src1          -> usage (regOp src1, regOp dst)+  REVB4H dst src1          -> usage (regOp src1, regOp dst)+  REVB2W dst src1          -> usage (regOp src1, regOp dst)+  REVBD  dst src1          -> usage (regOp src1, regOp dst)+  REVH2W dst src1          -> usage (regOp src1, regOp dst)+  REVHD  dst src1          -> usage (regOp src1, regOp dst)+  BITREV4B dst src1        -> usage (regOp src1, regOp dst)+  BITREV8B dst src1        -> usage (regOp src1, regOp dst)+  BITREVW dst src1         -> usage (regOp src1, regOp dst)+  BITREVD dst src1         -> usage (regOp src1, regOp dst)+  BSTRINS _ dst src1 src2 src3  -> usage (regOp src1 ++ regOp src2 ++ regOp src3, regOp dst)+  BSTRPICK _ dst src1 src2 src3 -> usage (regOp src1 ++ regOp src2 ++ regOp src3, regOp dst)+  MASKEQZ dst src1 src2         -> usage (regOp src1 ++ regOp src2, regOp dst)+  MASKNEZ dst src1 src2         -> usage (regOp src1 ++ regOp src2, regOp dst)+  --+  -- Pseudo instructions+  NOP                      -> usage ([], [])+  MOV dst src              -> usage (regOp src, regOp dst)+  NEG dst src              -> usage (regOp src, regOp dst)+  CSET _cond dst src1 src2  -> usage (regOp src1 ++ regOp src2 , regOp dst)+  -- 4. Branch Instructions ----------------------------------------------------+  J t                      -> usage (regTarget t, [])+  J_TBL _ _ t              -> usage ([t], [])+  B t                      -> usage (regTarget t, [])+  BL t ps                  -> usage (regTarget t ++ ps, callerSavedRegisters)+  CALL t ps                -> usage (regTarget t ++ ps, callerSavedRegisters)+  CALL36 t                 -> usage (regTarget t, [])+  TAIL36 r t               -> usage (regTarget t, regOp r)+  -- Here two kinds of BCOND and BCOND1 are implemented, mainly because we want+  -- to distinguish between two kinds of conditional jumps with different jump+  -- ranges, corresponding to 2 and 1 instruction implementations respectively.+  --+  -- BCOND1 is selected by default.+  BCOND1 _ j d t           -> usage (regTarget t ++ regOp j ++ regOp d, [])+  BCOND _ j d t            -> usage (regTarget t ++ regOp j ++ regOp d, [])+  BEQZ j t                 -> usage (regTarget t ++ regOp j, [])+  BNEZ j t                 -> usage (regTarget t ++ regOp j, [])+  -- 5. Common Memory Access Instructions --------------------------------------+  LD _ dst src             -> usage (regOp src, regOp dst)+  LDU _ dst src            -> usage (regOp src, regOp dst)+  ST _ dst src             -> usage (regOp src ++ regOp dst, [])+  LDX _ dst src            -> usage (regOp src, regOp dst)+  LDXU _ dst src           -> usage (regOp src, regOp dst)+  STX _ dst src            -> usage (regOp src ++ regOp dst, [])+  LDPTR _ dst src          -> usage (regOp src, regOp dst)+  STPTR _ dst src          -> usage (regOp src ++ regOp dst, [])+  PRELD _hint src          -> usage (regOp src, [])+  -- 6. Bound Check Memory Access Instructions ---------------------------------+  -- LDCOND dst src1 src2     -> usage (regOp src1 ++ regOp src2, regOp dst)+  -- STCOND dst src1 src2     -> usage (regOp src1 ++ regOp src2, regOp dst)+  -- 7. Atomic Memory Access Instructions --------------------------------------+  -- 8. Barrier Instructions ---------------------------------------------------+  DBAR _hint               -> usage ([], [])+  IBAR _hint               -> usage ([], [])+  -- 11. Floating Point Instructions -------------------------------------------+  FMAX dst src1 src2       -> usage (regOp src1 ++ regOp src2, regOp dst)+  FMIN dst src1 src2       -> usage (regOp src1 ++ regOp src2, regOp dst)+  FMAXA dst src1 src2      -> usage (regOp src1 ++ regOp src2, regOp dst)+  FMINA dst src1 src2      -> usage (regOp src1 ++ regOp src2, regOp dst)+  FNEG dst src1            -> usage (regOp src1, regOp dst)++  FCVT dst src             -> usage (regOp src, regOp dst)+  -- SCVTF dst src            -> usage (regOp src, regOp src ++ regOp dst)+  SCVTF dst src            -> usage (regOp src, regOp dst)+  FCVTZS dst src1 src2     -> usage (regOp src2, regOp src1 ++ regOp dst)+  FABS dst src             -> usage (regOp src, regOp dst)+  FSQRT dst src            -> usage (regOp src, regOp dst)+  FMA _ dst src1 src2 src3 -> usage (regOp src1 ++ regOp src2 ++ regOp src3, regOp dst)++  _ -> panic $ "regUsageOfInstr: " ++ instrCon instr++  where+        -- filtering the usage is necessary, otherwise the register+        -- allocator will try to allocate pre-defined fixed stg+        -- registers as well, as they show up.+        usage :: ([Reg], [Reg]) -> RegUsage+        usage (srcRegs, dstRegs) =+          RU+            (map mkFmt $ filter (interesting platform) srcRegs)+            (map mkFmt $ filter (interesting platform) dstRegs)++        mkFmt r = RegWithFormat r fmt+          where+            fmt = case cls of+              RcInteger -> II64+              RcFloat   -> FF64+              RcVector  -> sorry "The LoongArch64 NCG does not (yet) support vectors; please use -fllvm."+            cls = case r of+              RegVirtual vr -> classOfVirtualReg (platformArch platform) vr+              RegReal rr -> classOfRealReg rr++        regAddr :: AddrMode -> [Reg]+        regAddr (AddrRegReg r1 r2) = [r1, r2]+        regAddr (AddrRegImm r1 _)  = [r1]+        regAddr (AddrReg r1)       = [r1]++        regOp :: Operand -> [Reg]+        regOp (OpReg _ r1) = [r1]+        regOp (OpAddr a)    = regAddr a+        regOp (OpImm _)     = []++        regTarget :: Target -> [Reg]+        regTarget (TBlock _) = []+        regTarget (TLabel _) = []+        regTarget (TReg r1)  = [r1]++        -- Is this register interesting for the register allocator?+        interesting :: Platform -> Reg -> Bool+        interesting _        (RegVirtual _)                 = True+        interesting platform (RegReal (RealRegSingle i))    = freeReg platform i++-- | Caller-saved registers (according to calling convention)+--------------------------------------------------------------------------------------------------------------------------------------------------------------------+-- |  0 |  1 |  2 |  3 |  4 |  5 |  6 |  7 |  8 |  9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 |+--------------------------------------------------------------------------------------------------------------------------------------------------------------------+-- |zero| ra | tp | sp | a0 | a1 | a2 | a3 | a4 | a5 | a6 | a7 | t0 | t1 | t2 | t3 | t4 | t5 | t6 | t7 | t8 | Rv | fp | s0 | s1 | s2 | s3 | s4 | s5 | s6 | s7 | s8 |+--------------------------------------------------------------------------------------------------------------------------------------------------------------------+-- | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 42 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 |+--------------------------------------------------------------------------------------------------------------------------------------------------------------------+--f| a0 | a1 | a2 | a3 | a4 | a5 | a6 | a7 | t0 | t1 | t2 | t3 | t4 | t5 | t6 | t7 | t8 | t9 | t10| t11| t12| t13| t14| t15| s0 | s1 | s2 | s3 | s4 | s5 | s6 | s7 |+--------------------------------------------------------------------------------------------------------------------------------------------------------------------+callerSavedRegisters :: [Reg]+callerSavedRegisters =+    -- TODO: Not sure.+    [regSingle 1]                 -- ra+    ++ map regSingle [4 .. 11]    -- a0 - a7+    ++ map regSingle [12 .. 20]   -- t0 - t8+    ++ map regSingle [32 .. 39]   -- fa0 - fa7+    ++ map regSingle [40 .. 55]   -- ft0 - ft15++-- | Apply a given mapping to all the register references in this instruction.+patchRegsOfInstr :: Instr -> (Reg -> Reg) -> Instr+patchRegsOfInstr instr env = case instr of+    -- 0. Meta Instructions+    ANN d i             -> ANN d (patchRegsOfInstr i env)+    COMMENT{}           -> instr+    MULTILINE_COMMENT{} -> instr+    PUSH_STACK_FRAME    -> instr+    POP_STACK_FRAME     -> instr+    DELTA{}             -> instr+    LOCATION{}          -> instr+    -- 1. Arithmetic Instructions ------------------------------------------------+    ADD o1 o2 o3        -> ADD  (patchOp o1)  (patchOp o2)  (patchOp o3)+    SUB o1 o2 o3        -> SUB  (patchOp o1)  (patchOp o2)  (patchOp o3)+    ALSL o1 o2 o3 o4    -> ALSL  (patchOp o1)  (patchOp o2)  (patchOp o3)  (patchOp o4)+    ALSLU o1 o2 o3 o4   -> ALSLU (patchOp o1)  (patchOp o2)  (patchOp o3)  (patchOp o4)+    LU12I o1 o2         -> LU12I  (patchOp o1)  (patchOp o2)+    LU32I o1 o2         -> LU32I  (patchOp o1)  (patchOp o2)+    LU52I o1 o2 o3      -> LU52I  (patchOp o1)  (patchOp o2)  (patchOp o3)+    SSLT o1 o2 o3       -> SSLT  (patchOp o1)  (patchOp o2)  (patchOp o3)+    SSLTU o1 o2 o3      -> SSLTU  (patchOp o1)  (patchOp o2)  (patchOp o3)+    PCADDI o1 o2        -> PCADDI  (patchOp o1)  (patchOp o2)+    PCADDU12I o1 o2     -> PCADDU12I  (patchOp o1)  (patchOp o2)+    PCADDU18I o1 o2     -> PCADDU18I  (patchOp o1)  (patchOp o2)+    PCALAU12I o1 o2     -> PCALAU12I  (patchOp o1)  (patchOp o2)+    AND o1 o2 o3        -> AND  (patchOp o1)  (patchOp o2)  (patchOp o3)+    OR o1 o2 o3         -> OR  (patchOp o1)  (patchOp o2)  (patchOp o3)+    XOR o1 o2 o3        -> XOR  (patchOp o1)  (patchOp o2)  (patchOp o3)+    NOR o1 o2 o3        -> NOR  (patchOp o1)  (patchOp o2)  (patchOp o3)+    ANDN o1 o2 o3       -> ANDN  (patchOp o1)  (patchOp o2)  (patchOp o3)+    ORN o1 o2 o3        -> ORN  (patchOp o1)  (patchOp o2)  (patchOp o3)+    MUL o1 o2 o3        -> MUL  (patchOp o1)  (patchOp o2)  (patchOp o3)+    MULW o1 o2 o3       -> MULW  (patchOp o1)  (patchOp o2)  (patchOp o3)+    MULWU o1 o2 o3      -> MULWU (patchOp o1)  (patchOp o2)  (patchOp o3)+    MULH o1 o2 o3       -> MULH  (patchOp o1)  (patchOp o2)  (patchOp o3)+    MULHU o1 o2 o3      -> MULHU  (patchOp o1)  (patchOp o2)  (patchOp o3)+    DIV o1 o2 o3        -> DIV  (patchOp o1)  (patchOp o2)  (patchOp o3)+    MOD o1 o2 o3        -> MOD  (patchOp o1)  (patchOp o2)  (patchOp o3)+    DIVU o1 o2 o3       -> DIVU  (patchOp o1)  (patchOp o2)  (patchOp o3)+    MODU o1 o2 o3       -> MODU  (patchOp o1)  (patchOp o2)  (patchOp o3)+    -- 2. Bit-shift Instructions ------------------------------------------+    SLL o1 o2 o3        -> SLL  (patchOp o1)  (patchOp o2)  (patchOp o3)+    SRL o1 o2 o3        -> SRL  (patchOp o1)  (patchOp o2)  (patchOp o3)+    SRA o1 o2 o3        -> SRA  (patchOp o1)  (patchOp o2)  (patchOp o3)+    ROTR o1 o2 o3       -> ROTR  (patchOp o1)  (patchOp o2)  (patchOp o3)+    -- 3. Bit Manipulation Instructions ------------------------------------------+    EXT o1 o2             -> EXT  (patchOp o1)  (patchOp o2)+    CLO o1 o2             -> CLO  (patchOp o1)  (patchOp o2)+    CLZ o1 o2             -> CLZ  (patchOp o1)  (patchOp o2)+    CTO o1 o2             -> CTO  (patchOp o1)  (patchOp o2)+    CTZ o1 o2             -> CTZ  (patchOp o1)  (patchOp o2)+    BYTEPICK o1 o2 o3 o4  -> BYTEPICK  (patchOp o1)  (patchOp o2) (patchOp o3) (patchOp o4)+    REVB2H o1 o2          -> REVB2H  (patchOp o1)  (patchOp o2)+    REVB4H o1 o2          -> REVB4H  (patchOp o1)  (patchOp o2)+    REVB2W o1 o2          -> REVB2W  (patchOp o1)  (patchOp o2)+    REVBD  o1 o2          -> REVBD  (patchOp o1)  (patchOp o2)+    REVH2W o1 o2          -> REVH2W  (patchOp o1)  (patchOp o2)+    REVHD  o1 o2          -> REVHD  (patchOp o1)  (patchOp o2)+    BITREV4B o1 o2         -> BITREV4B  (patchOp o1)  (patchOp o2)+    BITREV8B o1 o2         -> BITREV8B  (patchOp o1)  (patchOp o2)+    BITREVW o1 o2          -> BITREVW  (patchOp o1)  (patchOp o2)+    BITREVD o1 o2          -> BITREVD  (patchOp o1)  (patchOp o2)+    BSTRINS f o1 o2 o3 o4  -> BSTRINS f (patchOp o1)  (patchOp o2)  (patchOp o3)  (patchOp o4)+    BSTRPICK f o1 o2 o3 o4 -> BSTRPICK f (patchOp o1)  (patchOp o2)  (patchOp o3)  (patchOp o4)+    MASKEQZ o1 o2 o3       -> MASKEQZ  (patchOp o1)  (patchOp o2)  (patchOp o3)+    MASKNEZ o1 o2 o3       -> MASKNEZ  (patchOp o1)  (patchOp o2)  (patchOp o3)+    --+    -- Pseudo instrcutions+    NOP                 -> NOP+    MOV o1 o2           -> MOV  (patchOp o1)  (patchOp o2)+    NEG o1 o2           -> NEG  (patchOp o1)  (patchOp o2)+    CSET cond o1 o2 o3  -> CSET cond (patchOp o1) (patchOp o2) (patchOp o3)+    -- 4. Branch Instructions ----------------------------------------------------+    -- TODO:+    J t            -> J (patchTarget t)+    J_TBL ids mbLbl t  -> J_TBL ids mbLbl (env t)+    B t            -> B (patchTarget t)+    BL t ps        -> BL (patchTarget t) ps+    CALL t ps      -> CALL (patchTarget t) ps+    CALL36 t       -> CALL36 (patchTarget t)+    TAIL36 r t     -> TAIL36 (patchOp r) (patchTarget t)+    BCOND1 c j d t -> BCOND1 c (patchOp j) (patchOp d) (patchTarget t)+    BCOND c j d t  -> BCOND c (patchOp j) (patchOp d) (patchTarget t)+    BEQZ j t       -> BEQZ (patchOp j) (patchTarget t)+    BNEZ j t       -> BNEZ (patchOp j) (patchTarget t)+    -- 5. Common Memory Access Instructions --------------------------------------+    -- TODO:+    LD f o1 o2         -> LD f (patchOp o1)  (patchOp o2)+    LDU f o1 o2        -> LDU f (patchOp o1)  (patchOp o2)+    ST f o1 o2         -> ST f (patchOp o1)  (patchOp o2)+    LDX f o1 o2        -> LDX f (patchOp o1)  (patchOp o2)+    LDXU f o1 o2       -> LDXU f (patchOp o1)  (patchOp o2)+    STX f o1 o2        -> STX f (patchOp o1)  (patchOp o2)+    LDPTR f o1 o2      -> LDPTR f (patchOp o1)  (patchOp o2)+    STPTR f o1 o2      -> STPTR f (patchOp o1)  (patchOp o2)+    PRELD o1 o2         -> PRELD (patchOp o1) (patchOp o2)+    -- 6. Bound Check Memory Access Instructions ---------------------------------+    -- LDCOND o1 o2 o3       -> LDCOND  (patchOp o1)  (patchOp o2)  (patchOp o3)+    -- STCOND o1 o2 o3       -> STCOND  (patchOp o1)  (patchOp o2)  (patchOp o3)+    -- 7. Atomic Memory Access Instructions --------------------------------------+    -- 8. Barrier Instructions ---------------------------------------------------+    -- TODO: need fix+    DBAR o1             -> DBAR o1+    IBAR o1             -> IBAR o1+    -- 11. Floating Point Instructions -------------------------------------------+    FCVT o1 o2          -> FCVT  (patchOp o1)  (patchOp o2)+    SCVTF o1 o2         -> SCVTF  (patchOp o1)  (patchOp o2)+    FCVTZS o1 o2 o3     -> FCVTZS  (patchOp o1)  (patchOp o2) (patchOp o3)+    FMIN o1 o2 o3       -> FMIN  (patchOp o1)  (patchOp o2)  (patchOp o3)+    FMAX o1 o2 o3       -> FMAX  (patchOp o1)  (patchOp o2)  (patchOp o3)+    FMINA o1 o2 o3      -> FMINA  (patchOp o1)  (patchOp o2)  (patchOp o3)+    FMAXA o1 o2 o3      -> FMAXA  (patchOp o1)  (patchOp o2)  (patchOp o3)+    FNEG o1 o2          -> FNEG  (patchOp o1)  (patchOp o2)+    FABS o1 o2          -> FABS  (patchOp o1)  (patchOp o2)+    FSQRT o1 o2         -> FSQRT  (patchOp o1)  (patchOp o2)+    FMA s o1 o2 o3 o4   -> FMA s (patchOp o1)  (patchOp o2)  (patchOp o3)  (patchOp o4)++    _                   -> panic $ "patchRegsOfInstr: " ++ instrCon instr+    where+        -- TODO:+        patchOp :: Operand -> Operand+        patchOp (OpReg w r) = OpReg w (env r)+        patchOp (OpAddr a) = OpAddr (patchAddr a)+        patchOp opImm = opImm++        patchTarget :: Target -> Target+        patchTarget (TReg r) = TReg (env r)+        patchTarget t = t++        patchAddr :: AddrMode -> AddrMode+        patchAddr (AddrRegReg r1 r2)  = AddrRegReg (env r1) (env r2)+        patchAddr (AddrRegImm r1 imm) = AddrRegImm (env r1) imm+        patchAddr (AddrReg r) = AddrReg (env r)++--------------------------------------------------------------------------------++-- | Checks whether this instruction is a jump/branch instruction.+-- One that can change the flow of control in a way that the+-- register allocator needs to worry about.+isJumpishInstr :: Instr -> Bool+isJumpishInstr instr = case instr of+  ANN _ i -> isJumpishInstr i+  J {} -> True+  J_TBL {} -> True+  B {} -> True+  BL {} -> True+  CALL {} -> True+  CALL36 {} -> True+  TAIL36 {} -> True+  BCOND1 {} -> True+  BCOND {} -> True+  BEQZ {} -> True+  BNEZ {} -> True+  _ -> False++-- | Get the `BlockId`s of the jump destinations (if any)+jumpDestsOfInstr :: Instr -> [BlockId]+jumpDestsOfInstr (ANN _ i) = jumpDestsOfInstr i+jumpDestsOfInstr (J t) = [id | TBlock id <- [t]]+jumpDestsOfInstr (J_TBL ids _mbLbl _r) = catMaybes ids+jumpDestsOfInstr (B t) = [id | TBlock id <- [t]]+jumpDestsOfInstr (BL t _) = [id | TBlock id <- [t]]+jumpDestsOfInstr (CALL t _) = [id | TBlock id <- [t]]+jumpDestsOfInstr (CALL36 t) = [id | TBlock id <- [t]]+jumpDestsOfInstr (TAIL36 _ t) = [id | TBlock id <- [t]]+jumpDestsOfInstr (BCOND1 _ _ _ t) = [id | TBlock id <- [t]]+jumpDestsOfInstr (BCOND _ _ _ t) = [id | TBlock id <- [t]]+jumpDestsOfInstr (BEQZ _ t) = [id | TBlock id <- [t]]+jumpDestsOfInstr (BNEZ _ t) = [id | TBlock id <- [t]]+jumpDestsOfInstr _ = []++-- | Change the destination of this (potential) jump instruction.+-- Used in the linear allocator when adding fixup blocks for join+-- points.+patchJumpInstr :: Instr -> (BlockId -> BlockId) -> Instr+patchJumpInstr instr patchF =+  case instr of+    ANN d i -> ANN d (patchJumpInstr i patchF)+    J (TBlock bid) -> J (TBlock (patchF bid))+    J_TBL ids mbLbl r -> J_TBL (map (fmap patchF) ids) mbLbl r+    B (TBlock bid) -> B (TBlock (patchF bid))+    BL (TBlock bid) ps -> BL (TBlock (patchF bid)) ps+    CALL (TBlock bid) ps -> CALL (TBlock (patchF bid)) ps+    CALL36 (TBlock bid) -> CALL36 (TBlock (patchF bid))+    TAIL36 r (TBlock bid) -> TAIL36 r (TBlock (patchF bid))+    BCOND1 c o1 o2 (TBlock bid) -> BCOND1 c o1 o2 (TBlock (patchF bid))+    BCOND c o1 o2 (TBlock bid) -> BCOND c o1 o2 (TBlock (patchF bid))+    BEQZ j (TBlock bid) -> BEQZ j (TBlock (patchF bid))+    BNEZ j (TBlock bid) -> BNEZ j (TBlock (patchF bid))+    _ -> panic $ "patchJumpInstr: " ++ instrCon instr++-- -----------------------------------------------------------------------------+-- | Make a spill instruction, spill a register into spill slot.+mkSpillInstr+   :: HasCallStack+   => NCGConfig+   -> RegWithFormat -- register to spill+   -> Int       -- current stack delta+   -> Int       -- spill slot to use+   -> [Instr]++mkSpillInstr _config (RegWithFormat reg _fmt) delta slot =+  case off - delta of+    imm | fitsInNbits 12 imm -> [mkStrSpImm imm]+    imm ->+      [ movImmToIp imm,+        addSpToIp,+        mkStrIp+      ]+  where+    fmt = case reg of+      RegReal (RealRegSingle n) | n < 32 -> II64+      _ -> FF64+    mkStrSpImm imm = ANN (text "Spill@" <> int (off - delta)) $ ST fmt (OpReg W64 reg) (OpAddr (AddrRegImm spMachReg (ImmInt imm)))+    movImmToIp imm = ANN (text "Spill: TMP <- " <> int imm) $ MOV tmp (OpImm (ImmInt imm))+    addSpToIp = ANN (text "Spill: TMP <- SP + TMP ") $ ADD tmp tmp sp+    mkStrIp = ANN (text "Spill@" <> int (off - delta)) $ ST fmt (OpReg W64 reg) (OpAddr (AddrReg tmpReg))+    off = spillSlotToOffset slot++-- | Make a reload instruction, reload from spill slot to a register.+mkLoadInstr+   :: NCGConfig+   -> RegWithFormat+   -> Int       -- current stack delta+   -> Int       -- spill slot to use+   -> [Instr]++mkLoadInstr _config (RegWithFormat reg _fmt) delta slot =+  case off - delta of+    imm | fitsInNbits 12 imm -> [mkLdrSpImm imm]+    imm ->+      [ movImmToIp imm,+        addSpToIp,+        mkLdrIp+      ]+  where+    fmt = case reg of+      RegReal (RealRegSingle n) | n < 32 -> II64+      _ -> FF64+    mkLdrSpImm imm = ANN (text "Reload@" <> int (off - delta)) $ LD fmt (OpReg W64 reg) (OpAddr (AddrRegImm spMachReg (ImmInt imm)))+    movImmToIp imm = ANN (text "Reload: TMP <- " <> int imm) $ MOV tmp (OpImm (ImmInt imm))+    addSpToIp = ANN (text "Reload: TMP <- SP + TMP ") $ ADD tmp tmp sp+    mkLdrIp = ANN (text "Reload@" <> int (off - delta)) $ LD fmt (OpReg W64 reg) (OpAddr (AddrReg tmpReg))+    off = spillSlotToOffset slot++-- | See if this instruction is telling us the current C stack delta+takeDeltaInstr :: Instr -> Maybe Int+takeDeltaInstr (ANN _ i) = takeDeltaInstr i+takeDeltaInstr (DELTA i) = Just i+takeDeltaInstr _         = Nothing++-- | Not real instructions.  Just meta data+isMetaInstr :: Instr -> Bool+isMetaInstr instr =+  case instr of+    ANN _ i -> isMetaInstr i+    COMMENT {} -> True+    MULTILINE_COMMENT {} -> True+    LOCATION {} -> True+    NEWBLOCK {} -> True+    DELTA {} -> True+    LDATA {} -> True+    PUSH_STACK_FRAME -> True+    POP_STACK_FRAME -> True+    _ -> False++canFallthroughTo :: Instr -> BlockId -> Bool+canFallthroughTo insn bid =+  case insn of+    J (TBlock target) -> bid == target+    J_TBL targets _ _ -> all isTargetBid targets+    B (TBlock target) -> bid == target+    TAIL36 _ (TBlock target) -> bid == target+    BCOND1 _ _ _ (TBlock target) -> bid == target+    BCOND _ _ _ (TBlock target) -> bid == target+    _ -> False+  where+    isTargetBid target = case target of+      Nothing -> True+      Just target -> target == bid++-- | Copy the value in a register to another one.+-- Must work for all register classes.+mkRegRegMoveInstr :: Reg -> Reg -> Instr+mkRegRegMoveInstr src dst = ANN desc instr+  where+    desc = text "Reg->Reg Move: " <> ppr src <> text " -> " <> ppr dst+    instr = MOV (OpReg W64 dst) (OpReg W64 src)++-- | Take the source and destination from this (potential) reg -> reg move instruction+-- We have to be a bit careful here: A `MOV` can also mean an implicit+-- conversion. This case is filtered out.+takeRegRegMoveInstr :: Instr -> Maybe (Reg, Reg)+takeRegRegMoveInstr (MOV (OpReg width dst) (OpReg width' src))+  | width == width' && (isFloatReg dst == isFloatReg src) = pure (src, dst)+takeRegRegMoveInstr _ = Nothing++-- | Make an unconditional jump instruction.+mkJumpInstr :: BlockId -> [Instr]+mkJumpInstr id = [TAIL36 (OpReg W64 tmpReg) (TBlock (id))]++-- | Decrement @sp@ to allocate stack space.+mkStackAllocInstr :: Platform -> Int -> [Instr]+mkStackAllocInstr _platform n+  | n == 0 = []+  | n > 0 && fitsInNbits 12 (fromIntegral n) =+      [ ANN (text "Alloc stack") $ SUB sp sp (OpImm (ImmInt n)) ]+  | n > 0 =+     [+         ANN (text "Alloc more stack") (MOV tmp (OpImm (ImmInt n))),+         SUB sp sp tmp+     ]+mkStackAllocInstr _platform n = pprPanic "mkStackAllocInstr" (int n)++-- | Increment SP to deallocate stack space.+mkStackDeallocInstr :: Platform -> Int -> [Instr]+mkStackDeallocInstr _platform  n+  | n == 0 = []+  | n > 0 && fitsInNbits 12 (fromIntegral n) =+      [ ANN (text "Dealloc stack") $ ADD sp sp (OpImm (ImmInt n)) ]+  | n > 0 =+     [+         ANN (text "Dealloc more stack") (MOV tmp (OpImm (ImmInt n))),+         ADD sp sp tmp+     ]+mkStackDeallocInstr _platform n = pprPanic "mkStackDeallocInstr" (int n)++allocMoreStack+  :: Platform+  -> Int+  -> NatCmmDecl statics GHC.CmmToAsm.LA64.Instr.Instr+  -> UniqDSM (NatCmmDecl statics GHC.CmmToAsm.LA64.Instr.Instr, [(BlockId,BlockId)])++allocMoreStack _ _ top@(CmmData _ _) = return (top, [])+allocMoreStack platform slots proc@(CmmProc info lbl live (ListGraph code)) = do+  let entries = entryBlocks proc++  retargetList <- mapM (\e -> (e,) <$> newBlockId) entries++  let+    delta = ((x + stackAlign - 1) `quot` stackAlign) * stackAlign -- round up+      where x = slots * spillSlotSize -- sp delta++    alloc   = mkStackAllocInstr   platform delta+    dealloc = mkStackDeallocInstr platform delta++    new_blockmap :: LabelMap BlockId+    new_blockmap = mapFromList retargetList++    insert_stack_insn (BasicBlock id insns)+      | Just new_blockid <- mapLookup id new_blockmap =+        [ BasicBlock id $ alloc ++ [ B (TBlock new_blockid) ],+          BasicBlock new_blockid block' ]+      | otherwise =+        [ BasicBlock id block' ]+      where+        block' = foldr insert_dealloc [] insns++    insert_dealloc insn r = case insn of+      J {} -> dealloc ++ (insn : r)+      ANN _ e -> insert_dealloc e r+      _other | jumpDestsOfInstr insn /= [] ->+        patchJumpInstr insn retarget : r+      _other -> insn : r++      where retarget b = fromMaybe b (mapLookup b new_blockmap)++    new_code = concatMap insert_stack_insn code+  return (CmmProc info lbl live (ListGraph new_code), retargetList)++-- -----------------------------------------------------------------------------+-- Machine's assembly language++-- We have a few common "instructions" (nearly all the pseudo-ops) but+-- mostly all of 'Instr' is machine-specific.++data Instr+    -- comment pseudo-op+    = COMMENT SDoc+    | MULTILINE_COMMENT SDoc++    -- Annotated instruction. Should print <instr> # <doc>+    | ANN SDoc Instr++    -- location pseudo-op (file, line, col, name)+    | LOCATION Int Int Int LexicalFastString++    -- start a new basic block.  Useful during codegen, removed later.+    -- Preceding instruction should be a jump, as per the invariants+    -- for a BasicBlock (see Cmm).+    | NEWBLOCK BlockId++    -- specify current stack offset for benefit of subsequent passes.+    -- This carries a BlockId so it can be used in unwinding information.+    | DELTA   Int++    -- | Static data spat out during code generation.+    | LDATA Section RawCmmStatics++    | PUSH_STACK_FRAME+    | POP_STACK_FRAME+    -- Basic Integer Instructions ------------------------------------------------+    -- 1. Arithmetic Instructions ------------------------------------------------+    | ADD Operand Operand Operand+    | SUB Operand Operand Operand+    | ALSL Operand Operand Operand Operand+    | ALSLU Operand Operand Operand Operand+    | LU12I Operand Operand+    | LU32I Operand Operand+    | LU52I Operand Operand Operand+    | SSLT Operand Operand Operand+    | SSLTU Operand Operand Operand+    | PCADDI Operand Operand+    | PCADDU12I Operand Operand+    | PCADDU18I Operand Operand+    | PCALAU12I Operand Operand+    | AND Operand Operand Operand+    | OR Operand Operand Operand+    | XOR Operand Operand Operand+    | NOR Operand Operand Operand+    | ANDN Operand Operand Operand+    | ORN Operand Operand Operand+    | MUL Operand Operand Operand+    | MULW Operand Operand Operand+    | MULWU Operand Operand Operand+    | MULH Operand Operand Operand+    | MULHU Operand Operand Operand+    | DIV Operand Operand Operand+    | DIVU Operand Operand Operand+    | MOD Operand Operand Operand+    | MODU Operand Operand Operand+    -- 2. Bit-shift Instuctions --------------------------------------------------+    | SLL Operand Operand Operand+    | SRL Operand Operand Operand+    | SRA Operand Operand Operand+    | ROTR Operand Operand Operand+    -- 3. Bit-manupulation Instructions ------------------------------------------+    | EXT Operand Operand+    | CLO Operand Operand+    | CTO Operand Operand+    | CLZ Operand Operand+    | CTZ Operand Operand+    | BYTEPICK Operand Operand Operand Operand+    | REVB2H Operand Operand+    | REVB4H Operand Operand+    | REVB2W Operand Operand+    | REVBD Operand Operand+    | REVH2W Operand Operand+    | REVHD Operand Operand+    | BITREV4B Operand Operand+    | BITREV8B Operand Operand+    | BITREVW Operand Operand+    | BITREVD Operand Operand+    | BSTRINS Format Operand Operand Operand Operand+    | BSTRPICK Format Operand Operand Operand Operand+    | MASKEQZ Operand Operand Operand+    | MASKNEZ Operand Operand Operand+    -- Pseudo instructions+    | NOP+    | MOV Operand Operand+    | NEG Operand Operand+    | CSET Cond Operand Operand Operand+    -- 4. Branch Instructions ----------------------------------------------------+    | J Target+    | J_TBL [Maybe BlockId] (Maybe CLabel) Reg+    | B Target+    | BL Target [Reg]+    | CALL Target [Reg]+    | CALL36 Target+    | TAIL36 Operand Target+    | BCOND1 Cond Operand Operand Target+    | BCOND Cond Operand Operand Target+    | BEQZ Operand Target+    | BNEZ Operand Target+    -- 5. Common Memory Access Instructions --------------------------------------+    | LD Format Operand Operand+    | LDU Format Operand Operand+    | ST Format Operand Operand+    | LDX Format Operand Operand+    | LDXU Format Operand Operand+    | STX Format Operand Operand+    | LDPTR Format Operand Operand+    | STPTR Format Operand Operand+    | PRELD Operand Operand+    -- 6. Bound Check Memory Access Instructions ---------------------------------+    -- 7. Atomic Memory Access Instructions --------------------------------------+    -- 8. Barrier Instructions ---------------------------------------------------+    | DBAR BarrierType+    | IBAR BarrierType+    -- Basic Floating Point Instructions -----------------------------------------+    | FCVT    Operand Operand+    | SCVTF   Operand Operand+    | FCVTZS  Operand Operand Operand+    | FMAX Operand Operand Operand+    | FMIN Operand Operand Operand+    | FMAXA Operand Operand Operand+    | FMINA Operand Operand Operand+    | FNEG Operand Operand+    | FABS Operand Operand+    | FSQRT Operand Operand+    -- Floating-point fused multiply-add instructions+    --  fmadd : d =   r1 * r2 + r3+    --  fnmsub: d =   r1 * r2 - r3+    --  fmsub : d = - r1 * r2 + r3+    --  fnmadd: d = - r1 * r2 - r3+    | FMA FMASign Operand Operand Operand Operand++-- TODO: Not complete.+data BarrierType = Hint0++instrCon :: Instr -> String+instrCon i =+    case i of+      COMMENT{} -> "COMMENT"+      MULTILINE_COMMENT{} -> "COMMENT"+      ANN{} -> "ANN"+      LOCATION{} -> "LOCATION"+      NEWBLOCK{} -> "NEWBLOCK"+      DELTA{} -> "DELTA"+      LDATA {} -> "LDATA"+      PUSH_STACK_FRAME{} -> "PUSH_STACK_FRAME"+      POP_STACK_FRAME{} -> "POP_STACK_FRAME"++      ADD{} -> "ADD"+      SUB{} -> "SUB"+      ALSL{} -> "ALSL"+      ALSLU{} -> "ALSLU"+      LU12I{} -> "LU12I"+      LU32I{} -> "LU32I"+      LU52I{} -> "LU52I"+      SSLT{} -> "SSLT"+      SSLTU{} -> "SSLTU"+      PCADDI{} -> "PCADDI"+      PCADDU12I{} -> "PCADDU12I"+      PCADDU18I{} -> "PCADDU18I"+      PCALAU12I{} -> "PCALAU12I"+      AND{} -> "AND"+      OR{} -> "OR"+      XOR{} -> "XOR"+      NOR{} -> "NOR"+      ANDN{} -> "ANDN"+      ORN{} -> "ORN"+      MUL{} -> "MUL"+      MULW{} -> "MULW"+      MULWU{} -> "MULWU"+      MULH{} -> "MULH"+      MULHU{} -> "MULHU"+      DIV{} -> "DIV"+      MOD{} -> "MOD"+      DIVU{} -> "DIVU"+      MODU{} -> "MODU"+      SLL{} -> "SLL"+      SRL{} -> "SRL"+      SRA{} -> "SRA"+      ROTR{} -> "ROTR"+      EXT{} -> "EXT"+      CLO{} -> "CLO"+      CLZ{} -> "CLZ"+      CTO{} -> "CTO"+      CTZ{} -> "CTZ"+      BYTEPICK{} -> "BYTEPICK"+      REVB2H{} -> "REVB2H"+      REVB4H{} -> "REVB4H"+      REVB2W{} -> "REVB2W"+      REVBD{} -> "REVBD"+      REVH2W{} -> "REVH2W"+      REVHD{} -> "REVHD"+      BITREV4B{} -> "BITREV4B"+      BITREV8B{} -> "BITREV8B"+      BITREVW{} -> "BITREVW"+      BITREVD{} -> "BITREVD"+      BSTRINS{} -> "BSTRINS"+      BSTRPICK{} -> "BSTRPICK"+      MASKEQZ{} -> "MASKEQZ"+      MASKNEZ{} -> "MASKNEZ"+      NOP{} -> "NOP"+      MOV{} -> "MOV"+      NEG{} -> "NEG"+      CSET{} -> "CSET"+      J{} -> "J"+      J_TBL{} -> "J_TBL"+      B{} -> "B"+      BL{} -> "BL"+      CALL{} -> "CALL"+      CALL36{} -> "CALL36"+      TAIL36{} -> "TAIL36"+      BCOND1{} -> "BCOND1"+      BCOND{} -> "BCOND"+      BEQZ{} -> "BEQZ"+      BNEZ{} -> "BNEZ"+      LD{} -> "LD"+      LDU{} -> "LDU"+      ST{} -> "ST"+      LDX{} -> "LDX"+      LDXU{} -> "LDXU"+      STX{} -> "STX"+      LDPTR{} -> "LDPTR"+      STPTR{} -> "STPTR"+      PRELD{} -> "PRELD"+      DBAR{} -> "DBAR"+      IBAR{} -> "IBAR"+      FCVT{} -> "FCVT"+      SCVTF{} -> "SCVTF"+      FCVTZS{} -> "FCVTZS"+      FMAX{} -> "FMAX"+      FMIN{} -> "FMIN"+      FMAXA{} -> "FMAXA"+      FMINA{} -> "FMINA"+      FNEG{} -> "FNEG"+      FABS{} -> "FABS"+      FSQRT{} -> "FSQRT"+      FMA variant _ _ _ _ ->+        case variant of+          FMAdd  -> "FMADD"+          FMSub  -> "FMSUB"+          FNMAdd -> "FNMADD"+          FNMSub -> "FNMSUB"++data Target+    = TBlock BlockId+    | TLabel CLabel+    | TReg   Reg++data Operand+  = OpReg Width Reg -- register+  | OpImm Imm       -- immediate+  | OpAddr AddrMode -- address+  deriving (Eq, Show)++opReg :: Reg -> Operand+opReg = OpReg W64++opRegNo :: RegNo -> Operand+opRegNo = opReg . regSingle++-- LoongArch64 has no ip register in ABI. Here ip register is for spilling/+-- reloading register to/from slots. So make t8(r20) non-free for ip.+zero, ra, tp, sp, fp, tmp :: Operand+zero = opReg zeroReg+ra   = opReg raReg+sp   = opReg spMachReg+tp   = opReg tpMachReg+fp   = opReg fpMachReg+tmp  = opReg tmpReg++x0,  x1,  x2,  x3,  x4,  x5,  x6,  x7  :: Operand+x8,  x9,  x10, x11, x12, x13, x14, x15 :: Operand+x16, x17, x18, x19, x20, x21, x22, x23 :: Operand+x24, x25, x26, x27, x28, x29, x30, x31 :: Operand+x0  = opRegNo  0+x1  = opRegNo  1+x2  = opRegNo  2+x3  = opRegNo  3+x4  = opRegNo  4+x5  = opRegNo  5+x6  = opRegNo  6+x7  = opRegNo  7+x8  = opRegNo  8+x9  = opRegNo  9+x10 = opRegNo 10+x11 = opRegNo 11+x12 = opRegNo 12+x13 = opRegNo 13+x14 = opRegNo 14+x15 = opRegNo 15+x16 = opRegNo 16+x17 = opRegNo 17+x18 = opRegNo 18+x19 = opRegNo 19+x20 = opRegNo 20+x21 = opRegNo 21+x22 = opRegNo 22+x23 = opRegNo 23+x24 = opRegNo 24+x25 = opRegNo 25+x26 = opRegNo 26+x27 = opRegNo 27+x28 = opRegNo 18+x29 = opRegNo 29+x30 = opRegNo 30+x31 = opRegNo 31++d0,  d1,  d2,  d3,  d4,  d5,  d6,  d7  :: Operand+d8,  d9,  d10, d11, d12, d13, d14, d15 :: Operand+d16, d17, d18, d19, d20, d21, d22, d23 :: Operand+d24, d25, d26, d27, d28, d29, d30, d31 :: Operand+d0  = opRegNo 32+d1  = opRegNo 33+d2  = opRegNo 34+d3  = opRegNo 35+d4  = opRegNo 36+d5  = opRegNo 37+d6  = opRegNo 38+d7  = opRegNo 39+d8  = opRegNo 40+d9  = opRegNo 41+d10 = opRegNo 42+d11 = opRegNo 43+d12 = opRegNo 44+d13 = opRegNo 45+d14 = opRegNo 46+d15 = opRegNo 47+d16 = opRegNo 48+d17 = opRegNo 49+d18 = opRegNo 50+d19 = opRegNo 51+d20 = opRegNo 52+d21 = opRegNo 53+d22 = opRegNo 54+d23 = opRegNo 55+d24 = opRegNo 56+d25 = opRegNo 57+d26 = opRegNo 58+d27 = opRegNo 59+d28 = opRegNo 60+d29 = opRegNo 61+d30 = opRegNo 62+d31 = opRegNo 63++fitsInNbits :: Int -> Int -> Bool+fitsInNbits n i = (-1 `shiftL` (n - 1)) <= i && i <= (1 `shiftL` (n - 1) - 1)++isUnsignOp :: Int -> Bool+isUnsignOp i = (i >= 0)++isNbitEncodeable :: Int -> Integer -> Bool+isNbitEncodeable n i = let shift = n - 1 in (-1 `shiftL` shift) <= i && i < (1 `shiftL` shift)++isEncodeableInWidth :: Width -> Integer -> Bool+isEncodeableInWidth = isNbitEncodeable . widthInBits++isIntOp :: Operand -> Bool+isIntOp = not . isFloatOp++isFloatOp :: Operand -> Bool+isFloatOp (OpReg _ reg) | isFloatReg reg = True+isFloatOp _ = False++isFloatReg :: Reg -> Bool+isFloatReg (RegReal (RealRegSingle i)) | i > 31 = True+isFloatReg (RegVirtual (VirtualRegD _)) = True+isFloatReg _ = False++widthToInt :: Width -> Int+widthToInt W8   = 8+widthToInt W16  = 16+widthToInt W32  = 32+widthToInt W64  = 64+widthToInt _ = 64++widthFromOpReg :: Operand -> Width+widthFromOpReg (OpReg W8 _)  = W8+widthFromOpReg (OpReg W16 _) = W16+widthFromOpReg (OpReg W32 _) = W32+widthFromOpReg (OpReg W64 _) = W64+widthFromOpReg _ = W64++ldFormat :: Format -> Format+ldFormat f+  | f `elem` [II8, II16, II32, II64] = II64+  | f `elem` [FF32, FF64] = FF64+  | otherwise = pprPanic "unsupported ldFormat: " (text $ show f)
+ GHC/CmmToAsm/LA64/Ppr.hs view
@@ -0,0 +1,1149 @@+module GHC.CmmToAsm.LA64.Ppr (pprNatCmmDecl, pprInstr) where++import GHC.Prelude hiding (EQ)++import GHC.CmmToAsm.LA64.Regs+import GHC.CmmToAsm.LA64.Instr+import GHC.CmmToAsm.LA64.Cond+import GHC.CmmToAsm.Config+import GHC.CmmToAsm.Format+import GHC.CmmToAsm.Ppr+import GHC.CmmToAsm.Types+import GHC.CmmToAsm.Utils+import GHC.Cmm hiding (topInfoTable)+import GHC.Cmm.BlockId+import GHC.Cmm.CLabel+import GHC.Cmm.Dataflow.Label+import GHC.Platform+import GHC.Platform.Reg+import GHC.Types.Unique ( pprUniqueAlways, getUnique )+import GHC.Utils.Outputable+import GHC.Types.Basic (Alignment, alignmentBytes, mkAlignment)+import GHC.Utils.Panic++pprNatCmmDecl :: forall doc. (IsDoc doc) => NCGConfig -> NatCmmDecl RawCmmStatics Instr -> doc++pprNatCmmDecl config (CmmData section dats) =+  pprSectionAlign config section $$ pprDatas config dats++pprNatCmmDecl config proc@(CmmProc top_info lbl _ (ListGraph blocks)) =+  let platform = ncgPlatform config++      pprProcAlignment :: doc+      pprProcAlignment = maybe empty (pprAlign . mkAlignment) (ncgProcAlignment config)+   in pprProcAlignment+        $$ case topInfoTable proc of+          Nothing ->+            -- special case for code without info table:+            pprSectionAlign config (Section Text lbl)+              $$+              -- do not+              -- pprProcAlignment config $$+              pprLabel platform lbl+              $$ vcat (map (pprBasicBlock config top_info) blocks) -- blocks guaranteed not null, so label needed+              $$ ppWhen+                (ncgDwarfEnabled config)+                (line (pprBlockEndLabel platform lbl) $$ line (pprProcEndLabel platform lbl))+              $$ pprSizeDecl platform lbl+          Just (CmmStaticsRaw info_lbl _) ->+            pprSectionAlign config (Section Text info_lbl)+              $$+              -- pprProcAlignment config $$+              ( if platformHasSubsectionsViaSymbols platform+                  then line (pprAsmLabel platform (mkDeadStripPreventer info_lbl) <> char ':')+                  else empty+              )+              $$ vcat (map (pprBasicBlock config top_info) blocks)+              $$ ppWhen (ncgDwarfEnabled config) (line (pprProcEndLabel platform info_lbl))+              $$+              -- above: Even the first block gets a label, because with branch-chain+              -- elimination, it might be the target of a goto.+              ( if platformHasSubsectionsViaSymbols platform+                  then -- See Note [Subsections Via Symbols]++                    line+                      $ text "\t.long "+                      <+> pprAsmLabel platform info_lbl+                      <+> char '-'+                      <+> pprAsmLabel platform (mkDeadStripPreventer info_lbl)+                  else empty+              )+              $$ pprSizeDecl platform info_lbl+{-# SPECIALIZE pprNatCmmDecl :: NCGConfig -> NatCmmDecl RawCmmStatics Instr -> SDoc #-}+{-# SPECIALIZE pprNatCmmDecl :: NCGConfig -> NatCmmDecl RawCmmStatics Instr -> HDoc #-} -- see Note [SPECIALIZE to HDoc] in GHC.Utils.Outputable++pprProcEndLabel :: IsLine doc => Platform -> CLabel -- ^ Procedure+                -> doc+pprProcEndLabel platform lbl =+    pprAsmLabel platform (mkAsmTempProcEndLabel lbl) <> colon++pprBlockEndLabel :: IsLine doc => Platform -> CLabel -- ^ Block name+                 -> doc+pprBlockEndLabel platform lbl =+    pprAsmLabel platform (mkAsmTempEndLabel lbl) <> colon++pprLabel :: IsDoc doc => Platform -> CLabel -> doc+pprLabel platform lbl =+   pprGloblDecl platform lbl+   $$ pprTypeDecl platform lbl+   $$ line (pprAsmLabel platform lbl <> char ':')++pprAlign :: (IsDoc doc) => Alignment -> doc+pprAlign alignment =+  -- .balign is stable, whereas .align is platform dependent.+  line $ text "\t.balign " <> int (alignmentBytes alignment)++-- | Print appropriate alignment for the given section type.+--+-- Currently, this always aligns to a full machine word (8 byte.) A future+-- improvement could be to really do this per section type (though, it's+-- probably not a big gain.)+pprAlignForSection :: (IsDoc doc) => SectionType -> doc+pprAlignForSection _seg = pprAlign . mkAlignment $ 8++-- Print section header and appropriate alignment for that section.+-- This will e.g. emit a header like:+--+--     .section .text+--     .balign 8+--+pprSectionAlign :: IsDoc doc => NCGConfig -> Section -> doc+pprSectionAlign _config (Section (OtherSection _) _) =+  panic "LA64.Ppr.pprSectionAlign: unknown section"+pprSectionAlign config sec@(Section seg _) =+    line (pprSectionHeader config sec)+    $$ pprAlignForSection seg++-- | Output the ELF .size directive+pprSizeDecl :: (IsDoc doc) => Platform -> CLabel -> doc+pprSizeDecl platform lbl+  | osElfTarget (platformOS platform) =+      line $ text "\t.size" <+> pprAsmLabel platform lbl <> text ", .-" <> pprAsmLabel platform lbl+pprSizeDecl _ _ = empty++pprBasicBlock ::+  (IsDoc doc) =>+  NCGConfig ->+  LabelMap RawCmmStatics ->+  NatBasicBlock Instr ->+  doc++pprBasicBlock config info_env (BasicBlock blockid instrs)+  = maybe_infotable $+    pprLabel platform asmLbl $$+    vcat (map (pprInstr platform) (id {-detectTrivialDeadlock-} optInstrs)) $$+    ppWhen (ncgDwarfEnabled config) (+      -- Emit both end labels since this may end up being a standalone+      -- top-level block+      line (pprBlockEndLabel platform asmLbl+         <> pprProcEndLabel platform asmLbl)+    )+  where+    -- Filter out identity moves. E.g. mov x18, x18 will be dropped.+    optInstrs = filter f instrs+      where f (MOV o1 o2) | o1 == o2 = False+            f _ = True++    asmLbl = blockLbl blockid+    platform = ncgPlatform config+    maybe_infotable c = case mapLookup blockid info_env of+       Nothing   -> c+       Just (CmmStaticsRaw info_lbl info) ->+          --  pprAlignForSection platform Text $$+           infoTableLoc $$+           vcat (map (pprData config) info) $$+           pprLabel platform info_lbl $$+           c $$+           ppWhen (ncgDwarfEnabled config)+              (line (pprBlockEndLabel platform info_lbl))+    -- Make sure the info table has the right .loc for the block+    -- coming right after it. See Note [Info Offset]+    infoTableLoc = case instrs of+      (l@LOCATION{} : _) -> pprInstr platform l+      _other             -> empty++pprDatas :: IsDoc doc => NCGConfig -> RawCmmStatics -> doc+-- See Note [emit-time elimination of static indirections] in "GHC.Cmm.CLabel".+pprDatas config (CmmStaticsRaw alias [CmmStaticLit (CmmLabel lbl), CmmStaticLit ind, _, _])+  | lbl == mkIndStaticInfoLabel+  , let labelInd (CmmLabelOff l _) = Just l+        labelInd (CmmLabel l) = Just l+        labelInd _ = Nothing+  , Just ind' <- labelInd ind+  , alias `mayRedirectTo` ind'+  = pprGloblDecl (ncgPlatform config) alias+    $$ line (text ".equiv" <+> pprAsmLabel (ncgPlatform config) alias <> comma <> pprAsmLabel (ncgPlatform config) ind')++pprDatas config (CmmStaticsRaw lbl dats)+  = vcat (pprLabel platform lbl : map (pprData config) dats)+   where+      platform = ncgPlatform config++pprData :: IsDoc doc => NCGConfig -> CmmStatic -> doc+pprData _config (CmmString str) = line (pprString str)+pprData _config (CmmFileEmbed path _) = line (pprFileEmbed path)++pprData config (CmmUninitialised bytes)+ = line $ let platform = ncgPlatform config+          in if platformOS platform == OSDarwin+                then text ".space " <> int bytes+                else text ".skip "  <> int bytes++pprData config (CmmStaticLit lit) = pprDataItem config lit++pprGloblDecl :: IsDoc doc => Platform -> CLabel -> doc+pprGloblDecl platform lbl+  | not (externallyVisibleCLabel lbl) = empty+  | otherwise = line (text "\t.globl " <> pprAsmLabel platform lbl)++-- Always use objects for info tables+--+-- See discussion in X86.Ppr for why this is necessary.  Essentially we need to+-- ensure that we never pass function symbols when we might want to lookup the+-- info table.  If we did, we could end up with procedure linking tables+-- (PLT)s, and thus the lookup wouldn't point to the function, but into the+-- jump table.+--+-- Fun fact: The LLVMMangler exists to patch this issue su on the LLVM side as+-- well.+pprLabelType' :: IsLine doc => Platform -> CLabel -> doc+pprLabelType' platform lbl =+  if isCFunctionLabel lbl || functionOkInfoTable+    then text "@function"+    else text "@object"+  where+    functionOkInfoTable = platformTablesNextToCode platform &&+      isInfoTableLabel lbl && not (isCmmInfoTableLabel lbl) && not (isConInfoTableLabel lbl)++-- this is called pprTypeAndSizeDecl in PPC.Ppr+pprTypeDecl :: IsDoc doc => Platform -> CLabel -> doc+pprTypeDecl platform lbl+    = if osElfTarget (platformOS platform) && externallyVisibleCLabel lbl+      then line (text ".type " <> pprAsmLabel platform lbl <> text ", " <> pprLabelType' platform lbl)+      else empty++pprDataItem :: IsDoc doc => NCGConfig -> CmmLit -> doc+pprDataItem config lit+  = lines_ (ppr_item (cmmTypeFormat $ cmmLitType platform lit) lit)+    where+        platform = ncgPlatform config++        imm = litToImm lit++        ppr_item II8  _ = [text "\t.byte\t"  <> pprDataImm platform imm]+        ppr_item II16 _ = [text "\t.short\t" <> pprDataImm platform imm]+        ppr_item II32 _ = [text "\t.long\t"  <> pprDataImm platform imm]+        ppr_item II64 _ = [text "\t.quad\t"  <> pprDataImm platform imm]++        ppr_item FF32  (CmmFloat r _)+           = let bs = floatToBytes (fromRational r)+             in  map (\b -> text "\t.byte\t" <> int (fromIntegral b)) bs++        ppr_item FF64 (CmmFloat r _)+           = let bs = doubleToBytes (fromRational r)+             in  map (\b -> text "\t.byte\t" <> int (fromIntegral b)) bs++        ppr_item _ _ = pprPanic "pprDataItem:ppr_item" (text $ show lit)++-- | Pretty print an immediate value in the @data@ section+-- This does not include any checks. We rely on the Assembler to check for+-- errors. Use `pprOpImm` for immediates in instructions (operands.)+pprDataImm :: IsLine doc => Platform -> Imm -> doc+pprDataImm _ (ImmInt i)     = int i+pprDataImm _ (ImmInteger i) = integer i+pprDataImm p (ImmCLbl l)    = pprAsmLabel p l+pprDataImm p (ImmIndex l i) = pprAsmLabel p l <> char '+' <> int i+pprDataImm _ (ImmLit s)     = ftext s+pprDataImm _ (ImmFloat f) = float (fromRational f)+pprDataImm _ (ImmDouble d) = double (fromRational d)++pprDataImm p (ImmConstantSum a b) = pprDataImm p a <> char '+' <> pprDataImm p b+pprDataImm p (ImmConstantDiff a b) = pprDataImm p a <> char '-'+                   <> lparen <> pprDataImm p b <> rparen++asmComment :: SDoc -> SDoc+asmComment c = text "#" <+> c++asmDoubleslashComment :: SDoc -> SDoc+asmDoubleslashComment c = text "//" <+> c++asmMultilineComment :: SDoc -> SDoc+asmMultilineComment c =  text "/*" $+$ c $+$ text "*/"++-- | Pretty print an immediate operand of an instruction+pprOpImm :: (IsLine doc) => Platform -> Imm -> doc+pprOpImm platform imm = case imm of+  ImmInt i -> int i+  ImmInteger i -> integer i+  ImmCLbl l -> char '=' <> pprAsmLabel platform l+  ImmFloat f -> float (fromRational f)+  ImmDouble d -> double (fromRational d)+  _ -> pprPanic "LA64.Ppr.pprOpImm" (text "Unsupported immediate for instruction operands:" <+> (text . show) imm)++negOp :: Operand -> Operand+negOp (OpImm (ImmInt i)) = OpImm (ImmInt (negate i))+negOp (OpImm (ImmInteger i)) = OpImm (ImmInteger (negate i))+negOp op = pprPanic "LA64.negOp" (text $ show op)++pprOp :: IsLine doc => Platform -> Operand -> doc+pprOp plat op = case op of+  OpReg w r                 -> pprReg w r+  OpImm imm                 -> pprOpImm plat imm+  OpAddr (AddrRegReg r1 r2) -> pprReg W64 r1 <> comma <+> pprReg W64 r2+  OpAddr (AddrRegImm r imm) -> pprReg W64 r <> comma <+> pprOpImm plat imm+  OpAddr (AddrReg r)        -> pprReg W64 r <+> text ", 0"++pprReg :: forall doc. IsLine doc => Width -> Reg -> doc+pprReg w r = case r of+  RegReal    (RealRegSingle i) -> ppr_reg_no i+  -- virtual regs should not show up, but this is helpful for debugging.+  RegVirtual (VirtualRegI u)   -> text "%vI_" <> pprUniqueAlways u+  -- RegVirtual (VirtualRegF u)   -> text "%vF_" <> pprUniqueAlways u+  RegVirtual (VirtualRegD u)   -> text "%vD_" <> pprUniqueAlways u+  _                            -> pprPanic "LA64.pprReg" (text (show r) <+> ppr w)++  where+    ppr_reg_no :: Int -> doc+    -- LoongArch's registers must be started from `$[fr]`+    -- General Purpose Registers+    ppr_reg_no 0  = text "$zero"+    ppr_reg_no 1  = text "$ra"+    ppr_reg_no 2  = text "$tp"+    ppr_reg_no 3  = text "$sp"+    ppr_reg_no 4  = text "$a0"+    ppr_reg_no 5  = text "$a1"+    ppr_reg_no 6  = text "$a2"+    ppr_reg_no 7  = text "$a3"+    ppr_reg_no 8  = text "$a4"+    ppr_reg_no 9  = text "$a5"+    ppr_reg_no 10 = text "$a6"+    ppr_reg_no 11 = text "$a7"+    ppr_reg_no 12 = text "$t0"+    ppr_reg_no 13 = text "$t1"+    ppr_reg_no 14 = text "$t2"+    ppr_reg_no 15 = text "$t3"+    ppr_reg_no 16 = text "$t4"+    ppr_reg_no 17 = text "$t5"+    ppr_reg_no 18 = text "$t6"+    ppr_reg_no 19 = text "$t7"+    ppr_reg_no 20 = text "$t8"+    ppr_reg_no 21 = text "$u0"  -- Reserverd+    ppr_reg_no 22 = text "$fp"+    ppr_reg_no 23 = text "$s0"+    ppr_reg_no 24 = text "$s1"+    ppr_reg_no 25 = text "$s2"+    ppr_reg_no 26 = text "$s3"+    ppr_reg_no 27 = text "$s4"+    ppr_reg_no 28 = text "$s5"+    ppr_reg_no 29 = text "$s6"+    ppr_reg_no 30 = text "$s7"+    ppr_reg_no 31 = text "$s8"++    -- Floating Point Registers+    ppr_reg_no 32 = text "$fa0"+    ppr_reg_no 33 = text "$fa1"+    ppr_reg_no 34 = text "$fa2"+    ppr_reg_no 35 = text "$fa3"+    ppr_reg_no 36 = text "$fa4"+    ppr_reg_no 37 = text "$fa5"+    ppr_reg_no 38 = text "$fa6"+    ppr_reg_no 39 = text "$fa7"+    ppr_reg_no 40 = text "$ft0"+    ppr_reg_no 41 = text "$ft1"+    ppr_reg_no 42 = text "$ft2"+    ppr_reg_no 43 = text "$ft3"+    ppr_reg_no 44 = text "$ft4"+    ppr_reg_no 45 = text "$ft5"+    ppr_reg_no 46 = text "$ft6"+    ppr_reg_no 47 = text "$ft7"+    ppr_reg_no 48 = text "$ft8"+    ppr_reg_no 49 = text "$ft9"+    ppr_reg_no 50 = text "$ft10"+    ppr_reg_no 51 = text "$ft11"+    ppr_reg_no 52 = text "$ft12"+    ppr_reg_no 53 = text "$ft13"+    ppr_reg_no 54 = text "$ft14"+    ppr_reg_no 55 = text "$ft15"+    ppr_reg_no 56 = text "$fs0"+    ppr_reg_no 57 = text "$fs1"+    ppr_reg_no 58 = text "$fs2"+    ppr_reg_no 59 = text "$fs3"+    ppr_reg_no 60 = text "$fs4"+    ppr_reg_no 61 = text "$fs5"+    ppr_reg_no 62 = text "$fs6"+    ppr_reg_no 63 = text "$fs7"++    ppr_reg_no i+         | i < 0 = pprPanic "Unexpected register number (min is 0)" (ppr w <+> int i)+         | i > 63 = pprPanic "Unexpected register number (max is 63)" (ppr w <+> int i)+         -- no support for widths > W64.+         | otherwise = pprPanic "Unsupported width in register (max is 64)" (ppr w <+> int i)++-- | Single precission `Operand` (floating-point)+isSingleOp :: Operand -> Bool+isSingleOp (OpReg W32 _) = True+isSingleOp _ = False++-- | Double precission `Operand` (floating-point)+isDoubleOp :: Operand -> Bool+isDoubleOp (OpReg W64 _) = True+isDoubleOp _ = False++-- | `Operand` is an immediate value+isImmOp :: Operand -> Bool+isImmOp (OpImm _) = True+isImmOp _ = False++-- | `Operand` is an immediate @0@ value+isImmZero :: Operand -> Bool+isImmZero (OpImm (ImmFloat 0)) = True+isImmZero (OpImm (ImmDouble 0)) = True+isImmZero (OpImm (ImmInt 0)) = True+isImmZero _ = False++pprInstr :: IsDoc doc => Platform -> Instr -> doc+pprInstr platform instr = case instr of+  -- Meta Instructions ---------------------------------------------------------+  -- see Note [dualLine and dualDoc] in GHC.Utils.Outputable+  COMMENT s  -> dualDoc (asmComment s) empty+  MULTILINE_COMMENT s -> dualDoc (asmMultilineComment s) empty+  ANN d i -> dualDoc (pprInstr platform i <+> asmDoubleslashComment d) (pprInstr platform i)++  LOCATION file line' col _name+    -> line (text "\t.loc" <+> int file <+> int line' <+> int col)+  DELTA d   -> dualDoc (asmComment $ text "\tdelta = " <> int d) empty+  NEWBLOCK _ -> panic "PprInstr: NEWBLOCK"+  LDATA _ _ -> panic "PprInstr: NEWBLOCK"++  -- Pseudo Instructions -------------------------------------------------------++  PUSH_STACK_FRAME -> lines_ [ text "\taddi.d $sp, $sp, -16"+                             , text "\tst.d   $ra, $sp, 8"+                             , text "\tst.d   $fp, $sp, 0"+                             , text "\taddi.d $fp, $sp, 16"+                             ]++  POP_STACK_FRAME -> lines_  [ text "\tld.d   $fp, $sp, 0"+                             , text "\tld.d   $ra, $sp, 8"+                             , text "\taddi.d $sp, $sp, 16"+                             ]+++  -- ===========================================================================+  -- LoongArch64 Instruction Set+  -- Basic Integer Instructions ------------------------------------------------+  -- 1. Arithmetic Instructions ------------------------------------------------+    -- ADD.{W/D}, SUB.{W/D}+    -- ADDI.{W/D}, ADDU16I.D+  ADD  o1 o2 o3+    | isFloatOp o2 && isFloatOp o3 && isSingleOp o2 && isSingleOp o3 -> op3 (text "\tfadd.s") o1 o2 o3+    | isFloatOp o2 && isFloatOp o3 && isDoubleOp o2 && isDoubleOp o3 -> op3 (text "\tfadd.d") o1 o2 o3+    | OpReg W32 _ <- o2, OpReg W32 _ <- o3 -> op3 (text "\tadd.w") o1 o2 o3+    | OpReg W64 _ <- o2, OpReg W64 _ <- o3 -> op3 (text "\tadd.d") o1 o2 o3+    | OpReg W32 _ <- o2, isImmOp o3 -> op3 (text "\taddi.w") o1 o2 o3+    | OpReg W64 _ <- o2, isImmOp o3 -> op3 (text "\taddi.d") o1 o2 o3+    | otherwise -> pprPanic "LA64.ppr: ADD error: " ((ppr (widthFromOpReg o1)) <+> pprOp platform o1 <+> (ppr (widthFromOpReg o2)) <+> pprOp platform o2 <+> (ppr (widthFromOpReg o3)) <+> pprOp platform o3)+    -- TODO: Not complete.+    -- Here we should add addu16i.d for optimizations of accelerating GOT accession+    -- with ldptr.w/d, stptr.w/d+  SUB  o1 o2 o3+    | isFloatOp o2 && isFloatOp o3 && isSingleOp o2 && isSingleOp o3 -> op3 (text "\tfsub.s") o1 o2 o3+    | isFloatOp o2 && isFloatOp o3 && isDoubleOp o2 && isDoubleOp o3 -> op3 (text "\tfsub.d") o1 o2 o3+    | OpReg W32 _ <- o2, OpReg W32 _ <- o3 -> op3 (text "\tsub.w") o1 o2 o3+    | OpReg W64 _ <- o2, OpReg W64 _ <- o3 -> op3 (text "\tsub.d") o1 o2 o3+    | OpReg W32 _ <- o2, isImmOp o3 -> op3 (text "\taddi.w") o1 o2 (negOp o3)+    | OpReg W64 _ <- o2, isImmOp o3 -> op3 (text "\taddi.d") o1 o2 (negOp o3)+    | otherwise -> pprPanic "LA64.ppr: SUB error: " ((ppr (widthFromOpReg o1)) <+> pprOp platform o1 <+> (ppr (widthFromOpReg o2)) <+> pprOp platform o2 <+> (ppr (widthFromOpReg o3)) <+> pprOp platform o3)+    -- ALSL.{W[U]/D}+  ALSL  o1 o2 o3 o4+    | OpReg W32 _ <- o2, OpReg W32 _ <- o3, isImmOp o4 -> op4 (text "\talsl.w") o1 o2 o3 o4+    | OpReg W64 _ <- o2, OpReg W64 _ <- o3, isImmOp o4 -> op4 (text "\talsl.d") o1 o2 o3 o4+    | otherwise -> pprPanic "LA64.ppr: ALSL error: " ((ppr (widthFromOpReg o1)) <+> pprOp platform o1 <+> (ppr (widthFromOpReg o2)) <+> pprOp platform o2 <+> (ppr (widthFromOpReg o3)) <+> pprOp platform o3)+  ALSLU  o1 o2 o3 o4 -> op4 (text "\talsl.wu") o1 o2 o3 o4+    -- LoongArch-Assembler should implement following pesudo instructions, here we can directly use them.+    -- li.w rd, s32+    -- li.w rd, u32+    -- li.d rd, s64+    -- li.d rd, u64+    --+    -- # Load with one instruction+    -- ori dst, $zero, imm[11:0]+    --+    -- # Load with two instructions+    -- lu12i.w dst, imm[31:12]+    -- ori     dst, dst, imm[11:0]+    --+    -- # Load with four instructions+    -- lu12i.w dst, imm[31:12]+    -- ori     dst, dst, imm[11:0]+    -- lu32i.d dst, imm[51:32]+    -- lu52i.d dst, dst, imm[63:52]++  --  -- LU12I.W, LU32I.D, LU52I.D+  LU12I  o1 o2 -> op2 (text "\tlu12i.w") o1 o2+  LU32I  o1 o2 -> op2 (text "\tlu32i.d") o1 o2+  LU52I  o1 o2 o3 -> op3 (text "\tlu52i.d") o1 o2 o3+    -- SSLT[U]+    -- SSLT[U]I+  SSLT  o1 o2 o3+    | isImmOp o3 -> op3 (text "\tslti") o1 o2 o3+    | OpReg W64 _ <- o2, OpReg W64 _ <- o3  -> op3 (text "\tslt") o1 o2 o3+    | otherwise -> pprPanic "LA64.ppr: SSLT error: " ((ppr (widthFromOpReg o1)) <+> pprOp platform o1 <+> (ppr (widthFromOpReg o2)) <+> pprOp platform o2 <+> (ppr (widthFromOpReg o3)) <+> pprOp platform o3)+  SSLTU  o1 o2 o3+    | isImmOp o3 -> op3 (text "\tsltui") o1 o2 o3+    | OpReg W64 _ <- o2, OpReg W64 _ <- o3 -> op3 (text "\tsltu") o1 o2 o3+    | otherwise -> pprPanic "LA64.ppr: SSLTU error: " ((ppr (widthFromOpReg o1)) <+> pprOp platform o1 <+> (ppr (widthFromOpReg o2)) <+> pprOp platform o2 <+> (ppr (widthFromOpReg o3)) <+> pprOp platform o3)+    -- PCADDI, PCADDU121, PCADDU18l, PCALAU12I+  PCADDI  o1 o2     -> op2 (text "\tpcaddi") o1 o2+  PCADDU12I  o1 o2  -> op2 (text "\tpcaddu12i") o1 o2+  PCADDU18I  o1 (OpImm (ImmCLbl lbl))  ->+    lines_ [+      text "\tpcaddu18i" <+> pprOp platform o1 <> comma <+> text "%call36(" <+> pprAsmLabel platform lbl <+> text ")"+           ]+  PCALAU12I  o1 o2  -> op2 (text "\tpcalau12i") o1 o2+    -- AND, OR, NOR, XOR, ANDN, ORN+    -- ANDI, ORI, XORI: zero-extention+  AND  o1 o2 o3+    | OpReg W64 _ <- o2, OpReg W64 _ <- o3 -> op3 (text "\tand") o1 o2 o3+    | OpReg W64 _ <- o2, isImmOp o3 -> op3 (text "\tandi") o1 o2 o3+    | otherwise -> pprPanic "LA64.ppr: AND error: " ((ppr (widthFromOpReg o1)) <+> pprOp platform o1 <+> (ppr (widthFromOpReg o2)) <+> pprOp platform o2 <+> (ppr (widthFromOpReg o3)) <+> pprOp platform o3)+  OR  o1 o2 o3+    | OpReg W64 _ <- o2, OpReg W64 _ <- o3 -> op3 (text "\tor") o1 o2 o3+    | OpReg W64 _ <- o2, isImmOp o3 -> op3 (text "\tori") o1 o2 o3+    | otherwise -> pprPanic "LA64.ppr: OR error: " ((ppr (widthFromOpReg o1)) <+> pprOp platform o1 <+> (ppr (widthFromOpReg o2)) <+> pprOp platform o2 <+> (ppr (widthFromOpReg o3)) <+> pprOp platform o3)+  XOR  o1 o2 o3+    | OpReg W64 _ <- o2, OpReg W64 _ <- o3 -> op3 (text "\txor") o1 o2 o3+    | OpReg W64 _ <- o2, isImmOp o3 -> op3 (text "\txori") o1 o2 o3+    | otherwise -> pprPanic "LA64.ppr: XOR error: " ((ppr (widthFromOpReg o1)) <+> pprOp platform o1 <+> (ppr (widthFromOpReg o2)) <+> pprOp platform o2 <+> (ppr (widthFromOpReg o3)) <+> pprOp platform o3)+  NOR  o1 o2 o3   -> op3 (text "\tnor") o1 o2 o3+  ANDN  o1 o2 o3  -> op3 (text "\tandn") o1 o2 o3+  ORN  o1 o2 o3   -> op3 (text "\torn") o1 o2 o3++  -----------------------------------------------------------------------------+  -- Pseudo instructions+  -- NOP, alias for "andi r0, r0, r0"+  NOP -> line $ text "\tnop"+  -- NEG o1 o2, alias for "sub o1, r0, o2"+  NEG o1 o2+    | isFloatOp o2 && isSingleOp o2 -> op2 (text "\tfneg.s") o1 o2+    | isFloatOp o2 && isDoubleOp o2 -> op2 (text "\tfneg.d") o1 o2+    | OpReg W32 _ <- o2 -> op3 (text "\tsub.w" ) o1 zero o2+    | OpReg W64 _ <- o2 -> op3 (text "\tsub.d" ) o1 zero o2+    | otherwise -> pprPanic "LA64.ppr: NEG error: " ((ppr (widthFromOpReg o1)) <+> pprOp platform o1 <+> (ppr (widthFromOpReg o2)) <+> pprOp platform o2)+  -- Here we can do more simplitcations.+  -- To be honest, floating point instructions are too scarce, so maybe+  -- we should reimplement some pseudo instructions with others.+  MOV o1 o2+    | isFloatOp o1 && isFloatOp o2 && isSingleOp o1 && isSingleOp o2 -> op2 (text "\tfmov.s") o1 o2+    | isFloatOp o1 && isFloatOp o2 && isDoubleOp o1 && isDoubleOp o2 -> op2 (text "\tfmov.d") o1 o2+    | isFloatOp o1 && isImmZero o2 && isSingleOp o1 -> op2 (text "\tmovgr2fr.w") o1 zero+    | isFloatOp o1 && isImmZero o2 && isDoubleOp o1 -> op2 (text "\tmovgr2fr.d") o1 zero+    | isFloatOp o1 && not (isFloatOp o2) && isSingleOp o1 -> op2 (text "\tmovgr2fr.w") o1 o2+    | isFloatOp o1 && not (isFloatOp o2) && isDoubleOp o1 -> op2 (text "\tmovgr2fr.d") o1 o2+    | not (isFloatOp o1) && isFloatOp o2 && isSingleOp o2 -> op2 (text "\tmovfr2gr.s") o1 o2+    | not (isFloatOp o1) && isFloatOp o2 && isDoubleOp o2 -> op2 (text "\tmovfr2gr.d") o1 o2+    | isImmOp o2, (OpImm (ImmInt i)) <- o2, fitsInNbits 12 (fromIntegral i) ->+      lines_ [text "\taddi.d" <+> pprOp platform o1 <> comma <+> pprOp platform x0 <+> comma <> pprOp platform o2]+    | isImmOp o2, (OpImm (ImmInteger i)) <- o2, fitsInNbits 12 (fromIntegral i) ->+      lines_ [text "\taddi.d" <+> pprOp platform o1 <> comma <+> pprOp platform x0 <+> comma <> pprOp platform o2]+    | OpReg W64 _ <- o2 -> op2 (text "\tmove") o1 o2+    | OpReg _ _ <- o2  ->+      lines_ [+        text "\tbstrpick.d" <+> pprOp platform o1 <> comma <+> pprOp platform o2 <> comma <+> pprOp platform (OpImm (ImmInt ((widthToInt (min (widthFromOpReg o1) (widthFromOpReg o2))) - 1))) <+> text ", 0"+             ]+    -- TODO: Maybe we can do more.+    -- Let the assembler do these concret things.+    | isImmOp o2 ->+      lines_ [text "\tli.d" <+> pprOp platform o1 <> comma <+> pprOp platform o2]+    | otherwise -> pprPanic "LA64.ppr: MOV error: " ((ppr (widthFromOpReg o1)) <+> pprOp platform o1 <+> (ppr (widthFromOpReg o2)) <+> pprOp platform o2)++  -- CSET pesudo instrcutions implementation+  CSET cond dst o1 o2 -> case cond of+    -- SEQ dst, rd, rs -> [SUB rd, rd, rs;  sltui dst, rd, 1]+    EQ | isIntOp o1 && isIntOp o2 ->+      lines_ [+              subFor o1 o2,+              text "\tsltui" <+> pprOp platform dst <> comma <+> pprOp platform dst <> comma <+> pprOp platform (OpImm (ImmInt 1))+             ]+    EQ | isFloatOp o1 && isFloatOp o2 && isDoubleOp o1 && isDoubleOp o2 ->+      lines_ [+              text "\tfcmp.seq.d $fcc0," <+> pprOp platform o1 <> comma <+> pprOp platform o2,+              text "\tmovcf2gr" <+> pprOp platform dst <+> text ", $fcc0"+             ]+    EQ | isFloatOp o1 && isFloatOp o2 && isSingleOp o1 && isSingleOp o2 ->+      lines_ [+              text "\tfcmp.seq.s $fcc0," <+> pprOp platform o1 <> comma <+> pprOp platform o2,+              text "\tmovcf2gr" <+> pprOp platform dst <+> text ", $fcc0"+             ]+    -- SNE rd, rs -> [SUB rd, rd, rs;   sltu rd, zero, rs]+    NE | isIntOp o1 && isIntOp o2 ->+      lines_ [+              subFor o1 o2,+              text "\tsltu" <+> pprOp platform dst <> comma <+> text "$r0" <+> comma <+> pprOp platform dst+             ]+    NE | isFloatOp o1 && isFloatOp o2 && isDoubleOp o1 && isDoubleOp o2 ->+      lines_ [+              text "\tfcmp.cune.d $fcc0," <+> pprOp platform o1 <> comma <+> pprOp platform o2,+              text "\tmovcf2gr" <+> pprOp platform dst <+> text ", $fcc0"+             ]+    NE | isFloatOp o1 && isFloatOp o2 && isSingleOp o1 && isSingleOp o2 ->+      lines_ [+              text "\tfcmp.cune.s $fcc0," <+> pprOp platform o1 <> comma <+> pprOp platform o2,+              text "\tmovcf2gr" <+> pprOp platform dst <+> text ", $fcc0"+             ]+    SLT -> lines_ [ sltFor o1 o2 <+> pprOp platform dst <> comma <+> pprOp platform o1 <> comma <+> pprOp platform o2 ]+    -- SLE rd, rs -> [SLT rd, rs;  xori rd, rs, o1]+    SLE ->+      lines_ [+              sltFor o1 o2 <+> pprOp platform dst <> comma <+> pprOp platform o2 <> comma <+> pprOp platform o1,+              text "\txori" <+>  pprOp platform dst <> comma <+> pprOp platform dst <> comma <+> pprOp platform (OpImm (ImmInt 1))+             ]+    -- SGE rd, rs -> [SLT rd, rs;  xori rd, rs, o1]+    SGE ->+      lines_ [+              sltFor o1 o2 <+> pprOp platform dst <> comma <+> pprOp platform o1 <> comma <+> pprOp platform o2,+              text "\txori" <+>  pprOp platform dst <> comma <+> pprOp platform dst <> comma <+> pprOp platform (OpImm (ImmInt 1))+             ]+    -- SGT rd, rs -> [SLT rd, rs]+    SGT -> lines_ [ sltFor o1 o2 <+> pprOp platform dst <> comma <+> pprOp platform o2 <> comma <+> pprOp platform o1 ]++    ULT -> lines_ [ sltuFor o1 o2 <+> pprOp platform dst <> comma <+> pprOp platform o1 <> comma <+> pprOp platform o2 ]+    ULE ->+      lines_ [+              sltuFor o1 o2 <+> pprOp platform dst <> comma <+> pprOp platform o2 <> comma <+> pprOp platform o1,+              text "\txori" <+> pprOp platform dst <> comma <+> pprOp platform dst <> comma <+> pprOp platform (OpImm (ImmInt 1))+             ]+    -- UGE rd, rs -> [SLTU rd, rs;  xori rd, rs, 1]+    UGE ->+      lines_ [+              sltuFor o1 o2 <+> pprOp platform dst <> comma <+> pprOp platform o1 <> comma <+> pprOp platform o2,+              text "\txori" <+>  pprOp platform dst <> comma <+> pprOp platform dst <> comma <+> pprOp platform (OpImm (ImmInt 1))+             ]+    -- SGTU rd, rs -> [SLTU rd, rs]+    UGT -> lines_ [ sltuFor o1 o2 <+> pprOp platform dst <> comma <+> pprOp platform o2 <> comma <+> pprOp platform o1 ]++    -- TODO:+    -- LoongArch's floating point instrcutions don't write the compared result to an interger register, instead of cc.+    -- Fcond dst o1 o2 -> [fcmp.cond.[s/d] fcc0 o1 o2;  movcf2gr dst, fcc0]+    FLT | isFloatOp o1 && isFloatOp o2 && isDoubleOp o1 && isDoubleOp o2 ->+      lines_ [+              text "\tfcmp.slt.d $fcc0," <+> pprOp platform o1 <> comma <+> pprOp platform o2,+              text "\tmovcf2gr" <+> pprOp platform dst <+> text ", $fcc0"+             ]+    FLE | isFloatOp o1 && isFloatOp o2 && isDoubleOp o1 && isDoubleOp o2 ->+      lines_ [+              text "\tfcmp.sle.d $fcc0," <+> pprOp platform o1 <> comma <+> pprOp platform o2,+              text "\tmovcf2gr" <+> pprOp platform dst <+> text ", $fcc0"+             ]+    FGT | isFloatOp o1 && isFloatOp o2 && isDoubleOp o1 && isDoubleOp o2 ->+      lines_ [+              text "\tfcmp.slt.d $fcc0," <+> pprOp platform o2 <> comma <+> pprOp platform o1,+              text "\tmovcf2gr" <+> pprOp platform dst <+> text ", $fcc0"+             ]+    FGE | isFloatOp o1 && isFloatOp o2 && isDoubleOp o1 && isDoubleOp o2 ->+      lines_ [+              text "\tfcmp.sle.d $fcc0," <+> pprOp platform o2 <> comma <+> pprOp platform o1,+              text "\tmovcf2gr" <+> pprOp platform dst <+> text ", $fcc0"+             ]++    FLT | isFloatOp o1 && isFloatOp o2 && isSingleOp o1 && isSingleOp o2 ->+      lines_ [+              text "\tfcmp.slt.s $fcc0," <+> pprOp platform o1 <> comma <+> pprOp platform o2,+              text "\tmovcf2gr" <+> pprOp platform dst <+> text ", $fcc0"+             ]+    FLE | isFloatOp o1 && isFloatOp o2 && isSingleOp o1 && isSingleOp o2 ->+      lines_ [+              text "\tfcmp.sle.s $fcc0," <+> pprOp platform o1 <> comma <+> pprOp platform o2,+              text "\tmovcf2gr" <+> pprOp platform dst <+> text ", $fcc0"+             ]+    FGT | isFloatOp o1 && isFloatOp o2 && isSingleOp o1 && isSingleOp o2 ->+      lines_ [+              text "\tfcmp.slt.s $fcc0," <+> pprOp platform o2 <> comma <+> pprOp platform o1,+              text "\tmovcf2gr" <+> pprOp platform dst <+> text ", $fcc0"+             ]+    FGE | isFloatOp o1 && isFloatOp o2 && isSingleOp o1 && isSingleOp o2 ->+      lines_ [+              text "\tfcmp.sle.s $fcc0," <+> pprOp platform o2 <> comma <+> pprOp platform o1,+              text "\tmovcf2gr" <+> pprOp platform dst <+> text ", $fcc0"+             ]++    _ -> pprPanic "LA64.ppr: CSET error: " (pprCond cond <+> pprOp platform dst <> comma <+> (ppr (widthFromOpReg o1)) <+> pprOp platform o1 <+> (ppr (widthFromOpReg o2)) <+> pprOp platform o2)++    where+      subFor o1 o2  | (OpReg W64 _) <- dst, (OpImm _) <- o2  =+                        text "\taddi.d" <+> pprOp platform dst <> comma <+> pprOp platform o1 <> comma <+> pprOp platform (negOp o2)+                    | (OpReg W64 _) <- dst, (OpReg W64 _) <- o2 =+                        text "\tsub.d" <+> pprOp platform dst <> comma <+> pprOp platform o1 <> comma <+> pprOp platform o2+                    | otherwise = pprPanic "LA64.ppr: unknown subFor format: " ((ppr (widthFromOpReg dst)) <+> pprOp platform dst <+> (ppr (widthFromOpReg o1)) <+> pprOp platform o1 <+> (ppr (widthFromOpReg o2)) <+> pprOp platform o2)++      sltFor o1 o2  | (OpReg W64 _) <- dst, (OpImm _) <- o2   = text "\tslti"+                    | (OpReg W64 _) <- dst, (OpReg W64 _) <- o2 = text "\tslt"+                    | otherwise = pprPanic "LA64.ppr: unknown sltFor format: " ((ppr (widthFromOpReg dst)) <+> pprOp platform dst <+> (ppr (widthFromOpReg o1)) <+> pprOp platform o1 <+> (ppr (widthFromOpReg o2)) <+> pprOp platform o2)++      sltuFor o1 o2 | (OpReg W64 _) <- dst, (OpImm _) <- o2   = text "\tsltui"+                    | (OpReg W64 _) <- dst, (OpReg W64 _) <- o2 = text "\tsltu"+                    | otherwise = pprPanic "LA64.ppr: unknown sltuFor format: " ((ppr (widthFromOpReg dst)) <+> pprOp platform dst <+> (ppr (widthFromOpReg o1)) <+> pprOp platform o1 <+> (ppr (widthFromOpReg o2)) <+> pprOp platform o2)++    -- MUL.{W/D}, MULH, {W[U]/D[U]}, 'h' means high 32bit.+    -- MULW.D.W[U]+  MUL  o1 o2 o3+    | isFloatOp o1 && isFloatOp o2 && isFloatOp o3 && isSingleOp o1 && isSingleOp o2 && isSingleOp o3 -> op3 (text "\tfmul.s") o1 o2 o3+    | isFloatOp o1 && isFloatOp o2 && isFloatOp o3 && isDoubleOp o1 && isDoubleOp o2 && isDoubleOp o3 -> op3 (text "\tfmul.d") o1 o2 o3+    | OpReg W32 _ <- o2, OpReg W32 _ <- o3 -> op3 (text "\tmul.w") o1 o2 o3+    | OpReg W64 _ <- o2, OpReg W64 _ <- o3 -> op3 (text "\tmul.d") o1 o2 o3+    | otherwise -> pprPanic "LA64.ppr: MUL error: " ((ppr (widthFromOpReg o1)) <+> pprOp platform o1 <+> (ppr (widthFromOpReg o2)) <+> pprOp platform o2 <+> (ppr (widthFromOpReg o3)) <+> pprOp platform o3)+  MULW   o1 o2 o3+    | OpReg W32 _ <- o2, OpReg W32 _ <- o3 -> op3 (text "\tmulw.d.w") o1 o2 o3+    | otherwise -> pprPanic "LA64.ppr: MULW error: " ((ppr (widthFromOpReg o1)) <+> pprOp platform o1 <+> (ppr (widthFromOpReg o2)) <+> pprOp platform o2 <+> (ppr (widthFromOpReg o3)) <+> pprOp platform o3)+  MULWU  o1 o2 o3+    | OpReg W32 _ <- o2, OpReg W32 _ <- o3 -> op3 (text "\tmulw.d.wu") o1 o2 o3+    | otherwise -> pprPanic "LA64.ppr: MULWU error: " ((ppr (widthFromOpReg o1)) <+> pprOp platform o1 <+> (ppr (widthFromOpReg o2)) <+> pprOp platform o2 <+> (ppr (widthFromOpReg o3)) <+> pprOp platform o3)+  MULH  o1 o2 o3+    | OpReg W32 _ <- o2, OpReg W32 _ <- o3 -> op3 (text "\tmulh.w") o1 o2 o3+    | OpReg W64 _ <- o2, OpReg W64 _ <- o2 -> op3 (text "\tmulh.d") o1 o2 o3+    | otherwise -> pprPanic "LA64.ppr: MULH error: " ((ppr (widthFromOpReg o1)) <+> pprOp platform o1 <+> (ppr (widthFromOpReg o2)) <+> pprOp platform o2 <+> (ppr (widthFromOpReg o3)) <+> pprOp platform o3)+  MULHU  o1 o2 o3+    | OpReg W32 _ <- o2, OpReg W32 _ <- o3 -> op3 (text "\tmulh.wu") o1 o2 o3+    | OpReg W64 _ <- o2, OpReg W64 _ <- o3 -> op3 (text "\tmulh.du") o1 o2 o3+    | otherwise -> pprPanic "LA64.ppr: MULHU error: " ((ppr (widthFromOpReg o1)) <+> pprOp platform o1 <+> (ppr (widthFromOpReg o2)) <+> pprOp platform o2 <+> (ppr (widthFromOpReg o3)) <+> pprOp platform o3)+    -- DIV.{W[U]/D[U]}, MOD.{W[U]/D[U]}+  DIV  o1 o2 o3+    | isFloatOp o1 && isFloatOp o2 && isFloatOp o3 && isSingleOp o1 && isSingleOp o2 && isSingleOp o3 -> op3 (text "\tfdiv.s") o1 o2 o3+    | isFloatOp o1 && isFloatOp o2 && isFloatOp o3 && isDoubleOp o1 && isDoubleOp o2 && isDoubleOp o3 -> op3 (text "\tfdiv.d") o1 o2 o3+    | OpReg W32 _ <- o2, OpReg W32 _ <- o3 -> op3 (text "\tdiv.w") o1 o2 o3+    | OpReg W64 _ <- o2, OpReg W64 _ <- o3 -> op3 (text "\tdiv.d") o1 o2 o3+    | otherwise -> pprPanic "LA64.ppr: DIV error: " ((ppr (widthFromOpReg o1)) <+> pprOp platform o1 <+> (ppr (widthFromOpReg o2)) <+> pprOp platform o2 <+> (ppr (widthFromOpReg o3)) <+> pprOp platform o3)+  DIVU  o1 o2 o3+    | OpReg W32 _ <- o2, OpReg W32 _ <- o3 -> op3 (text "\tdiv.wu") o1 o2 o3+    | OpReg W64 _ <- o2, OpReg W64 _ <- o3 -> op3 (text "\tdiv.du") o1 o2 o3+    | otherwise -> pprPanic "LA64.ppr: DIVU error: " ((ppr (widthFromOpReg o1)) <+> pprOp platform o1 <+> (ppr (widthFromOpReg o2)) <+> pprOp platform o2 <+> (ppr (widthFromOpReg o3)) <+> pprOp platform o3)+  MOD  o1 o2 o3+    | OpReg W32 _ <- o2, OpReg W32 _ <- o3 -> op3 (text "\tmod.w") o1 o2 o3+    | OpReg W64 _ <- o2, OpReg W64 _ <- o3 -> op3 (text "\tmod.d") o1 o2 o3+    | otherwise -> pprPanic "LA64.ppr: MOD error: " ((ppr (widthFromOpReg o1)) <+> pprOp platform o1 <+> (ppr (widthFromOpReg o2)) <+> pprOp platform o2 <+> (ppr (widthFromOpReg o3)) <+> pprOp platform o3)+  MODU  o1 o2 o3+    | OpReg W32 _ <- o2, OpReg W32 _ <- o3 -> op3 (text "\tmod.wu") o1 o2 o3+    | OpReg W64 _ <- o2, OpReg W64 _ <- o3 -> op3 (text "\tmod.du") o1 o2 o3+    | otherwise -> pprPanic "LA64.ppr: MODU error: " ((ppr (widthFromOpReg o1)) <+> pprOp platform o1 <+> (ppr (widthFromOpReg o2)) <+> pprOp platform o2 <+> (ppr (widthFromOpReg o3)) <+> pprOp platform o3)+  -- 2. Bit-shift Instuctions --------------------------------------------------+    -- SLL.W, SRL.W, SRA.W, ROTR.W+    -- SLL.D, SRL.D, SRA.D, ROTR.D+    -- SLLI.W, SRLI.W, SRAI.W, ROTRI.W+    -- SLLI.D, SRLI.D, SRAI.D, ROTRI.D+  SLL  o1 o2 o3+    | OpReg W32 _ <- o2, OpReg W32 _ <- o3 -> op3 (text "\tsll.w") o1 o2 o3+    | OpReg W64 _ <- o2, OpReg W64 _ <- o3 -> op3 (text "\tsll.d") o1 o2 o3+    | OpReg W32 _ <- o2, isImmOp o3 ->+        lines_ [text "\tslli.w" <+> pprOp platform o1 <> comma <+> pprOp platform o2 <> comma <+> pprOp platform o3]+    | OpReg W64 _ <- o2, isImmOp o3 ->+        lines_ [text "\tslli.d" <+> pprOp platform o1 <> comma <+> pprOp platform o2 <> comma <+> pprOp platform o3]+    | otherwise -> pprPanic "LA64.ppr: SLL error: " ((ppr (widthFromOpReg o1)) <+> pprOp platform o1 <+> (ppr (widthFromOpReg o2)) <+> pprOp platform o2 <+> (ppr (widthFromOpReg o3)) <+> pprOp platform o3)+  SRL  o1 o2 o3+    | OpReg W32 _ <- o2, OpReg W32 _ <- o3 -> op3 (text "\tsrl.w") o1 o2 o3+    | OpReg W64 _ <- o2, OpReg W64 _ <- o3 -> op3 (text "\tsrl.d") o1 o2 o3+    | OpReg W32 _ <- o2, isImmOp o3 ->+        lines_ [text "\tsrli.w" <+> pprOp platform o1 <> comma <+> pprOp platform o2 <> comma <+> pprOp platform o3]+    | OpReg W64 _ <- o2, isImmOp o3 ->+        lines_ [text "\tsrli.d" <+> pprOp platform o1 <> comma <+> pprOp platform o2 <> comma <+> pprOp platform o3]+    | otherwise -> pprPanic "LA64.ppr: SRL error: " ((ppr (widthFromOpReg o1)) <+> pprOp platform o1 <+> (ppr (widthFromOpReg o2)) <+> pprOp platform o2 <+> (ppr (widthFromOpReg o3)) <+> pprOp platform o3)+  SRA  o1 o2 o3+    | OpReg W32 _ <- o2, OpReg W32 _ <- o3 -> op3 (text "\tsra.w") o1 o2 o3+    | OpReg W64 _ <- o2, OpReg W64 _ <- o3 -> op3 (text "\tsra.d") o1 o2 o3+    | OpReg W32 _ <- o2, isImmOp o3 ->+        lines_ [text "\tsrai.w" <+> pprOp platform o1 <> comma <+> pprOp platform o2 <> comma <+> pprOp platform o3]+    | OpReg W64 _ <- o2, isImmOp o3 ->+        lines_ [text "\tsrai.d" <+> pprOp platform o1 <> comma <+> pprOp platform o2 <> comma <+> pprOp platform o3]+    | otherwise -> pprPanic "LA64.ppr: SRA error: " ((ppr (widthFromOpReg o1)) <+> pprOp platform o1 <+> (ppr (widthFromOpReg o2)) <+> pprOp platform o2 <+> (ppr (widthFromOpReg o3)) <+> pprOp platform o3)+  ROTR  o1 o2 o3+    | OpReg W32 _ <- o2, OpReg W32 _ <- o3 -> op3 (text "\trotr.w") o1 o2 o3+    | OpReg W64 _ <- o2, OpReg W64 _ <- o3 -> op3 (text "\trotr.d") o1 o2 o3+    | OpReg W32 _ <- o2, isImmOp o3 ->+        lines_ [text "\trotri.w" <+> pprOp platform o1 <> comma <+> pprOp platform o2 <> comma <+> pprOp platform o3]+    | OpReg W64 _ <- o2, isImmOp o3 ->+        lines_ [text "\trotri.d" <+> pprOp platform o1 <> comma <+> pprOp platform o2 <> comma <+> pprOp platform o3]+    | otherwise -> pprPanic "LA64.ppr: ROTR error: " ((ppr (widthFromOpReg o1)) <+> pprOp platform o1 <+> (ppr (widthFromOpReg o2)) <+> pprOp platform o2 <+> (ppr (widthFromOpReg o3)) <+> pprOp platform o3)+  -- 3. Bit-manupulation Instructions ------------------------------------------+    -- EXT.W{B/H}+  EXT o1 o2+    | OpReg W8 _ <- o2  -> op2 (text "\text.w.b") o1 o2+    | OpReg W16 _ <- o2 -> op2 (text "\text.w.h") o1 o2+    | otherwise -> pprPanic "LA64.ppr: EXT error: " ((ppr (widthFromOpReg o1)) <+> pprOp platform o1 <+> (ppr (widthFromOpReg o2)) <+> pprOp platform o2)+    -- CL{O/Z}.{W/D}, CT{O/Z}.{W/D}+  CLO o1 o2+    | OpReg W32 _ <- o2 -> op2 (text "\tclo.w") o1 o2+    | OpReg W64 _ <- o2 -> op2 (text "\tclo.d") o1 o2+    | otherwise -> pprPanic "LA64.ppr: CLO error" (pprOp platform o1 <+> pprOp platform o2)+  CLZ o1 o2+    | OpReg W32 _ <- o2 -> op2 (text "\tclz.w") o1 o2+    | OpReg W64 _ <- o2 -> op2 (text "\tclz.d") o1 o2+    | otherwise -> pprPanic "LA64.ppr: CLZ error" (pprOp platform o1 <+> pprOp platform o2)+  CTO o1 o2+    | OpReg W32 _ <- o2 -> op2 (text "\tcto.w") o1 o2+    | OpReg W64 _ <- o2 -> op2 (text "\tcto.d") o1 o2+    | otherwise -> pprPanic "LA64.ppr: CTO error" (pprOp platform o1 <+> pprOp platform o2)+  CTZ o1 o2+    | OpReg W32 _ <- o2 -> op2 (text "\tctz.w") o1 o2+    | OpReg W64 _ <- o2 -> op2 (text "\tctz.d") o1 o2+    | otherwise -> pprPanic "LA64.ppr: CTZ error" (pprOp platform o1 <+> pprOp platform o2)+    -- BYTEPICK.{W/D} rd, rj, rk, sa2/sa3+  BYTEPICK o1 o2 o3 o4+    | OpReg W32 _ <- o2 -> op4 (text "\tbytepick.w") o1 o2 o3 o4+    | OpReg W64 _ <- o2 -> op4 (text "\tbytepick.d") o1 o2 o3 o4+    | otherwise -> pprPanic "LA64.ppr: BYTEPICK error" (pprOp platform o1 <+> pprOp platform o2 <+> pprOp platform o3 <+> pprOp platform o4)+    -- REVB.{2H/4H/2W/D}+  REVB2H o1 o2 -> op2 (text "\trevb.2h") o1 o2+  REVB4H o1 o2 -> op2 (text "\trevb.4h") o1 o2+  REVB2W o1 o2 -> op2 (text "\trevb.2w") o1 o2+  REVBD  o1 o2 -> op2 (text "\trevb.d") o1 o2+    -- REVH.{2W/D}+  REVH2W o1 o2 -> op2 (text "\trevh.2w") o1 o2+  REVHD o1 o2 -> op2 (text "\trevh.d") o1 o2+    -- BITREV.{4B/8B}+    -- BITREV.{W/D}+  BITREV4B o1 o2 -> op2 (text "\tbitrev.4b") o1 o2+  BITREV8B o1 o2 -> op2 (text "\tbitrev.8b") o1 o2+  BITREVW o1 o2 -> op2 (text "\tbitrev.w") o1 o2+  BITREVD o1 o2 -> op2 (text "\tbitrev.d") o1 o2+    -- BSTRINS.{W/D}+  BSTRINS II64 o1 o2 o3 o4 -> op4 (text "\tbstrins.d") o1 o2 o3 o4+  BSTRINS II32 o1 o2 o3 o4 -> op4 (text "\tbstrins.w") o1 o2 o3 o4+    -- BSTRPICK.{W/D}+  BSTRPICK II64 o1 o2 o3 o4 -> op4 (text "\tbstrpick.d") o1 o2 o3 o4+  BSTRPICK II32 o1 o2 o3 o4 -> op4 (text "\tbstrpick.w") o1 o2 o3 o4+    -- MASKEQZ rd, rj, rk:  if rk == 0 ? rd = 0 : rd = rj+  MASKEQZ o1 o2 o3 -> op3 (text "\tmaskeqz") o1 o2 o3+    -- MASKNEZ:  if rk == 0 ? rd = 0 : rd = rj+  MASKNEZ o1 o2 o3 -> op3 (text "\tmasknez") o1 o2 o3+  -- 4. Branch Instructions ----------------------------------------------------+    -- BEQ, BNE, BLT[U], BGE[U]   rj, rd, off16+    -- BEQZ, BNEZ   rj, off21+    -- B+    -- BL+    -- JIRL+    -- jr rd = jirl $zero, rd, 0: Commonly used for subroutine return.+  J (TReg r) -> line $ text "\tjirl" <+> text "$r0" <> comma <+> pprReg W64 r <> comma <+> text " 0"+  J_TBL _ _ r    -> pprInstr platform (B (TReg r))++  B (TBlock bid) -> line $ text "\tb" <+> pprAsmLabel platform (mkLocalBlockLabel (getUnique bid))+  B (TLabel lbl) -> line $ text "\tb" <+> pprAsmLabel platform lbl+  B (TReg r)     -> line $ text "\tjr" <+> pprReg W64 r++  BL (TBlock bid) _ -> line $ text "\tbl" <+> pprAsmLabel platform (mkLocalBlockLabel (getUnique bid))+  BL (TLabel lbl) _ -> line $ text "\tbl" <+> pprAsmLabel platform lbl+  BL (TReg r) _    -> line $ text "\tjirl" <+> text "$r1" <> comma <+> pprReg W64 r <> comma <+> text " 0"++  CALL (TBlock bid) _ -> line $ text "\tcall36" <+> pprAsmLabel platform (mkLocalBlockLabel (getUnique bid))+  CALL (TLabel lbl) _ -> line $ text "\tcall36" <+> pprAsmLabel platform lbl+  CALL (TReg r) _ -> line $ text "\tjirl" <+> text "$r1" <> comma <+> pprReg W64 r <> comma <+> text " 0"++  CALL36 (TBlock bid) -> line $ text "\tcall36" <+> pprAsmLabel platform (mkLocalBlockLabel (getUnique bid))+  CALL36 (TLabel lbl) -> line $ text "\tcall36" <+> pprAsmLabel platform lbl+  CALL36 _ -> panic "LA64.ppr: CALL36: Not to registers!"+  TAIL36 r (TBlock bid) -> line $ text "\ttail36" <+> pprOp platform r <> comma <+> pprAsmLabel platform (mkLocalBlockLabel (getUnique bid))+  TAIL36 r (TLabel lbl) -> line $ text "\ttail36" <+> pprOp platform r <> comma <+> pprAsmLabel platform lbl+  TAIL36 _ _ -> panic "LA64.ppr: TAIL36: Not to registers!"++  BCOND1 c j d (TBlock bid) -> case c of+    SLE ->+      line $ text "\tbge" <+> pprOp platform d <> comma <+> pprOp platform j <> comma <+> pprAsmLabel platform (mkLocalBlockLabel (getUnique bid))+    SGT ->+      line $ text "\tblt" <+> pprOp platform d <> comma <+> pprOp platform j <> comma <+> pprAsmLabel platform (mkLocalBlockLabel (getUnique bid))+    ULE ->+      line $ text "\tbgeu" <+> pprOp platform d <> comma <+> pprOp platform j <> comma <+> pprAsmLabel platform (mkLocalBlockLabel (getUnique bid))+    UGT ->+      line $ text "\tbltu" <+> pprOp platform d <> comma <+> pprOp platform j <> comma <+> pprAsmLabel platform (mkLocalBlockLabel (getUnique bid))+    _ -> line $ text "\t" <> pprBcond c <+> pprOp platform j <> comma <+> pprOp platform d <> comma <+> pprAsmLabel platform (mkLocalBlockLabel (getUnique bid))++  BCOND1 _ _ _ (TLabel _) -> panic "LA64.ppr: BCOND1: No conditional branching to TLabel!"++  BCOND1 _ _ _ (TReg _) -> panic "LA64.ppr: BCOND1: No conditional branching to registers!"++  -- Reuse t8(IP) register+  BCOND c j d (TBlock bid) -> case c of+    SLE ->+      lines_ [+              text "\tslt $t8, " <+> pprOp platform  d <> comma <+> pprOp platform j,+              text "\tbeqz $t8, " <+> pprAsmLabel platform (mkLocalBlockLabel (getUnique bid))+             ]+    SGT ->+      lines_ [+              text "\tslt $t8, " <+> pprOp platform  d <> comma <+> pprOp platform j,+              text "\tbnez $t8, " <+> pprAsmLabel platform (mkLocalBlockLabel (getUnique bid))+             ]+    ULE ->+      lines_ [+              text "\tsltu $t8, " <+> pprOp platform  d <> comma <+> pprOp platform j,+              text "\tbeqz $t8, " <+> pprAsmLabel platform (mkLocalBlockLabel (getUnique bid))+             ]+    UGT ->+      lines_ [+              text "\tsltu $t8, " <+> pprOp platform  d <> comma <+> pprOp platform j,+              text "\tbnez $t8, " <+> pprAsmLabel platform (mkLocalBlockLabel (getUnique bid))+             ]+    EQ ->+      lines_ [+              text "\tsub.d $t8, " <+> pprOp platform  j <> comma <+> pprOp platform d,+              text "\tbeqz $t8, " <+> pprAsmLabel platform (mkLocalBlockLabel (getUnique bid))+             ]+    NE ->+      lines_ [+              text "\tsub.d $t8, " <+> pprOp platform  j <> comma <+> pprOp platform d,+              text "\tbnez $t8, " <+> pprAsmLabel platform (mkLocalBlockLabel (getUnique bid))+             ]+    SLT ->+      lines_ [+              text "\tslt $t8, " <+> pprOp platform  j <> comma <+> pprOp platform d,+              text "\tbnez $t8, " <+> pprAsmLabel platform (mkLocalBlockLabel (getUnique bid))+             ]+    SGE ->+      lines_ [+              text "\tslt $t8, " <+> pprOp platform  j <> comma <+> pprOp platform d,+              text "\tbeqz $t8, " <+> pprAsmLabel platform (mkLocalBlockLabel (getUnique bid))+             ]+    ULT ->+      lines_ [+              text "\tsltu $t8, " <+> pprOp platform  j <> comma <+> pprOp platform d,+              text "\tbnez $t8, " <+> pprAsmLabel platform (mkLocalBlockLabel (getUnique bid))+             ]+    UGE ->+      lines_ [+              text "\tsltu $t8, " <+> pprOp platform  j <> comma <+> pprOp platform d,+              text "\tbeqz $t8, " <+> pprAsmLabel platform (mkLocalBlockLabel (getUnique bid))+             ]+    _ -> panic "LA64.ppr: BCOND: Unsupported cond!"++  BCOND _ _ _ (TLabel _) -> panic "LA64.ppr: BCOND: No conditional branching to TLabel!"++  BCOND _ _ _ (TReg _) -> panic "LA64.ppr: BCOND: No conditional branching to registers!"++  BEQZ j (TBlock bid) ->+    line $ text "\tbeqz" <+> pprOp platform j <> comma <+> pprAsmLabel platform (mkLocalBlockLabel (getUnique bid))+  BEQZ j (TLabel lbl) ->+    line $ text "\tbeqz" <+> pprOp platform j <> comma <+> pprAsmLabel platform lbl+  BEQZ _ (TReg _)     -> panic "LA64.ppr: BEQZ: No conditional branching to registers!"++  BNEZ j (TBlock bid) ->+    line $ text "\tbnez" <+> pprOp platform j <> comma <+> pprAsmLabel platform (mkLocalBlockLabel (getUnique bid))+  BNEZ j (TLabel lbl) ->+    line $ text "\tbnez" <+> pprOp platform j <> comma <+> pprAsmLabel platform lbl+  BNEZ _ (TReg _)     -> panic "LA64.ppr: BNEZ: No conditional branching to registers!"++  -- 5. Common Memory Access Instructions --------------------------------------+    -- LD.{B[U]/H[U]/W[U]/D}, ST.{B/H/W/D}: AddrRegImm+    -- LD: load, ST: store, x: offset in register, u: load unsigned imm.+    -- LD format dst src: 'src' means final address, not single register or immdiate.+  -- Load symbol's address+  LD _fmt o1 (OpImm (ImmIndex lbl' off)) | Just (_, lbl) <- dynamicLinkerLabelInfo lbl' ->+    lines_ [ text "\tpcalau12i" <+> pprOp platform o1 <> comma <+> text "%got_pc_hi20(" <> pprAsmLabel platform lbl <> text ")"+            , text "\tld.d"   <+> pprOp platform o1 <> comma <+> pprOp platform o1 <> comma <+> text "%got_pc_lo12(" <> pprAsmLabel platform lbl <> text ")"+            , text "\taddi.d"   <+> pprOp platform o1 <> comma <+> pprOp platform o1 <> comma <+> int off+           ]+  LD _fmt o1 (OpImm (ImmIndex lbl off)) | isForeignLabel lbl ->+    lines_ [ text "\tpcalau12i" <+> pprOp platform o1 <> comma <+> text "%got_pc_hi20(" <> pprAsmLabel platform lbl <> text ")"+            , text "\tld.d"   <+> pprOp platform o1 <> comma <+> pprOp platform o1 <> comma <+> text "%got_pc_lo12(" <> pprAsmLabel platform lbl <> text ")"+            , text "\taddi.d"   <+> pprOp platform o1 <> comma <+> pprOp platform o1 <> comma <+> int off+           ]+  LD _fmt o1 (OpImm (ImmIndex lbl off)) ->+    lines_ [ text "\tpcalau12i" <+> pprOp platform o1 <> comma <+> text "%pc_hi20(" <> pprAsmLabel platform lbl <> text ")"+            , text "\taddi.d"    <+> pprOp platform o1 <> comma <+> pprOp platform o1 <> comma <+> text "%pc_lo12(" <> pprAsmLabel platform lbl <> text ")"+            , text "\taddi.d"   <+> pprOp platform o1 <> comma <+> pprOp platform o1 <> comma <+> int off+           ]++  LD _fmt o1 (OpImm (ImmCLbl lbl')) | Just (_, lbl) <- dynamicLinkerLabelInfo lbl' ->+    lines_ [ text "\tpcalau12i" <+> pprOp platform o1 <> comma <+> text "%got_pc_hi20(" <> pprAsmLabel platform lbl <> text ")"+            , text "\tld.d"   <+> pprOp platform o1 <> comma <+> pprOp platform o1 <> comma <+> text "%got_pc_lo12(" <> pprAsmLabel platform lbl <> text ")"+           ]+  LD _fmt o1 (OpImm (ImmCLbl lbl)) | isForeignLabel lbl ->+    lines_ [ text "\tpcalau12i" <+> pprOp platform o1 <> comma <+> text "%got_pc_hi20(" <> pprAsmLabel platform lbl <> text ")"+            , text "\tld.d"   <+> pprOp platform o1 <> comma <+> pprOp platform o1 <> comma <+> text "%got_pc_lo12(" <> pprAsmLabel platform lbl <> text ")"+           ]+  LD _fmt o1 (OpImm (ImmCLbl lbl)) ->+    lines_ [ text "\tpcalau12i" <+> pprOp platform o1 <> comma <+> text "%pc_hi20(" <> pprAsmLabel platform lbl <> text ")"+            , text "\taddi.d"    <+> pprOp platform o1 <> comma <+> pprOp platform o1 <> comma <+> text "%pc_lo12(" <> pprAsmLabel platform lbl <> text ")"+           ]++  LD II8  o1 o2 -> op2 (text "\tld.b") o1 o2+  LD II16 o1 o2 -> op2 (text "\tld.h") o1 o2+  LD II32 o1 o2 -> op2 (text "\tld.w") o1 o2+  LD II64 o1 o2 -> op2 (text "\tld.d") o1 o2+  LD FF32 o1 o2 -> op2 (text "\tfld.s") o1 o2+  LD FF64 o1 o2 -> op2 (text "\tfld.d") o1 o2++  LDU II8  o1 o2 -> op2 (text "\tld.bu") o1 o2+  LDU II16 o1 o2 -> op2 (text "\tld.hu") o1 o2+  LDU II32 o1 o2 -> op2 (text "\tld.wu") o1 o2+  LDU II64 o1 o2 -> op2 (text "\tld.d") o1 o2   -- double words (64bit) cannot be sign extended by definition+  LDU FF32 o1 o2@(OpAddr (AddrReg _))       -> op2 (text "\tfld.s") o1 o2+  LDU FF32 o1 o2@(OpAddr (AddrRegImm _ _))  -> op2 (text "\tfld.s") o1 o2+  LDU FF64 o1 o2@(OpAddr (AddrReg _))       -> op2 (text "\tfld.d") o1 o2+  LDU FF64 o1 o2@(OpAddr (AddrRegImm _ _))  -> op2 (text "\tfld.d") o1 o2+  LDU f o1 o2 -> pprPanic "Unsupported unsigned load" ((text.show) f <+> pprOp platform o1 <+> pprOp platform o2)++  ST II8  o1 o2 -> op2 (text "\tst.b") o1 o2+  ST II16 o1 o2 -> op2 (text "\tst.h") o1 o2+  ST II32 o1 o2 -> op2 (text "\tst.w") o1 o2+  ST II64 o1 o2 -> op2 (text "\tst.d") o1 o2+  ST FF32 o1 o2 -> op2 (text "\tfst.s") o1 o2+  ST FF64 o1 o2 -> op2 (text "\tfst.d") o1 o2++    -- LDPTR.{W/D}, STPTR.{W/D}: AddrRegImm: AddrRegImm+  LDPTR II32 o1 o2 -> op2 (text "\tldptr.w") o1 o2+  LDPTR II64 o1 o2 -> op2 (text "\tldptr.d") o1 o2+  STPTR II32 o1 o2 -> op2 (text "\tstptr.w") o1 o2+  STPTR II64 o1 o2 -> op2 (text "\tstptr.d") o1 o2++    -- LDX.{B[U]/H[U]/W[U]/D}, STX.{B/H/W/D}: AddrRegReg+  LDX II8   o1 o2 -> op2 (text "\tldx.b")  o1 o2+  LDX II16  o1 o2 -> op2 (text "\tldx.h")  o1 o2+  LDX II32  o1 o2 -> op2 (text "\tldx.w")  o1 o2+  LDX II64  o1 o2 -> op2 (text "\tldx.d")  o1 o2+  LDX FF32  o1 o2 -> op2 (text "\tfldx.s") o1 o2+  LDX FF64  o1 o2 -> op2 (text "\tfldx.d") o1 o2+  LDXU II8  o1 o2 -> op2 (text "\tldx.bu") o1 o2+  LDXU II16 o1 o2 -> op2 (text "\tldx.hu") o1 o2+  LDXU II32 o1 o2 -> op2 (text "\tldx.wu") o1 o2+  LDXU II64 o1 o2 -> op2 (text "\tldx.d")  o1 o2+  STX II8   o1 o2 -> op2 (text "\tstx.b")  o1 o2+  STX II16  o1 o2 -> op2 (text "\tstx.h")  o1 o2+  STX II32  o1 o2 -> op2 (text "\tstx.w")  o1 o2+  STX II64  o1 o2 -> op2 (text "\tstx.d")  o1 o2+  STX FF32  o1 o2 -> op2 (text "\tfstx.s") o1 o2+  STX FF64  o1 o2 -> op2 (text "\tfstx.d") o1 o2++  PRELD h o1@(OpAddr (AddrRegImm _ _)) -> op2 (text "\tpreld") h o1+  -- 6. Bound Check Memory Access Instructions ---------------------------------+    -- LD{GT/LE}.{B/H/W/D}, ST{GT/LE}.{B/H/W/D}+  -- 7. Atomic Memory Access Instructions --------------------------------------+    -- AM{SWAP/ADD/AND/OR/XOR/MAX/MIN}[DB].{W/D}, AM{MAX/MIN}[_DB].{WU/DU}+    -- AM.{SWAP/ADD}[_DB].{B/H}+    -- AMCAS[_DB].{B/H/W/D}+    -- LL.{W/D}, SC.{W/D}+    -- SC.Q+    -- LL.ACQ.{W/D}, SC.REL.{W/D}+  -- 8. Barrier Instructions ---------------------------------------------------+    -- DBAR, IBAR+  DBAR h -> line $ text "\tdbar" <+> pprBarrierType h+  IBAR h -> line $ text "\tibar" <+> pprBarrierType h++    -- Floating-point convert precision+  FCVT o1@(OpReg W32 _) o2@(OpReg W64 _) -> op2 (text "\tfcvt.s.d") o1 o2+  FCVT o1@(OpReg W64 _) o2@(OpReg W32 _) -> op2 (text "\tfcvt.d.s") o1 o2+  FCVT o1 o2 -> pprPanic "LA64.pprInstr - impossible float conversion" $+                  line (pprOp platform o1 <> text "->" <> pprOp platform o2)+    -- Signed fixed-point convert to floating-point+    -- For LoongArch, ffint.* instructions's second operand must be float-pointing register,+    -- so we need one more operation.+    -- Also to tfint.*.+  SCVTF o1@(OpReg W32 _) o2@(OpReg W32 _) -> lines_+    [+      text "\tmovgr2fr.w" <+> pprOp platform o1 <> comma <+> pprOp platform o2,+      text "\tffint.s.w" <+> pprOp platform o1 <> comma <+> pprOp platform o1+    ]+  SCVTF o1@(OpReg W32 _) o2@(OpReg W64 _) -> lines_+    [+      text "\tmovgr2fr.d" <+> pprOp platform o1 <> comma <+> pprOp platform o2,+      text "\tffint.s.l" <+> pprOp platform o1 <> comma <+> pprOp platform o1+    ]+  SCVTF o1@(OpReg W64 _) o2@(OpReg W32 _) -> lines_+    [+      text "\tmovgr2fr.w" <+> pprOp platform o1 <> comma <+> pprOp platform o2,+      text "\tffint.d.w" <+> pprOp platform o1 <> comma <+> pprOp platform o1+    ]+  SCVTF o1@(OpReg W64 _) o2@(OpReg W64 _) -> lines_+    [+      text "\tmovgr2fr.d" <+> pprOp platform o1 <> comma <+> pprOp platform o2,+      text "\tffint.d.l" <+> pprOp platform o1 <> comma <+> pprOp platform o1+    ]+  SCVTF o1 o2 -> pprPanic "LA64.pprInstr - impossible integer to float conversion" $+                  line (pprOp platform o1 <> text "->" <> pprOp platform o2)++    -- Floating-point convert to signed integer, rounding toward zero+    -- TODO: FCVTZS will destroy src-floating register if the previous opertion+    -- includes this reg. So I'm just stupidly saving and restoring by adding+    -- an extra register.+  FCVTZS o1@(OpReg W32 _) o2@(OpReg W32 _) o3@(OpReg W32 _) -> lines_+    [+      text "\tfmov.s" <+> pprOp platform o2 <> comma <+> pprOp platform o3,+      text "\tftintrz.w.s" <+> pprOp platform o3 <> comma <+> pprOp platform o3,+      text "\tmovfr2gr.s" <+> pprOp platform o1 <> comma <+> pprOp platform o3,+      text "\tfmov.s" <+> pprOp platform o3 <> comma <+> pprOp platform o2+    ]+  FCVTZS o1@(OpReg W32 _) o2@(OpReg W64 _) o3@(OpReg W64 _) -> lines_+    [+      text "\tfmov.d" <+> pprOp platform o2 <> comma <+> pprOp platform o3,+      text "\tftintrz.w.d" <+> pprOp platform o3 <> comma <+> pprOp platform o3,+      text "\tmovfr2gr.s" <+> pprOp platform o1 <> comma <+> pprOp platform o3,+      text "\tfmov.s" <+> pprOp platform o3 <> comma <+> pprOp platform o2+    ]+  FCVTZS o1@(OpReg W64 _) o2@(OpReg W32 _) o3@(OpReg W32 _) -> lines_+    [+      text "\tfmov.s" <+> pprOp platform o2 <> comma <+> pprOp platform o3,+      text "\tftintrz.l.s" <+> pprOp platform o3 <> comma <+> pprOp platform o3,+      text "\tmovfr2gr.d" <+> pprOp platform o1 <> comma <+> pprOp platform o3,+      text "\tfmov.s" <+> pprOp platform o3 <> comma <+> pprOp platform o2+    ]+  FCVTZS o1@(OpReg W64 _) o2@(OpReg W64 _) o3@(OpReg W64 _) -> lines_+    [+      text "\tfmov.d" <+> pprOp platform o2 <> comma <+> pprOp platform o3,+      text "\tftintrz.l.d" <+> pprOp platform o3 <> comma <+> pprOp platform o3,+      text "\tmovfr2gr.d" <+> pprOp platform o1 <> comma <+> pprOp platform o3,+      text "\tfmov.d" <+> pprOp platform o3 <> comma <+> pprOp platform o2+    ]+  FCVTZS o1 o2 o3 -> pprPanic "LA64.pprInstr - impossible float to integer conversion" $+                   line (pprOp platform o3 <> text "->" <+> pprOp platform o1 <+> text "tmpReg:" <+> pprOp platform o2)++  FMIN o1 o2 o3  -> op3 (text "fmin." <> if isSingleOp o2 then text "s" else text "d") o1 o2 o3+  FMINA o1 o2 o3 -> op3 (text "fmina." <> if isSingleOp o2 then text "s" else text "d") o1 o2 o3+  FMAX o1 o2 o3  -> op3 (text "fmax." <> if isSingleOp o2 then text "s" else text "d") o1 o2 o3+  FMAXA o1 o2 o3 -> op3 (text "fmaxa." <> if isSingleOp o2 then text "s" else text "d") o1 o2 o3+  FABS o1 o2 -> op2 (text "fabs." <> if isSingleOp o2 then text "s" else text "d") o1 o2+  FNEG o1 o2 -> op2 (text "fneg." <> if isSingleOp o2 then text "s" else text "d") o1 o2+  FSQRT o1 o2 -> op2 (text "fsqrt." <> if isSingleOp o2 then text "s" else text "d") o1 o2+  FMA variant d o1 o2 o3 ->+    let fma = case variant of+                FMAdd   -> text "\tfmadd." <+> floatPrecission d+                FMSub   -> text "\tfmsub." <+> floatPrecission d+                FNMAdd  -> text "\tfnmadd." <+> floatPrecission d+                FNMSub  -> text "\tfnmsub." <+> floatPrecission d+    in op4 fma d o1 o2 o3++  instr -> panic $ "LA64.pprInstr - Unknown instruction: " ++ (instrCon instr)+  where op2 op o1 o2        = line $ op <+> pprOp platform o1 <> comma <+> pprOp platform o2+        op3 op o1 o2 o3     = line $ op <+> pprOp platform o1 <> comma <+> pprOp platform o2 <> comma <+> pprOp platform o3+        op4 op o1 o2 o3 o4  = line $ op <+> pprOp platform o1 <> comma <+> pprOp platform o2 <> comma <+> pprOp platform o3 <> comma <+> pprOp platform o4+{-+    -- TODO: Support dbar with different hints.+    On LoongArch uses "dbar 0" (full completion barrier) for everything.+    But the full completion barrier has no performance to tell, so+    Loongson-3A6000 and newer processors have made finer granularity hints+    available:++    Bit4: ordering or completion (0: completion, 1: ordering)+    Bit3: barrier for previous read (0: true, 1: false)+    Bit2: barrier for previous write (0: true, 1: false)+    Bit1: barrier for succeeding read (0: true, 1: false)+    Bit0: barrier for succeeding write (0: true, 1: false)+-}+        pprBarrierType Hint0 = text "0x0"+        floatPrecission o | isSingleOp o = text "s"+                          | isDoubleOp o = text "d"+                          | otherwise  = pprPanic "Impossible floating point precission: " (pprOp platform o)++-- LoongArch64 Conditional Branch Instructions+pprBcond :: IsLine doc => Cond -> doc+pprBcond c = text "b" <> pprCond c++pprCond :: IsLine doc => Cond -> doc+pprCond c = case c of+      EQ -> text "eq"     -- beq  rj, rd, off16+      NE -> text "ne"     -- bne  rj, rd, off16+      SLT -> text "lt"    -- blt  rj, rd, off16+      SGE -> text "ge"    -- bge  rj, rd, off16+      ULT -> text "ltu"   -- bltu rj, rd, off16+      UGE -> text "geu"   -- bgeu rj, rd, off16+      -- Following not real instructions, just mark it.+      SLE    -> text "sle->ge"   -- ble  rj, rd, off16 -> bge  rd, rj, off16+      SGT    -> text "sgt->lt"   -- bgt  rj, rd, off16 -> blt  rd, rj, off16+      ULE    -> text "ule->geu"  -- bleu rj, rd, off16 -> bgeu rd, rj, off16+      UGT    -> text "ugt->ltu"  -- bgtu rj, rd, off16 -> bltu rd, rj, off16+      _ -> panic $ "LA64.ppr: non-implemented branch condition: " ++ show c
+ GHC/CmmToAsm/LA64/RegInfo.hs view
@@ -0,0 +1,25 @@+-- Here maybe have something to be optimized in future?+module GHC.CmmToAsm.LA64.RegInfo where++import GHC.Cmm+import GHC.Cmm.BlockId+import GHC.CmmToAsm.LA64.Instr+import GHC.Prelude+import GHC.Utils.Outputable++newtype JumpDest = DestBlockId BlockId++instance Outputable JumpDest where+  ppr (DestBlockId bid) = text "jd<blk>:" <> ppr bid++getJumpDestBlockId :: JumpDest -> Maybe BlockId+getJumpDestBlockId (DestBlockId bid) = Just bid++canShortcut :: Instr -> Maybe JumpDest+canShortcut _ = Nothing++shortcutStatics :: (BlockId -> Maybe JumpDest) -> RawCmmStatics -> RawCmmStatics+shortcutStatics _ other_static = other_static++shortcutJump :: (BlockId -> Maybe JumpDest) -> Instr -> Instr+shortcutJump _ other = other
+ GHC/CmmToAsm/LA64/Regs.hs view
@@ -0,0 +1,155 @@+module GHC.CmmToAsm.LA64.Regs where++import GHC.Prelude+import GHC.Cmm+import GHC.Cmm.CLabel           ( CLabel )+import GHC.CmmToAsm.Format+import GHC.Data.FastString+import GHC.Platform+import GHC.Platform.Reg+import GHC.Platform.Reg.Class+import GHC.Platform.Reg.Class.Separate+import GHC.Platform.Regs+import GHC.Utils.Outputable+import GHC.Utils.Panic+import GHC.Types.Unique++-- All machine register numbers.+allMachRegNos :: [RegNo]+allMachRegNos = [0..31] ++ [32..63]++zeroReg, raReg, tpMachReg, fpMachReg, spMachReg, tmpReg :: Reg+zeroReg = regSingle 0+raReg = regSingle 1+tpMachReg = regSingle 2+-- Not to be confused with the `CmmReg` `spReg`+spMachReg = regSingle 3+fpMachReg = regSingle 22+-- Use t8(r20) for LA64 IP register.+tmpReg = regSingle 20++-- Registers available to the register allocator.+allocatableRegs :: Platform -> [RealReg]+allocatableRegs platform =+  let isFree = freeReg platform+   in map RealRegSingle $ filter isFree allMachRegNos++-- Integer argument registers according to the calling convention+allGpArgRegs :: [Reg]+allGpArgRegs = map regSingle [4..11]++-- | Floating point argument registers according to the calling convention+allFpArgRegs :: [Reg]+allFpArgRegs = map regSingle [32..39]++-- Addressing modes+data AddrMode+  = AddrRegReg Reg Reg+  | AddrRegImm Reg Imm+  | AddrReg Reg+  deriving (Eq, Show)++-- Immediates+data Imm+  = ImmInt      Int+  | ImmInteger  Integer     -- Sigh.+  | ImmCLbl     CLabel      -- AbstractC Label (with baggage)+  | ImmLit      FastString+  | ImmIndex    CLabel Int+  | ImmFloat    Rational+  | ImmDouble   Rational+  | ImmConstantSum Imm Imm+  | ImmConstantDiff Imm Imm+  deriving (Eq, Show)++-- Map CmmLit to Imm+litToImm :: CmmLit -> Imm+litToImm (CmmInt i w) = ImmInteger (narrowS w i)+-- narrow to the width: a CmmInt might be out of+-- range, but we assume that ImmInteger only contains+-- in-range values.  A signed value should be fine here.+litToImm (CmmFloat f W32) = ImmFloat f+litToImm (CmmFloat f W64) = ImmDouble f+litToImm (CmmLabel l)     = ImmCLbl l+litToImm (CmmLabelOff l off) = ImmIndex l off+litToImm (CmmLabelDiffOff l1 l2 off _) =+  ImmConstantSum+    (ImmConstantDiff (ImmCLbl l1) (ImmCLbl l2))+    (ImmInt off)+litToImm l = panic $ "LA64.Regs.litToImm: no match for " ++ show l++-- == To satisfy GHC.CmmToAsm.Reg.Target =======================================++-- squeese functions for the graph allocator -----------------------------------+-- | regSqueeze_class reg+--      Calculate the maximum number of register colors that could be+--      denied to a node of this class due to having this reg+--      as a neighbour.+--+{-# INLINE virtualRegSqueeze #-}+virtualRegSqueeze :: RegClass -> VirtualReg -> Int+virtualRegSqueeze cls vr+  = case cls of+    RcInteger ->+      case vr of+        VirtualRegI {} -> 1+        VirtualRegHi {} -> 1+        _other -> 0+    RcFloat ->+      case vr of+        VirtualRegD {} -> 1+        _other -> 0+    RcVector ->+      case vr of+        VirtualRegV128 {} -> 1+        _other -> 0++{-# INLINE realRegSqueeze #-}+realRegSqueeze :: RegClass -> RealReg -> Int+realRegSqueeze cls rr =+  case cls of+    RcInteger ->+      case rr of+        RealRegSingle regNo+          | regNo < 32+          -> 1+          | otherwise+          -> 0+    RcFloat ->+      case rr of+        RealRegSingle regNo+          |  regNo < 32+          || regNo > 63+          -> 0+          | otherwise+          -> 1+    RcVector ->+      case rr of+        RealRegSingle regNo+          | regNo > 63+          -> 1+          | otherwise+          -> 0++mkVirtualReg :: Unique -> Format -> VirtualReg+mkVirtualReg u format+   | not (isFloatFormat format) = VirtualRegI u+   | otherwise+   = case format of+        FF32    -> VirtualRegD u+        FF64    -> VirtualRegD u+        _       -> panic "LA64.mkVirtualReg"++{-# INLINE classOfRealReg #-}+classOfRealReg :: RealReg -> RegClass+classOfRealReg (RealRegSingle i)+   | i < 32 = RcInteger+   | i > 63 = RcVector+   | otherwise = RcFloat++regDotColor :: RealReg -> SDoc+regDotColor reg+ = case classOfRealReg reg of+        RcInteger       -> text "blue"+        RcFloat         -> text "red"+        RcVector        -> text "green"
GHC/CmmToAsm/PIC.hs view
@@ -137,6 +137,11 @@               addImport symbolPtr               return $ cmmMakePicReference config symbolPtr +        AccessViaSymbolPtr | ArchLoongArch64 <- platformArch platform -> do+              let symbolPtr = mkDynamicLinkerLabel SymbolPtr lbl+              addImport symbolPtr+              return $ cmmMakePicReference config symbolPtr+         AccessViaSymbolPtr -> do               let symbolPtr = mkDynamicLinkerLabel SymbolPtr lbl               addImport symbolPtr@@ -176,6 +181,9 @@    -- as on AArch64, there's no pic base register.   | ArchRISCV64 <- platformArch platform+  = CmmLit $ CmmLabel lbl++  | ArchLoongArch64 <- platformArch platform   = CmmLit $ CmmLabel lbl    | OSAIX <- platformOS platform
GHC/CmmToAsm/PPC/CodeGen.hs view
@@ -182,7 +182,7 @@               format = cmmTypeFormat ty      CmmUnsafeForeignCall target result_regs args-       -> genCCall platform target result_regs args+       -> genCCall target result_regs args      CmmBranch id          -> genBranch id     CmmCondBranch arg true false prediction -> do@@ -340,8 +340,6 @@   let Reg64 hi lo = localReg64 local_reg   return (RegCode64 nilOL hi lo) -iselExpr64 regoff@(CmmRegOff _ _) = iselExpr64 $ mangleIndexTree regoff- iselExpr64 (CmmLit (CmmInt i _)) = do   Reg64 rhi rlo <- getNewReg64   let@@ -471,27 +469,49 @@         return (Any II64 code)  -- catch simple cases of zero- or sign-extended load-getRegister' _ _ (CmmMachOp (MO_UU_Conv src tgt) [CmmLoad mem pk _])-  | src < tgt-  , cmmTypeFormat pk == intFormat src = loadZeroExpand mem pk tgt+getRegister' _ _ (CmmMachOp (MO_UU_Conv W8 W32) [CmmLoad mem _ _]) = do+    Amode addr addr_code <- getAmode D mem+    return (Any II32 (\dst -> addr_code `snocOL` LD II8 dst addr)) -getRegister' _ _ (CmmMachOp (MO_XX_Conv src tgt) [CmmLoad mem pk _])-  | src < tgt-  , cmmTypeFormat pk == intFormat src = loadZeroExpand mem pk tgt+getRegister' _ _ (CmmMachOp (MO_XX_Conv W8 W32) [CmmLoad mem _ _]) = do+    Amode addr addr_code <- getAmode D mem+    return (Any II32 (\dst -> addr_code `snocOL` LD II8 dst addr)) -  -- XXX: This is ugly, refactor-getRegister' _ _ (CmmMachOp (MO_SS_Conv src tgt) [CmmLoad mem pk _])-  -- Note: there is no Load Byte Arithmetic instruction-  | cmmTypeFormat pk /= II8-  , src < tgt = do-      let format = cmmTypeFormat pk-      -- lwa is DS-form. See Note [Power instruction format]-      let form = if format >= II32 then DS else D-      Amode addr addr_code <- getAmode form mem-      let code dst = assert (format == intFormat src)-                     $ addr_code `snocOL` LA format dst addr-      return (Any (intFormat tgt) code)+getRegister' _ _ (CmmMachOp (MO_UU_Conv W8 W64) [CmmLoad mem _ _]) = do+    Amode addr addr_code <- getAmode D mem+    return (Any II64 (\dst -> addr_code `snocOL` LD II8 dst addr)) +getRegister' _ _ (CmmMachOp (MO_XX_Conv W8 W64) [CmmLoad mem _ _]) = do+    Amode addr addr_code <- getAmode D mem+    return (Any II64 (\dst -> addr_code `snocOL` LD II8 dst addr))++-- Note: there is no Load Byte Arithmetic instruction, so no signed case here++getRegister' _ _ (CmmMachOp (MO_UU_Conv W16 W32) [CmmLoad mem _ _]) = do+    Amode addr addr_code <- getAmode D mem+    return (Any II32 (\dst -> addr_code `snocOL` LD II16 dst addr))++getRegister' _ _ (CmmMachOp (MO_SS_Conv W16 W32) [CmmLoad mem _ _]) = do+    Amode addr addr_code <- getAmode D mem+    return (Any II32 (\dst -> addr_code `snocOL` LA II16 dst addr))++getRegister' _ _ (CmmMachOp (MO_UU_Conv W16 W64) [CmmLoad mem _ _]) = do+    Amode addr addr_code <- getAmode D mem+    return (Any II64 (\dst -> addr_code `snocOL` LD II16 dst addr))++getRegister' _ _ (CmmMachOp (MO_SS_Conv W16 W64) [CmmLoad mem _ _]) = do+    Amode addr addr_code <- getAmode D mem+    return (Any II64 (\dst -> addr_code `snocOL` LA II16 dst addr))++getRegister' _ _ (CmmMachOp (MO_UU_Conv W32 W64) [CmmLoad mem _ _]) = do+    Amode addr addr_code <- getAmode D mem+    return (Any II64 (\dst -> addr_code `snocOL` LD II32 dst addr))++getRegister' _ _ (CmmMachOp (MO_SS_Conv W32 W64) [CmmLoad mem _ _]) = do+    -- lwa is DS-form. See Note [Power instruction format]+    Amode addr addr_code <- getAmode DS mem+    return (Any II64 (\dst -> addr_code `snocOL` LA II32 dst addr))+ getRegister' config platform (CmmMachOp (MO_RelaxedRead w) [e]) =       getRegister' config platform (CmmLoad e (cmmBits w) NaturallyAligned) @@ -641,11 +661,7 @@       MO_V_Add {} -> vectorsNeedLlvm       MO_V_Sub {} -> vectorsNeedLlvm       MO_V_Mul {} -> vectorsNeedLlvm-      MO_VS_Quot {} -> vectorsNeedLlvm-      MO_VS_Rem {} -> vectorsNeedLlvm       MO_VS_Neg {} -> vectorsNeedLlvm-      MO_VU_Quot {} -> vectorsNeedLlvm-      MO_VU_Rem {} -> vectorsNeedLlvm       MO_VF_Extract {} -> vectorsNeedLlvm       MO_VF_Add {} -> vectorsNeedLlvm       MO_VF_Sub {} -> vectorsNeedLlvm@@ -775,12 +791,6 @@ extendUExpr :: Width -> Width -> CmmExpr -> CmmExpr extendUExpr from to x = CmmMachOp (MO_UU_Conv from to) [x] -loadZeroExpand :: CmmExpr -> CmmType -> Width -> NatM Register-loadZeroExpand mem pk tgt = do-    Amode addr addr_code <- getAmode D mem-    let code dst = addr_code `snocOL` LD (cmmTypeFormat pk) dst addr-    return (Any (intFormat tgt) code)- -- ----------------------------------------------------------------------------- --  The 'Amode' type: Memory addressing modes passed up the tree. @@ -1190,25 +1200,24 @@ -- @get_arg@, which moves the arguments to the correct registers/stack -- locations.  Apart from that, the code is easy. -genCCall :: Platform-         -> ForeignTarget      -- function to call+genCCall :: ForeignTarget      -- function to call          -> [CmmFormal]        -- where to put the result          -> [CmmActual]        -- arguments (of mixed type)          -> NatM InstrBlock-genCCall _ (PrimTarget MO_AcquireFence) _ _+genCCall (PrimTarget MO_AcquireFence) _ _  = return $ unitOL LWSYNC-genCCall _ (PrimTarget MO_ReleaseFence) _ _+genCCall (PrimTarget MO_ReleaseFence) _ _  = return $ unitOL LWSYNC-genCCall _ (PrimTarget MO_SeqCstFence) _ _+genCCall (PrimTarget MO_SeqCstFence) _ _  = return $ unitOL HWSYNC -genCCall _ (PrimTarget MO_Touch) _ _+genCCall (PrimTarget MO_Touch) _ _  = return $ nilOL -genCCall _ (PrimTarget (MO_Prefetch_Data _)) _ _+genCCall (PrimTarget (MO_Prefetch_Data _)) _ _  = return $ nilOL -genCCall _ (PrimTarget (MO_AtomicRMW width amop)) [dst] [addr, n]+genCCall (PrimTarget (MO_AtomicRMW width amop)) [dst] [addr, n]  = do let fmt      = intFormat width           reg_dst  = getLocalRegReg dst       (instr, n_code) <- case amop of@@ -1258,7 +1267,7 @@                           (n_reg, n_code) <- getSomeReg n                           return  (op dst dst (RIReg n_reg), n_code) -genCCall _ (PrimTarget (MO_AtomicRead width _)) [dst] [addr]+genCCall (PrimTarget (MO_AtomicRead width _)) [dst] [addr]  = do let fmt      = intFormat width           reg_dst  = getLocalRegReg dst           form     = if widthInBits width == 64 then DS else D@@ -1285,12 +1294,12 @@ -- This is also what gcc does.  -genCCall _ (PrimTarget (MO_AtomicWrite width _)) [] [addr, val] = do+genCCall (PrimTarget (MO_AtomicWrite width _)) [] [addr, val] = do     code <- assignMem_IntCode (intFormat width) addr val     return $ unitOL HWSYNC `appOL` code -genCCall platform (PrimTarget (MO_Cmpxchg width)) [dst] [addr, old, new]-  | width == W32 || (width == W64 && not (target32Bit platform))+genCCall (PrimTarget (MO_Cmpxchg width)) [dst] [addr, old, new]+  | width == W32 || width == W64   = do       (old_reg, old_code) <- getSomeReg old       (new_reg, new_code) <- getSomeReg new@@ -1319,8 +1328,9 @@     format = intFormat width  -genCCall platform (PrimTarget (MO_Clz width)) [dst] [src]- = do let reg_dst = getLocalRegReg dst+genCCall (PrimTarget (MO_Clz width)) [dst] [src]+ = do platform <- getPlatform+      let reg_dst = getLocalRegReg dst       if target32Bit platform && width == W64         then do           RegCode64 code vr_hi vr_lo <- iselExpr64 src@@ -1368,8 +1378,9 @@           let cntlz = unitOL (CNTLZ format reg_dst reg)           return $ s_code `appOL` pre `appOL` cntlz `appOL` post -genCCall platform (PrimTarget (MO_Ctz width)) [dst] [src]- = do let reg_dst = getLocalRegReg dst+genCCall (PrimTarget (MO_Ctz width)) [dst] [src]+ = do platform <- getPlatform+      let reg_dst = getLocalRegReg dst       if target32Bit platform && width == W64         then do           let format = II32@@ -1431,8 +1442,9 @@                           , SUBFC dst r' (RIImm (ImmInt (format_bits)))                           ] -genCCall platform target dest_regs argsAndHints- = do case target of+genCCall target dest_regs argsAndHints+ = do platform <- getPlatform+      case target of         PrimTarget (MO_S_QuotRem  width) -> divOp1 True  width                                                    dest_regs argsAndHints         PrimTarget (MO_U_QuotRem  width) -> divOp1 False width@@ -2176,6 +2188,14 @@                     MO_AddIntC {}    -> unsupported                     MO_SubIntC {}    -> unsupported                     MO_U_Mul2 {}     -> unsupported+                    MO_VS_Quot {}    -> unsupported+                    MO_VS_Rem {}     -> unsupported+                    MO_VU_Quot {}    -> unsupported+                    MO_VU_Rem {}     -> unsupported+                    MO_I64X2_Min     -> unsupported+                    MO_I64X2_Max     -> unsupported+                    MO_W64X2_Min     -> unsupported+                    MO_W64X2_Max     -> unsupported                     MO_AcquireFence  -> unsupported                     MO_ReleaseFence  -> unsupported                     MO_SeqCstFence   -> unsupported@@ -2430,8 +2450,8 @@   let op_len = max W32 width       extend = if sgn then extendSExpr else extendUExpr   (src1, code1) <- getSomeReg (extend width op_len x)-  (src2, code2) <- getSomeReg y-+  (src2, code2) <- getSomeReg (extendUExpr width op_len y)+  -- Note: Shift amount `y` is unsigned   let code dst = code1 `appOL` code2 `snocOL`                  instr (intFormat op_len) dst src1 (RIReg src2)   return (Any (intFormat width) code)
GHC/CmmToAsm/PPC/Instr.hs view
@@ -1,5 +1,3 @@-{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-}- ----------------------------------------------------------------------------- -- -- Machine-dependent assembly language@@ -60,7 +58,7 @@ import Data.Foldable (toList) import qualified Data.List.NonEmpty as NE import GHC.Data.FastString (FastString)-import Data.Maybe (fromMaybe)+import GHC.Data.Maybe (expectJust, fromMaybe)   --------------------------------------------------------------------------------@@ -721,7 +719,7 @@             = BCCFAR cond tgt p             | otherwise             = BCC cond tgt p-            where Just targetAddr = lookupUFM blockAddressMap tgt+            where targetAddr = expectJust $ lookupUFM blockAddressMap tgt         makeFar _ other            = other          -- 8192 instructions are allowed; let's keep some distance, as
GHC/CmmToAsm/Ppr.hs view
@@ -1,6 +1,4 @@-{-# LANGUAGE CPP #-} {-# LANGUAGE MagicHash #-}-{-# LANGUAGE MultiWayIf #-}  ----------------------------------------------------------------------------- --@@ -16,7 +14,6 @@         pprASCII,         pprString,         pprFileEmbed,-        pprCOFFComdatKey,         pprSectionHeader ) @@ -26,7 +23,6 @@  import GHC.Utils.Asm import GHC.Cmm.CLabel-import GHC.Cmm.InitFini import GHC.Cmm import GHC.CmmToAsm.Config import GHC.Utils.Outputable as SDoc@@ -43,11 +39,6 @@ import GHC.Exts import GHC.Word -#if !MIN_VERSION_base(4,16,0)-word8ToWord# :: Word# -> Word#-word8ToWord# w = w-{-# INLINE word8ToWord# #-}-#endif  -- ----------------------------------------------------------------------------- -- Converting floating-point literals to integrals for printing@@ -229,8 +220,8 @@                     | otherwise -> text ".rodata"       RelocatableReadOnlyData | OSMinGW32 <- platformOS platform                                 -- Concept does not exist on Windows,-                                -- So map these to data.-                                          -> text ".data"+                                -- So map these to R/O data.+                                          -> text ".rdata$rel.ro"                               | otherwise -> text ".data.rel.ro"       UninitialisedData -> text ".bss"       InitArray@@ -247,74 +238,19 @@         | otherwise -> text ".rodata.str"       OtherSection _ ->         panic "PprBase.pprGNUSectionHeader: unknown section type"-    flags-      -- See-      -- https://github.com/llvm/llvm-project/blob/llvmorg-21.1.8/lld/COFF/Chunks.cpp#L54-      -- and https://llvm.org/docs/Extensions.html#section-directive.-      -- LLD COFF backend gc-sections only work on COMDAT sections so-      -- we need to mark it as a COMDAT section. You can use clang64-      -- toolchain to compile small examples with-      -- `-ffunction-sections -fdata-sections -S` to see these section-      -- headers in the wild. Also see Note [Split sections on COFF objects]-      -- below.-      | OSMinGW32 <- platformOS platform,-        splitSections =-          if-            | Just _ <- isInitOrFiniSection t -> text ",\"dw\""-            | otherwise ->-                let coff_section_flags-                      | Text <- t = "xr"-                      | UninitialisedData <- t = "bw"-                      | ReadOnlySection <- sectionProtection t = "dr"-                      | otherwise = "dw"-                 in hcat-                      [ text ",\"",-                        text coff_section_flags,-                        text "\",one_only,",-                        pprCOFFComdatKey platform suffix-                      ]-      | otherwise =-          case t of-            Text-              | splitSections-                          -> text ",\"ax\"," <> sectionType platform "progbits"-            CString-              | OSMinGW32 <- platformOS platform-                          -> empty-              | otherwise -> text ",\"aMS\"," <> sectionType platform "progbits" <> text ",1"-            _ -> empty+    flags = case t of+      Text+        | OSMinGW32 <- platformOS platform, splitSections+                    -> text ",\"xr\""+        | splitSections+                    -> text ",\"ax\"," <> sectionType platform "progbits"+      CString+        | OSMinGW32 <- platformOS platform+                    -> empty+        | otherwise -> text ",\"aMS\"," <> sectionType platform "progbits" <> text ",1"+      _ -> empty {-# SPECIALIZE pprGNUSectionHeader :: NCGConfig -> SectionType -> CLabel -> SDoc #-} {-# SPECIALIZE pprGNUSectionHeader :: NCGConfig -> SectionType -> CLabel -> HLine #-} -- see Note [SPECIALIZE to HDoc] in GHC.Utils.Outputable---- | Note [Split sections on COFF objects]--- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~------ On Windows/COFF, LLD's gc-sections only works on COMDAT sections,--- so we mark split sections as COMDAT and need to provide a unique--- "key" symbol.------ Important: We must not use a dot-prefixed local label (e.g.--- @.L...@) as the COMDAT key symbol, because LLVM's COFF assembler--- treats dot-prefixed COMDAT key symbols specially and forces them to--- have value 0 (the beginning of the section). That breaks--- @tablesNextToCode@, where the info label is intentionally placed--- after the info table data (at a non-zero offset).------ Therefore we generate a non-dot-prefixed key symbol derived from--- the section suffix, and (see arch-specific 'pprSectionAlign') we--- emit a label definition for it at the beginning of the section.------ ctor/dtor sections are specially treated; they must be emitted as--- regular data sections, otherwise LLD will drop them.------ Note that we must not emit .equiv directives for COMDAT sections in--- COFF objects, they seriously confuse LLD and we end up with access--- violations at runtimes.-pprCOFFComdatKey :: IsLine doc => Platform -> CLabel -> doc-pprCOFFComdatKey platform suffix =-  text "__ghc_coff_comdat_" <> pprAsmLabel platform suffix-{-# SPECIALIZE pprCOFFComdatKey :: Platform -> CLabel -> SDoc #-}-{-# SPECIALIZE pprCOFFComdatKey :: Platform -> CLabel -> HLine #-} -- see Note [SPECIALIZE to HDoc] in GHC.Utils.Outputable  -- XCOFF doesn't support relocating label-differences, so we place all -- RO sections into .text[PR] sections
GHC/CmmToAsm/RV64/CodeGen.hs view
@@ -1868,6 +1868,14 @@     MO_AddIntC _w -> unsupported mop     MO_SubIntC _w -> unsupported mop     MO_U_Mul2 _w -> unsupported mop+    MO_VS_Quot {} -> unsupported mop+    MO_VS_Rem {} -> unsupported mop+    MO_VU_Quot {} -> unsupported mop+    MO_VU_Rem {} -> unsupported mop+    MO_I64X2_Min -> unsupported mop+    MO_I64X2_Max -> unsupported mop+    MO_W64X2_Min -> unsupported mop+    MO_W64X2_Max -> unsupported mop     -- Memory Ordering     -- The related C functions are:     -- #include <stdatomic.h>
GHC/CmmToAsm/Reg/Graph.hs view
@@ -339,14 +339,14 @@ --   Conflicts between virtual and real regs are recorded as exclusions. graphAddConflictSet         :: Platform-        -> Regs+        -> UniqSet RegWithFormat         -> Color.Graph VirtualReg RegClass RealReg         -> Color.Graph VirtualReg RegClass RealReg  graphAddConflictSet platform regs graph  = let  arch = platformArch platform-        virtuals = takeVirtualRegs $ getRegs regs-        reals    = takeRealRegs $ getRegs regs+        virtuals = takeVirtualRegs regs+        reals    = takeRealRegs regs          graph1  = Color.addConflicts virtuals (classOfVirtualReg arch) graph           -- NB: we could add "arch" as argument to functions such as "addConflicts"
GHC/CmmToAsm/Reg/Graph/Base.hs view
@@ -30,6 +30,7 @@ import GHC.Builtin.Uniques import GHC.Utils.Monad (concatMapM) +import Data.List.NonEmpty (NonEmpty (..))  -- Some basic register classes. --      These aren't necessarily in 1-to-1 correspondence with the allocatable@@ -113,7 +114,7 @@         regsS_conflict                 = map (\s -> intersectUniqSets regsN (regAliasS s)) regsS -  in    maximum $ map sizeUniqSet $ regsS_conflict+  in    maximum $ 0 :| map sizeUniqSet regsS_conflict   -- | For a node N of classN and neighbors of classesC
GHC/CmmToAsm/Reg/Graph/Coalesce.hs view
@@ -13,8 +13,10 @@ import GHC.Data.Bag import GHC.Data.Graph.Directed import GHC.Platform (Platform)+import GHC.Types.Unique (getUnique) import GHC.Types.Unique.FM import GHC.Types.Unique.Supply+import GHC.Types.Unique.Set  -- | Do register coalescing on this top level thing --@@ -86,8 +88,8 @@         slurpLI    rs (LiveInstr _      Nothing)    = rs         slurpLI    rs (LiveInstr instr (Just live))                 | Just (r1, r2) <- takeRegRegMoveInstr platform instr-                , r1 `elemRegs` liveDieRead live-                , r2 `elemRegs` liveBorn live+                , elemUniqSet_Directly (getUnique r1) $ liveDieRead live+                , elemUniqSet_Directly (getUnique r2) $ liveBorn live                  -- only coalesce movs between two virtuals for now,                 -- else we end up with allocatable regs in the live
GHC/CmmToAsm/Reg/Graph/Spill.hs view
@@ -144,7 +144,7 @@         -- then record the fact that these slots are now live in those blocks         -- in the given slotmap.         patchLiveSlot-                :: BlockMap IntSet -> BlockId -> Regs -> BlockMap IntSet+                :: BlockMap IntSet -> BlockId -> UniqSet RegWithFormat-> BlockMap IntSet          patchLiveSlot slotMap blockId regsLive          = let@@ -154,8 +154,7 @@                  moreSlotsLive   = IntSet.fromList                                 $ mapMaybe (lookupUFM regSlotMap . regWithFormat_reg)-                                $ nonDetEltsUniqSet-                                $ getRegs regsLive+                                $ nonDetEltsUniqSet regsLive                     -- See Note [Unique Determinism and code generation]                  slotMap'
GHC/CmmToAsm/Reg/Graph/SpillClean.hs view
@@ -47,12 +47,13 @@ import GHC.Types.Unique.FM import GHC.Types.Unique import GHC.Builtin.Uniques+import GHC.Utils.Misc import GHC.Utils.Monad.State.Strict import GHC.Utils.Outputable import GHC.Utils.Panic import GHC.Cmm.Dataflow.Label -import Data.List (nub, foldl1', find)+import Data.List (nub, find) import Data.Maybe import Data.IntSet              (IntSet) import qualified Data.IntSet    as IntSet@@ -410,8 +411,7 @@         , sJumpValidAcc = emptyUFM }  intersects :: [Assoc Store]     -> Assoc Store-intersects []           = emptyAssoc-intersects assocs       = foldl1' intersectAssoc assocs+intersects = foldl1WithDefault' emptyAssoc intersectAssoc   -- | See if we have a reg with the same value as this slot in the association table.
GHC/CmmToAsm/Reg/Graph/SpillCost.hs view
@@ -36,8 +36,9 @@ import GHC.Utils.Monad.State.Strict import GHC.CmmToAsm.CFG import GHC.CmmToAsm.Format+import GHC.Utils.Misc -import Data.List        (nub, minimumBy)+import Data.List        (nub) import Data.Maybe import Control.Monad (join) @@ -101,7 +102,7 @@         countBlock info freqMap (BasicBlock blockId instrs)                 | LiveInfo _ _ blockLive _ <- info                 , Just rsLiveEntry  <- mapLookup blockId blockLive-                , rsLiveEntry_virt  <- takeVirtualRegs $ getRegs rsLiveEntry+                , rsLiveEntry_virt  <- takeVirtualRegs rsLiveEntry                 = countLIs (ceiling $ blockFreq freqMap blockId) rsLiveEntry_virt instrs                  | otherwise@@ -135,9 +136,9 @@                 mapM_ (incDefs scale) $ nub $ mapMaybe (takeVirtualReg . regWithFormat_reg) written                  -- Compute liveness for entry to next instruction.-                let liveDieRead_virt    = takeVirtualRegs $ getRegs (liveDieRead  live)-                let liveDieWrite_virt   = takeVirtualRegs $ getRegs (liveDieWrite live)-                let liveBorn_virt       = takeVirtualRegs $ getRegs (liveBorn     live)+                let liveDieRead_virt    = takeVirtualRegs (liveDieRead  live)+                let liveDieWrite_virt   = takeVirtualRegs (liveDieWrite live)+                let liveBorn_virt       = takeVirtualRegs (liveBorn     live)                  let rsLiveAcross                         = rsLiveEntry `minusUniqSet` liveDieRead_virt@@ -168,7 +169,7 @@ chooseSpill info graph  = let  cost    = spillCost_length info graph         node    = minimumBy (\n1 n2 -> compare (cost $ nodeId n1) (cost $ nodeId n2))-                $ nonDetEltsUFM $ graphMap graph+                $ expectNonEmpty $ nonDetEltsUFM $ graphMap graph                 -- See Note [Unique Determinism and code generation]     in   nodeId node
GHC/CmmToAsm/Reg/Graph/Stats.hs view
@@ -1,6 +1,3 @@--{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-}- -- | Carries interesting info for debugging / profiling of the --   graph coloring register allocator. module GHC.CmmToAsm.Reg.Graph.Stats (@@ -219,11 +216,10 @@  pprStatsSpills stats  = let-        finals  = [ s   | s@RegAllocStatsColored{} <- stats]+        finals  = [srms | RegAllocStatsColored{ raSRMs = srms } <- stats]          -- sum up how many stores\/loads\/reg-reg-moves were left in the code-        total   = foldl' addSRM (0, 0, 0)-                $ map raSRMs finals+        total   = foldl' addSRM (0, 0, 0) finals      in  (  text "-- spills-added-total"         $$ text "--    (stores, loads, reg_reg_moves_remaining)"@@ -237,8 +233,7 @@  pprStatsLifetimes stats  = let  info            = foldl' plusSpillCostInfo zeroSpillCostInfo-                                [ raSpillCosts s-                                        | s@RegAllocStatsStart{} <- stats ]+                          [ sc | RegAllocStatsStart{ raSpillCosts = sc } <- stats ]          lifeBins        = binLifetimeCount $ lifeMapFromSpillCostInfo info @@ -287,20 +282,21 @@ pprStatsLifeConflict stats graph  = let  lifeMap = lifeMapFromSpillCostInfo                 $ foldl' plusSpillCostInfo zeroSpillCostInfo-                $ [ raSpillCosts s | s@RegAllocStatsStart{} <- stats ]+                $ [ sc | RegAllocStatsStart{ raSpillCosts = sc } <- stats ] -        scatter = map   (\r ->  let lifetime  = case lookupUFM lifeMap r of-                                                      Just (_, l) -> l-                                                      Nothing     -> 0-                                    Just node = Color.lookupNode graph r-                                in parens $ hcat $ punctuate (text ", ")-                                        [ doubleQuotes $ ppr $ Color.nodeId node-                                        , ppr $ sizeUniqSet (Color.nodeConflicts node)-                                        , ppr $ lifetime ])-                $ map Color.nodeId-                $ nonDetEltsUFM+        scatter =+          [ let lifetime  = case lookupUFM lifeMap r of+                    Just (_, l) -> l+                    Nothing     -> 0+            in parens $ hcat $ punctuate (text ", ")+              [ doubleQuotes $ ppr $ Color.nodeId node+              , ppr $ sizeUniqSet (Color.nodeConflicts node)+              , ppr $ lifetime ]+          | node <- nonDetEltsUFM                 -- See Note [Unique Determinism and code generation]                 $ Color.graphMap graph+          , let r = Color.nodeId node+          ]     in   (  text "-- vreg-conflict-lifetime"         $$ text "--   (vreg, vreg_conflicts, vreg_lifetime)"
GHC/CmmToAsm/Reg/Graph/TrivColorable.hs view
@@ -148,7 +148,10 @@       Separate.RcInteger -> 14       Separate.RcFloat   -> 20       Separate.RcVector  -> 20-    ArchLoongArch64->panic "trivColorable ArchLoongArch64"+    ArchLoongArch64   -> case rc of+      Separate.RcInteger -> 16+      Separate.RcFloat   -> 24+      Separate.RcVector  -> 24     ArchJavaScript-> panic "trivColorable ArchJavaScript"     ArchWasm32    -> panic "trivColorable ArchWasm32"     ArchUnknown   -> panic "trivColorable ArchUnknown"
GHC/CmmToAsm/Reg/Linear.hs view
@@ -1,6 +1,4 @@ -{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-}- ----------------------------------------------------------------------------- -- -- The register allocator@@ -113,6 +111,7 @@ import qualified GHC.CmmToAsm.Reg.Linear.X86_64  as X86_64 import qualified GHC.CmmToAsm.Reg.Linear.AArch64 as AArch64 import qualified GHC.CmmToAsm.Reg.Linear.RV64    as RV64+import qualified GHC.CmmToAsm.Reg.Linear.LA64    as LA64 import GHC.CmmToAsm.Reg.Target import GHC.CmmToAsm.Reg.Liveness import GHC.CmmToAsm.Reg.Utils@@ -141,7 +140,7 @@  import Data.Containers.ListUtils import Data.Maybe-import Data.List (partition)+import Data.List (sortOn) import Control.Monad  -- -----------------------------------------------------------------------------@@ -178,8 +177,7 @@                  -- make sure the block that was first in the input list                 --      stays at the front of the output-                let !(!(!first':_), !rest')-                                = partition ((== first_id) . blockId) final_blocks+                let !final_blocks' = sortOn ((/= first_id) . blockId) final_blocks                  let max_spill_slots = maxSpillSlots config                     extra_stack@@ -188,7 +186,7 @@                       | otherwise                       = Nothing -                return  ( CmmProc info lbl live (ListGraph (first' : rest'))+                return  ( CmmProc info lbl live (ListGraph final_blocks')                         , extra_stack                         , Just stats) @@ -209,7 +207,7 @@         :: forall instr. (Instruction instr)         => NCGConfig         -> [BlockId] -- ^ entry points-        -> BlockMap Regs+        -> BlockMap (UniqSet RegWithFormat)               -- ^ live regs on entry to each basic block         -> [SCC (LiveBasicBlock instr)]               -- ^ instructions annotated with "deaths"@@ -228,7 +226,7 @@       ArchMipseb     -> panic "linearRegAlloc ArchMipseb"       ArchMipsel     -> panic "linearRegAlloc ArchMipsel"       ArchRISCV64    -> go (frInitFreeRegs platform :: RV64.FreeRegs)-      ArchLoongArch64-> panic "linearRegAlloc ArchLoongArch64"+      ArchLoongArch64 -> go $ (frInitFreeRegs platform :: LA64.FreeRegs)       ArchJavaScript -> panic "linearRegAlloc ArchJavaScript"       ArchWasm32     -> panic "linearRegAlloc ArchWasm32"       ArchUnknown    -> panic "linearRegAlloc ArchUnknown"@@ -248,7 +246,7 @@         => NCGConfig         -> freeRegs         -> [BlockId]                    -- ^ entry points-        -> BlockMap Regs              -- ^ live regs on entry to each basic block+        -> BlockMap (UniqSet RegWithFormat)              -- ^ live regs on entry to each basic block         -> [SCC (LiveBasicBlock instr)] -- ^ instructions annotated with "deaths"         -> UniqDSM ([NatBasicBlock instr], RegAllocStats, Int) @@ -262,7 +260,7 @@  linearRA_SCCs :: OutputableRegConstraint freeRegs instr               => [BlockId]-              -> BlockMap Regs+              -> BlockMap (UniqSet RegWithFormat)               -> [NatBasicBlock instr]               -> [SCC (LiveBasicBlock instr)]               -> RegM freeRegs [NatBasicBlock instr]@@ -297,7 +295,7 @@  process :: forall freeRegs instr. (OutputableRegConstraint freeRegs instr)         => [BlockId]-        -> BlockMap Regs+        -> BlockMap (UniqSet RegWithFormat)         -> [GenBasicBlock (LiveInstr instr)]         -> RegM freeRegs [[NatBasicBlock instr]] process entry_ids block_live =@@ -336,7 +334,7 @@ -- processBlock         :: OutputableRegConstraint freeRegs instr-        => BlockMap Regs              -- ^ live regs on entry to each basic block+        => BlockMap (UniqSet RegWithFormat)              -- ^ live regs on entry to each basic block         -> LiveBasicBlock instr         -- ^ block to do register allocation on         -> RegM freeRegs [NatBasicBlock instr]   -- ^ block with registers allocated @@ -353,7 +351,7 @@ -- | Load the freeregs and current reg assignment into the RegM state --      for the basic block with this BlockId. initBlock :: FR freeRegs-          => BlockId -> BlockMap Regs -> RegM freeRegs ()+          => BlockId -> BlockMap (UniqSet RegWithFormat) -> RegM freeRegs () initBlock id block_live  = do   platform    <- getPlatform         block_assig <- getBlockAssigR@@ -370,7 +368,7 @@                             setFreeRegsR    (frInitFreeRegs platform)                           Just live ->                             setFreeRegsR $ foldl' (flip $ frAllocateReg platform) (frInitFreeRegs platform)-                                                  (nonDetEltsUniqSet $ takeRealRegs $ getRegs live)+                                                  (nonDetEltsUniqSet $ takeRealRegs live)                             -- See Note [Unique Determinism and code generation]                         setAssigR       emptyRegMap @@ -383,7 +381,7 @@ -- | Do allocation for a sequence of instructions. linearRA         :: forall freeRegs instr. (OutputableRegConstraint freeRegs instr)-        => BlockMap Regs                      -- ^ map of what vregs are live on entry to each block.+        => BlockMap (UniqSet RegWithFormat)                      -- ^ map of what vregs are live on entry to each block.         -> BlockId                              -- ^ id of the current block, for debugging.         -> [LiveInstr instr]                    -- ^ liveness annotated instructions in this block.         -> RegM freeRegs@@ -408,7 +406,7 @@ -- | Do allocation for a single instruction. raInsn         :: OutputableRegConstraint freeRegs instr-        => BlockMap Regs                         -- ^ map of what vregs are live on entry to each block.+        => BlockMap (UniqSet RegWithFormat)                      -- ^ map of what vregs are love on entry to each block.         -> [instr]                              -- ^ accumulator for instructions already processed.         -> BlockId                              -- ^ the id of the current block, for debugging         -> LiveInstr instr                      -- ^ the instr to have its regs allocated, with liveness info.@@ -429,7 +427,7 @@ raInsn block_live new_instrs id (LiveInstr (Instr instr) (Just live))  = do     platform <- getPlatform-    assig    <- getAssigR+    assig    <- getAssigR :: RegM freeRegs (UniqFM Reg Loc)      -- If we have a reg->reg move between virtual registers, where the     -- src register is not live after this instruction, and the dst@@ -439,12 +437,12 @@     -- (we can't eliminate it if the source register is on the stack, because     --  we do not want to use one spill slot for different virtual registers)     case takeRegRegMoveInstr platform instr of-        Just (src,dst)  | Just fmt <- lookupReg src (liveDieRead live),+        Just (src,dst)  | Just (RegWithFormat _ fmt) <- lookupUniqSet_Directly (liveDieRead live) (getUnique src),                           isVirtualReg dst,                           not (dst `elemUFM` assig),                           isRealReg src || isInReg src assig -> do            case src of-              RegReal rr -> setAssigR (addToUFM assig dst (Loc (InReg rr) fmt))+              RegReal rr -> setAssigR (addToUFM assig dst (InReg $ RealRegUsage rr fmt))                 -- if src is a fixed reg, then we just map dest to this                 -- reg in the assignment.  src must be an allocatable reg,                 -- otherwise it wouldn't be in r_dying.@@ -463,8 +461,8 @@            return (new_instrs, [])          _ -> genRaInsn block_live new_instrs id instr-                        (map regWithFormat_reg $ nonDetEltsUniqSet $ getRegs $ liveDieRead live)-                        (map regWithFormat_reg $ nonDetEltsUniqSet $ getRegs $ liveDieWrite live)+                        (map regWithFormat_reg $ nonDetEltsUniqSet $ liveDieRead live)+                        (map regWithFormat_reg $ nonDetEltsUniqSet $ liveDieWrite live)                         -- See Note [Unique Determinism and code generation]  raInsn _ _ _ instr@@ -487,16 +485,13 @@   isInReg :: Reg -> RegMap Loc -> Bool-isInReg src assig-  | Just (Loc (InReg _) _) <- lookupUFM assig src-  = True-  | otherwise-  = False+isInReg src assig | Just (InReg _) <- lookupUFM assig src = True+                  | otherwise = False   genRaInsn :: forall freeRegs instr.              (OutputableRegConstraint freeRegs instr)-          => BlockMap Regs+          => BlockMap (UniqSet RegWithFormat)           -> [instr]           -> BlockId           -> instr@@ -509,8 +504,8 @@   platform <- getPlatform   case regUsageOfInstr platform instr of { RU read written ->     do-    let real_written = [ rr                          | RegWithFormat {regWithFormat_reg = RegReal rr} <- written ]-    let virt_written = [ VirtualRegWithFormat vr fmt | RegWithFormat (RegVirtual vr) fmt              <- written ]+    let real_written = [ rr                      | RegWithFormat {regWithFormat_reg = RegReal rr} <- written ]+    let virt_written = [ VirtualRegWithFormat vr fmt | RegWithFormat (RegVirtual vr) fmt         <- written ]      -- we don't need to do anything with real registers that are     -- only read by this instr.  (the list is typically ~2 elements,@@ -648,16 +643,14 @@       loop assig !free (RegReal rr : rs) = loop assig (frReleaseReg platform rr free) rs       loop assig !free (r:rs) =          case lookupUFM assig r of-         Just (Loc (InBoth real _) _) ->-           loop (delFromUFM assig r)-                (frReleaseReg platform real free) rs-         Just (Loc (InReg real) _) ->-           loop (delFromUFM assig r)-                (frReleaseReg platform real free) rs-         _ ->-           loop (delFromUFM assig r) free rs+         Just (InBoth real _) -> loop (delFromUFM assig r)+                                      (frReleaseReg platform (realReg real) free) rs+         Just (InReg real)    -> loop (delFromUFM assig r)+                                      (frReleaseReg platform (realReg real) free) rs+         _                    -> loop (delFromUFM assig r) free rs   loop assig free regs + -- ----------------------------------------------------------------------------- -- Clobber real registers @@ -675,18 +668,17 @@ saveClobberedTemps         :: forall instr freeRegs.            (Instruction instr, FR freeRegs)-        => [RealReg]             -- ^ real registers clobbered by this instruction-        -> [Reg]                 -- ^ registers which are no longer live after this instruction,-                                 -- because read for the last time-        -> RegM freeRegs [instr] -- return: instructions to spill any temps that will-                                 -- be clobbered.+        => [RealReg]            -- real registers clobbered by this instruction+        -> [Reg]                -- registers which are no longer live after this insn+        -> RegM freeRegs [instr]         -- return: instructions to spill any temps that will+                                -- be clobbered.  saveClobberedTemps [] _         = return []  saveClobberedTemps clobbered dying  = do-        assig   <- getAssigR+        assig   <- getAssigR :: RegM freeRegs (UniqFM Reg Loc)         (assig',instrs) <- nonDetStrictFoldUFM_DirectlyM maybe_spill (assig,[]) assig         setAssigR assig'         return $ -- mkComment (text "<saveClobberedTemps>") ++@@ -695,21 +687,19 @@    where      -- Unique represents the VirtualReg      -- Here we separate the cases which we do want to spill from these we don't.-     maybe_spill :: Unique-                 -> (RegMap Loc,[instr])-                 -> Loc-                 -> RegM freeRegs (RegMap Loc,[instr])+     maybe_spill :: Unique -> (RegMap Loc,[instr]) -> (Loc) -> RegM freeRegs (RegMap Loc,[instr])      maybe_spill !temp !(assig,instrs) !loc =         case loc of                 -- This is non-deterministic but we do not                 -- currently support deterministic code-generation.                 -- See Note [Unique Determinism and code generation]-                Loc (InReg reg) fmt-                    | any (realRegsAlias reg) clobbered+                InReg reg+                    | any (realRegsAlias $ realReg reg) clobbered                     , temp `notElem` map getUnique dying-                    -> clobber temp (assig,instrs) (RealRegUsage reg fmt)+                    -> clobber temp (assig,instrs) reg                 _ -> return (assig,instrs) +      -- See Note [UniqFM and the register allocator]      clobber :: Unique -> (RegMap Loc,[instr]) -> RealRegUsage -> RegM freeRegs (RegMap Loc,[instr])      clobber temp (assig,instrs) (RealRegUsage reg fmt)@@ -728,7 +718,7 @@               (my_reg : _) -> do                   setFreeRegsR (frAllocateReg platform my_reg freeRegs) -                  let new_assign = addToUFM_Directly assig temp (Loc (InReg my_reg) fmt)+                  let new_assign = addToUFM_Directly assig temp (InReg (RealRegUsage my_reg fmt))                   let instr = mkRegRegMoveInstr config fmt                                   (RegReal reg) (RegReal my_reg) @@ -736,13 +726,12 @@                -- (2) no free registers: spill the value               [] -> do-                   (spill, slot)   <- spillR (RegWithFormat (RegReal reg) fmt) temp                    -- record why this reg was spilled for profiling                   recordSpill (SpillClobber temp) -                  let new_assign  = addToUFM_Directly assig temp (Loc (InBoth reg slot) fmt)+                  let new_assign  = addToUFM_Directly assig temp (InBoth (RealRegUsage reg fmt) slot)                    return (new_assign, (spill ++ instrs)) @@ -790,9 +779,9 @@         clobber assig []                 = assig -        clobber assig ((temp, Loc (InBoth reg slot) regFmt) : rest)-                | any (realRegsAlias reg) clobbered-                = clobber (addToUFM_Directly assig temp (Loc (InMem slot) regFmt)) rest+        clobber assig ((temp, InBoth reg slot) : rest)+                | any (realRegsAlias $ realReg reg) clobbered+                = clobber (addToUFM_Directly assig temp (InMem slot)) rest          clobber assig (_:rest)                 = clobber assig rest@@ -801,9 +790,9 @@ -- allocateRegsAndSpill  -- Why are we performing a spill?-data SpillLoc = ReadMem StackSlot Format -- reading from register only in memory-              | WriteNew                 -- writing to a new variable-              | WriteMem                 -- writing to register only in memory+data SpillLoc = ReadMem StackSlot  -- reading from register only in memory+              | WriteNew           -- writing to a new variable+              | WriteMem           -- writing to register only in memory -- Note that ReadNew is not valid, since you don't want to be reading -- from an uninitialized register.  We also don't need the location of -- the register in memory, since that will be invalidated by the write.@@ -829,36 +818,28 @@ allocateRegsAndSpill _       _    spills alloc []         = return (spills, reverse alloc) -allocateRegsAndSpill reading keep spills alloc (r@(VirtualRegWithFormat vr vrFmt):rs)+allocateRegsAndSpill reading keep spills alloc (r@(VirtualRegWithFormat vr _fmt):rs)  = do   assig <- toVRegMap <$> getAssigR         -- pprTraceM "allocateRegsAndSpill:assig" (ppr (r:rs) $$ ppr assig)         -- See Note [UniqFM and the register allocator]         let doSpill = allocRegsAndSpill_spill reading keep spills alloc r rs assig         case lookupUFM assig vr of                 -- case (1a): already in a register-                Just (Loc (InReg my_reg) in_reg_fmt) -> do-                  -- (RF1) from Note [Allocated register formats]:-                  -- writes redefine the format the register is used at.-                  when (not reading && vrFmt /= in_reg_fmt) $-                    setAssigR $ toRegMap $-                      addToUFM assig vr (Loc (InReg my_reg) vrFmt)-                  allocateRegsAndSpill reading keep spills (my_reg:alloc) rs+                Just (InReg my_reg) ->+                        allocateRegsAndSpill reading keep spills (realReg my_reg:alloc) rs                  -- case (1b): already in a register (and memory)-                Just (Loc (InBoth my_reg _) _) -> do-                  -- NB1. if we're writing this register, update its assignment to be-                  -- InReg, because the memory value is no longer valid.-                  -- NB2. This is why we must process written registers here, even if they-                  -- are also read by the same instruction.-                  when (not reading) $-                    setAssigR $ toRegMap $-                      addToUFM assig vr (Loc (InReg my_reg) vrFmt)-                  allocateRegsAndSpill reading keep spills (my_reg:alloc) rs+                -- NB1. if we're writing this register, update its assignment to be+                -- InReg, because the memory value is no longer valid.+                -- NB2. This is why we must process written registers here, even if they+                -- are also read by the same instruction.+                Just (InBoth my_reg _)+                 -> do  when (not reading) (setAssigR $ toRegMap (addToUFM assig vr (InReg my_reg)))+                        allocateRegsAndSpill reading keep spills (realReg my_reg:alloc) rs                  -- Not already in a register, so we need to find a free one...-                Just (Loc (InMem slot) memFmt)-                   | reading   -> doSpill (ReadMem slot memFmt)-                   | otherwise -> doSpill WriteMem+                Just (InMem slot) | reading   -> doSpill (ReadMem slot)+                                  | otherwise -> doSpill WriteMem                 Nothing | reading   ->                    pprPanic "allocateRegsAndSpill: Cannot read from uninitialized register" (ppr vr)                    -- NOTE: if the input to the NCG contains some@@ -894,7 +875,7 @@                         -> UniqFM VirtualReg Loc                         -> SpillLoc                         -> RegM freeRegs ([instr], [RealReg])-allocRegsAndSpill_spill reading keep spills alloc r@(VirtualRegWithFormat vr vrFmt) rs assig spill_loc+allocRegsAndSpill_spill reading keep spills alloc r@(VirtualRegWithFormat vr fmt) rs assig spill_loc  = do   platform <- getPlatform         freeRegs <- getFreeRegsR         let regclass = classOfVirtualReg (platformArch platform) vr@@ -916,7 +897,7 @@                 spills'   <- loadTemp r spill_loc final_reg spills                  setAssigR $ toRegMap-                          $ (addToUFM assig vr $! newLocation spill_loc $ RealRegUsage final_reg vrFmt)+                          $ (addToUFM assig vr $! newLocation spill_loc $ RealRegUsage final_reg fmt)                 setFreeRegsR $  frAllocateReg platform final_reg freeRegs                  allocateRegsAndSpill reading keep spills' (final_reg : alloc) rs@@ -930,7 +911,7 @@                 let candidates' :: UniqFM VirtualReg Loc                     candidates' =                       flip delListFromUFM (fmap virtualRegWithFormat_reg keep) $-                      filterUFM (inRegOrBoth . locWithFormat_loc) $+                      filterUFM inRegOrBoth $                       assig                       -- This is non-deterministic but we do not                       -- currently support deterministic code-generation.@@ -943,54 +924,50 @@                       == regclass                     candidates_inBoth :: [(Unique, RealRegUsage, StackSlot)]                     candidates_inBoth-                        = [ (temp, RealRegUsage reg fmt, mem)-                          | (temp, Loc (InBoth reg mem) fmt) <- candidates-                          , compat reg ]+                        = [ (temp, reg, mem)+                          | (temp, InBoth reg mem) <- candidates+                          , compat (realReg reg) ]                  -- the vregs we could kick out that are only in a reg                 --      this would require writing the reg to a new slot before using it.                 let candidates_inReg-                        = [ (temp, RealRegUsage reg fmt)-                          | (temp, Loc (InReg reg) fmt) <- candidates-                          , compat reg ]+                        = [ (temp, reg)+                          | (temp, InReg reg) <- candidates+                          , compat (realReg reg) ]                  let result                          -- we have a temporary that is in both register and mem,                         -- just free up its register for use.-                        | (temp, (RealRegUsage cand_reg old_fmt), slot) : _ <- candidates_inBoth-                        = do    spills' <- loadTemp r spill_loc cand_reg spills-                                let assig1  = addToUFM_Directly assig temp $ Loc (InMem slot) old_fmt-                                let assig2  = addToUFM assig1 vr $! newLocation spill_loc (RealRegUsage cand_reg vrFmt)+                        | (temp, (RealRegUsage my_reg _old_fmt), slot) : _ <- candidates_inBoth+                        = do    spills' <- loadTemp r spill_loc my_reg spills+                                let assig1  = addToUFM_Directly assig temp (InMem slot)+                                let assig2  = addToUFM assig1 vr $! newLocation spill_loc (RealRegUsage my_reg fmt)                                  setAssigR $ toRegMap assig2-                                allocateRegsAndSpill reading keep spills' (cand_reg:alloc) rs+                                allocateRegsAndSpill reading keep spills' (my_reg:alloc) rs                          -- otherwise, we need to spill a temporary that currently                         -- resides in a register.-                        | (temp_to_push_out, RealRegUsage cand_reg old_reg_fmt) : _+                        | (temp_to_push_out, RealRegUsage my_reg fmt) : _                                         <- candidates_inReg                         = do-                                -- Spill what's currently in the register, with the format of what's in the register.-                                (spill_store, slot) <- spillR (RegWithFormat (RegReal cand_reg) old_reg_fmt) temp_to_push_out+                                (spill_store, slot) <- spillR (RegWithFormat (RegReal my_reg) fmt) temp_to_push_out                                  -- record that this temp was spilled                                 recordSpill (SpillAlloc temp_to_push_out) -                                -- Update the register assignment:-                                --  - the old data is now only in memory,-                                --  - the new data is now allocated to this register;-                                --    make sure to use the new format (#26542)-                                let assig1  = addToUFM_Directly assig temp_to_push_out $ Loc (InMem slot) old_reg_fmt-                                let assig2  = addToUFM assig1 vr $! newLocation spill_loc (RealRegUsage cand_reg vrFmt)+                                -- update the register assignment+                                let assig1  = addToUFM_Directly assig temp_to_push_out (InMem slot)+                                let assig2  = addToUFM assig1 vr $! newLocation spill_loc (RealRegUsage my_reg fmt)                                 setAssigR $ toRegMap assig2                                  -- if need be, load up a spilled temp into the reg we've just freed up.-                                spills' <- loadTemp r spill_loc cand_reg spills+                                spills' <- loadTemp r spill_loc my_reg spills                                  allocateRegsAndSpill reading keep                                         (spill_store ++ spills')-                                        (cand_reg:alloc) rs+                                        (my_reg:alloc) rs                           -- there wasn't anything to spill, so we're screwed.@@ -999,7 +976,7 @@                         $ vcat                                 [ text "allocating vreg:  " <> text (show vr)                                 , text "assignment:       " <> ppr assig-                                , text "format:           " <> ppr vrFmt+                                , text "format:           " <> ppr fmt                                 , text "freeRegs:         " <> text (showRegs freeRegs)                                 , text "initFreeRegs:     " <> text (showRegs (frInitFreeRegs platform `asTypeOf` freeRegs))                                 ]@@ -1011,12 +988,9 @@ -- | Calculate a new location after a register has been loaded. newLocation :: SpillLoc -> RealRegUsage -> Loc -- if the tmp was read from a slot, then now its in a reg as well-newLocation (ReadMem slot memFmt) (RealRegUsage r _regFmt) =-  -- See Note [Use spilled format when reloading]-  Loc (InBoth r slot) memFmt-+newLocation (ReadMem slot) my_reg = InBoth my_reg slot -- writes will always result in only the register being available-newLocation _ (RealRegUsage r regFmt) = Loc (InReg r) regFmt+newLocation _ my_reg = InReg my_reg  -- | Load up a spilled temporary if we need to (read from memory). loadTemp@@ -1027,91 +1001,11 @@         -> [instr]         -> RegM freeRegs [instr] -loadTemp (VirtualRegWithFormat vreg _fmt) (ReadMem slot memFmt) hreg spills+loadTemp (VirtualRegWithFormat vreg fmt) (ReadMem slot) hreg spills  = do-        -- See Note [Use spilled format when reloading]-        insn <- loadR (RegWithFormat (RegReal hreg) memFmt) slot+        insn <- loadR (RegWithFormat (RegReal hreg) fmt) slot         recordSpill (SpillLoad $ getUnique vreg)         return  $  {- mkComment (text "spill load") : -} insn ++ spills  loadTemp _ _ _ spills =    return spills--{- Note [Allocated register formats]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-We uphold the following principle for the format at which we keep track of-alllocated registers:--  RF1. Writes redefine the format.--    When we write to a register 'r' at format 'fmt', we consider the register-    to hold that format going forwards.--    (In cases where a partial write is desired, the move instruction should-     specify that the destination format is the full register, even if, say,-     the instruction only writes to the low 64 bits of the register.-     See also Wrinkle [Don't allow scalar partial writes] in-     Note [Register formats in liveness analysis] in GHC.CmmToAsm.Reg.Liveness.)--  RF2. Reads from a register do not redefine its format.--    Generally speaking, as explained in Note [Register formats in liveness analysis]-    in GHC.CmmToAsm.Reg.Liveness, when computing the used format from a collection-    of reads, we take a least upper bound.--It is particularly important to get (RF1) correct, as otherwise we can end up in-the situation of T26411b, where code such as--  movsd .Ln6m(%rip),%v1-  shufpd $0,%v1,%v1--we start off with %v1 :: F64, but after shufpd (which broadcasts the low part-to the high part) we must consider that %v1 :: F64x2. If we fail to do that,-then we will silently discard the top bits in spill/reload operations.--}--{- Note [Use spilled format when reloading]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-We always reload at the full format that a register was spilled at. The rationale-is as follows:--  1. If later instructions only need the lower 64 bits of an XMM register,-     then we should have only spilled the lower 64 bits in the first place.-     (Whether this is true currently is another question.)-  2. If later instructions need say 128 bits, then we should immediately load-     the entire 128 bits, as this avoids multiple load instructions.--For (2), consider the situation of #26526, where we need to spill around a C-call (because we are using the System V ABI with no callee saved XMM registers).-Before register allocation, we have:--  vmovupd %v1 %v0-  call ...-  movsd   %v0 %v3-  movhlps %v0 %v4--The contents of %v0 need to be preserved across the call. We must spill %v0 at-format F64x2 (as later instructions need the entire 128 bits), and reload it-later. We thus expect something like:--  vmovupd %xmm1    %xmm0-  vmovupd %xmm0    72(%rsp) -- spill to preserve-  call ...-  vmovupd 72(%rsp) %xmm0    -- restore-  movsd   %xmm0    %xmm3-  movhlps %xmm0    %xmm4--This is certainly better than doing two loads from the stack, e.g.--  call ...-  movsd   72(%rsp) %xmm0 -- restore only lower 64 bits-  movsd   %xmm0    %xmm3-  vmovupd 72(%rsp) %xmm0 -- restore the full 128 bits-  movhlps %xmm0    %xmm4--The latter being especially risky because we don't want to believe %v0 is 'InBoth'-with format F64. The risk is that, when allocating registers for the 'VMOVUPD'-instruction, we think our data is already in a register and thus doesn't need to-be reloaded from memory, when in fact we have only loaded the lower 64 bits of-the data.--}
GHC/CmmToAsm/Reg/Linear/AArch64.hs view
@@ -118,6 +118,7 @@ getFreeRegs cls (FreeRegs g f) =   case cls of     RcFloatOrVector -> go 32 f 31+    -- x18 is a platform-reserved register for Win/Mac and free for Linux (See Note [Aarch64 Register x18 at Darwin and Windows])     RcInteger       -> go  0 g 18     where         go _   _ i | i < 0 = []
GHC/CmmToAsm/Reg/Linear/Base.hs view
@@ -1,4 +1,3 @@-{-# LANGUAGE LambdaCase #-} {-# LANGUAGE RecordWildCards #-}  -- | Put common type definitions here to break recursive module dependencies.@@ -10,7 +9,7 @@         emptyBlockAssignment,         updateBlockAssignment, -        VLoc(..), Loc(..), IgnoreFormat(..),+        Loc(..),         regsOfLoc,         RealRegUsage(..), @@ -40,6 +39,8 @@ import GHC.CmmToAsm.Reg.Utils import GHC.CmmToAsm.Format +import Data.Function ( on )+ data ReadingOrWriting = Reading | Writing deriving (Eq,Ord)  -- | Used to store the register assignment on entry to a basic block.@@ -69,13 +70,8 @@   -> BlockAssignment freeRegs   -> BlockAssignment freeRegs updateBlockAssignment dest (freeRegs, regMap) (BlockAssignment {..}) =-  BlockAssignment-    (mapInsert dest (freeRegs, regMap) blockMap)-    (mergeUFM combWithExisting id-        (mapMaybeUFM (fromVLoc . locWithFormat_loc))-        firstUsed-        (toVRegMap regMap)-    )+  BlockAssignment (mapInsert dest (freeRegs, regMap) blockMap)+                  (mergeUFM combWithExisting id (mapMaybeUFM fromLoc) (firstUsed) (toVRegMap regMap))   where     -- The blocks are processed in dependency order, so if there's already an     -- entry in the map then keep that assignment rather than writing the new@@ -83,14 +79,13 @@     combWithExisting :: RealReg -> Loc -> Maybe RealReg     combWithExisting old_reg _ = Just $ old_reg -    fromVLoc :: VLoc -> Maybe RealReg-    fromVLoc (InReg rr) = Just rr-    fromVLoc (InBoth rr _) = Just rr-    fromVLoc _ = Nothing+    fromLoc :: Loc -> Maybe RealReg+    fromLoc (InReg rr) = Just $ realReg rr+    fromLoc (InBoth rr _) = Just $ realReg rr+    fromLoc _ = Nothing --- | Where a vreg is currently stored.------++-- | Where a vreg is currently stored --      A temporary can be marked as living in both a register and memory --      (InBoth), for example if it was recently loaded from a spill location. --      This makes it cheap to spill (no save instruction required), but we@@ -101,40 +96,21 @@ --      save it in a spill location, but mark it as InBoth because the current --      instruction might still want to read it. ---data VLoc+data Loc         -- | vreg is in a register-        = InReg   {-# UNPACK #-} !RealReg+        = InReg   {-# UNPACK #-} !RealRegUsage          -- | vreg is held in stack slots-        | InMem   {-# UNPACK #-} !StackSlot+        | InMem   {-# UNPACK #-}  !StackSlot +         -- | vreg is held in both a register and stack slots-        | InBoth  {-# UNPACK #-} !RealReg-                  {-# UNPACK #-} !StackSlot+        | InBoth   {-# UNPACK #-} !RealRegUsage+                   {-# UNPACK #-} !StackSlot         deriving (Eq, Ord, Show) --- | Where a virtual register is stored, together with the format it is stored at.------ See 'VLoc'.-data Loc-  = Loc-  { locWithFormat_loc    :: {-# UNPACK #-} !VLoc-  , locWithFormat_format :: Format-  }---- | A newtype used to hang off 'Eq' and 'Ord' instances for 'Loc' which--- ignore the format, as used in 'GHC.CmmToAsm.Reg.Linear.JoinToTargets'.-newtype IgnoreFormat a = IgnoreFormat a-instance Eq (IgnoreFormat Loc) where-  IgnoreFormat (Loc l1 _) == IgnoreFormat (Loc l2 _) = l1 == l2-instance Ord (IgnoreFormat Loc) where-  compare (IgnoreFormat (Loc l1 _)) (IgnoreFormat (Loc l2 _)) = compare l1 l2--instance Outputable VLoc where-        ppr l = text (show l)- instance Outputable Loc where-  ppr (Loc loc fmt) = parens (ppr loc <+> dcolon <+> ppr fmt)+        ppr l = text (show l)  -- | A 'RealReg', together with the specific 'Format' it is used at. data RealRegUsage@@ -146,12 +122,22 @@ instance Outputable RealRegUsage where   ppr (RealRegUsage r fmt) = ppr r <> dcolon <+> ppr fmt +-- NB: these instances only compare the underlying 'RealReg', as that is what+-- is important for register allocation.+--+-- (It would nonetheless be a good idea to remove these instances.)+instance Eq RealRegUsage where+  (==) = (==) `on` realReg+instance Ord RealRegUsage where+  compare = compare `on` realReg+ -- | Get the reg numbers stored in this Loc.-regsOfLoc :: VLoc -> [RealReg]+regsOfLoc :: Loc -> [RealRegUsage] regsOfLoc (InReg r)    = [r] regsOfLoc (InBoth r _) = [r] regsOfLoc (InMem _)    = [] + -- | Reasons why instructions might be inserted by the spiller. --      Used when generating stats for -ddrop-asm-stats. --@@ -220,5 +206,4 @@         , ra_fixups     :: [(BlockId,BlockId,BlockId)]          }- 
GHC/CmmToAsm/Reg/Linear/FreeRegs.hs view
@@ -34,11 +34,13 @@ import qualified GHC.CmmToAsm.Reg.Linear.X86_64  as X86_64 import qualified GHC.CmmToAsm.Reg.Linear.AArch64 as AArch64 import qualified GHC.CmmToAsm.Reg.Linear.RV64    as RV64+import qualified GHC.CmmToAsm.Reg.Linear.LA64    as LA64  import qualified GHC.CmmToAsm.PPC.Instr     as PPC.Instr import qualified GHC.CmmToAsm.X86.Instr     as X86.Instr import qualified GHC.CmmToAsm.AArch64.Instr as AArch64.Instr import qualified GHC.CmmToAsm.RV64.Instr    as RV64.Instr+import qualified GHC.CmmToAsm.LA64.Instr    as LA64.Instr  class Show freeRegs => FR freeRegs where     frAllocateReg :: Platform -> RealReg -> freeRegs -> freeRegs@@ -76,6 +78,12 @@     frInitFreeRegs = RV64.initFreeRegs     frReleaseReg = const RV64.releaseReg +instance FR LA64.FreeRegs where+    frAllocateReg = \_ -> LA64.allocateReg+    frGetFreeRegs = \_ -> LA64.getFreeRegs+    frInitFreeRegs = LA64.initFreeRegs+    frReleaseReg = \_ -> LA64.releaseReg+ allFreeRegs :: FR freeRegs => Platform -> freeRegs -> [RealReg] allFreeRegs plat fr = foldMap (\rcls -> frGetFreeRegs plat rcls fr) allRegClasses   where@@ -98,7 +106,7 @@    ArchMipseb    -> panic "maxSpillSlots ArchMipseb"    ArchMipsel    -> panic "maxSpillSlots ArchMipsel"    ArchRISCV64   -> RV64.Instr.maxSpillSlots config-   ArchLoongArch64->panic "maxSpillSlots ArchLoongArch64"+   ArchLoongArch64  -> LA64.Instr.maxSpillSlots config    ArchJavaScript-> panic "maxSpillSlots ArchJavaScript"    ArchWasm32    -> panic "maxSpillSlots ArchWasm32"    ArchUnknown   -> panic "maxSpillSlots ArchUnknown"
GHC/CmmToAsm/Reg/Linear/JoinToTargets.hs view
@@ -1,5 +1,3 @@-{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-}- -- | Handles joining of a jump instruction to its targets.  --      The first time we encounter a jump to a particular basic block, we@@ -25,6 +23,7 @@ import GHC.Cmm.BlockId import GHC.Cmm.Dataflow.Label import GHC.Data.Graph.Directed+import GHC.Data.Maybe import GHC.Utils.Panic import GHC.Utils.Monad (concatMapM) import GHC.Types.Unique@@ -34,14 +33,12 @@ import GHC.CmmToAsm.Format import GHC.Types.Unique.Set -import Data.Coerce (coerce)- -- | For a jump instruction at the end of a block, generate fixup code so its --      vregs are in the correct regs for its destination. -- joinToTargets         :: (FR freeRegs, Instruction instr)-        => BlockMap Regs -- ^ maps the unique of the blockid to the set of vregs+        => BlockMap (UniqSet RegWithFormat) -- ^ maps the unique of the blockid to the set of vregs                                         --      that are known to be live on the entry to each block.          -> BlockId                      -- ^ id of the current block@@ -65,7 +62,7 @@ ----- joinToTargets'         :: (FR freeRegs, Instruction instr)-        => BlockMap Regs -- ^ maps the unique of the blockid to the set of vregs+        => BlockMap (UniqSet RegWithFormat) -- ^ maps the unique of the blockid to the set of vregs                                         --      that are known to be live on the entry to each block.          -> [NatBasicBlock instr]        -- ^ acc blocks of fixup code.@@ -92,24 +89,24 @@          -- adjust the current assignment to remove any vregs that are not live         -- on entry to the destination block.-        let Just live_set       = mapLookup dest block_live-        let still_live uniq _   = uniq `elemUniqSet_Directly` getRegs live_set+        let live_set            = expectJust $ mapLookup dest block_live+        let still_live uniq _   = uniq `elemUniqSet_Directly` live_set         let adjusted_assig      = filterUFM_Directly still_live assig          -- and free up those registers which are now free.         let to_free =-                [ r     | (reg, Loc loc _locFmt) <- nonDetUFMToList assig+                [ r     | (reg, loc) <- nonDetUFMToList assig                         -- This is non-deterministic but we do not                         -- currently support deterministic code-generation.                         -- See Note [Unique Determinism and code generation]-                        , not (elemUniqSet_Directly reg $ getRegs live_set)+                        , not (elemUniqSet_Directly reg live_set)                         , r          <- regsOfLoc loc ]          case lookupBlockAssignment  dest block_assig of          Nothing           -> joinToTargets_first                         block_live new_blocks block_id instr dest dests-                        block_assig adjusted_assig to_free+                        block_assig adjusted_assig $ map realReg to_free           Just (_, dest_assig)           -> joinToTargets_again@@ -119,7 +116,7 @@  -- this is the first time we jumped to this block. joinToTargets_first :: (FR freeRegs, Instruction instr)-                    => BlockMap Regs+                    => BlockMap (UniqSet RegWithFormat)                     -> [NatBasicBlock instr]                     -> BlockId                     -> instr@@ -145,9 +142,10 @@          joinToTargets' block_live new_blocks block_id instr dests + -- we've jumped to this block before joinToTargets_again :: (Instruction instr, FR freeRegs)-                    => BlockMap Regs+                    => BlockMap (UniqSet RegWithFormat)                     -> [NatBasicBlock instr]                     -> BlockId                     -> instr@@ -161,9 +159,7 @@     src_assig dest_assig          -- the assignments already match, no problem.-        | equalIgnoringFormats-            (nonDetUFMToList dest_assig)-            (nonDetUFMToList src_assig)+        | nonDetUFMToList dest_assig == nonDetUFMToList src_assig         -- This is non-deterministic but we do not         -- currently support deterministic code-generation.         -- See Note [Unique Determinism and code generation]@@ -187,7 +183,7 @@                 --                 -- We need to do the R2 -> R3 move before R1 -> R2.                 ---                let sccs  = movementGraphSCCs graph+                let sccs  = stronglyConnCompFromEdgedVerticesOrdR graph                -- debugging                 {-@@ -271,38 +267,32 @@ -- expandNode         :: a-        -> Loc -- ^ source of move-        -> Loc -- ^ destination of move-        -> [Node Loc a]-expandNode vreg src@(Loc srcLoc srcFmt) dst@(Loc dstLoc dstFmt) =-  case (srcLoc, dstLoc) of-    (InReg srcReg, InBoth dstReg dstMem)-        | srcReg == dstReg-        -> [DigraphNode vreg src [Loc (InMem dstMem) dstFmt]]-        | otherwise-        -> [DigraphNode vreg src [Loc (InReg dstReg) dstFmt-                                 ,Loc (InMem dstMem) dstFmt]]-    (InMem srcMem, InBoth dstReg dstMem)-        | srcMem == dstMem-        -> [DigraphNode vreg src [Loc (InReg dstReg) dstFmt]]-        | otherwise-        -> [DigraphNode vreg src [Loc (InReg dstReg) dstFmt-                                 ,Loc (InMem dstMem) dstFmt]]-    (InBoth _ srcMem, InMem dstMem)-        | srcMem == dstMem-        -> [] -- guaranteed to be true-    (InBoth srcReg _, InReg dstReg)-        | srcReg == dstReg-        -> []-    (InBoth srcReg _, _)-        -> expandNode vreg (Loc (InReg srcReg) srcFmt) dst-    _-      | srcLoc == dstLoc-      -> []-      | otherwise-      -> [DigraphNode vreg src [dst]]+        -> Loc                  -- ^ source of move+        -> Loc                  -- ^ destination of move+        -> [Node Loc a ] +expandNode vreg loc@(InReg src) (InBoth dst mem)+        | src == dst = [DigraphNode vreg loc [InMem mem]]+        | otherwise  = [DigraphNode vreg loc [InReg dst, InMem mem]] +expandNode vreg loc@(InMem src) (InBoth dst mem)+        | src == mem = [DigraphNode vreg loc [InReg dst]]+        | otherwise  = [DigraphNode vreg loc [InReg dst, InMem mem]]++expandNode _        (InBoth _ src) (InMem dst)+        | src == dst = [] -- guaranteed to be true++expandNode _        (InBoth src _) (InReg dst)+        | src == dst = []++expandNode vreg     (InBoth src _) dst+        = expandNode vreg (InReg src) dst++expandNode vreg src dst+        | src == dst = []+        | otherwise  = [DigraphNode vreg src [dst]]++ -- | Generate fixup code for a particular component in the move graph --      This component tells us what values need to be moved to what --      destinations. We have eliminated any possibility of single-node@@ -337,7 +327,7 @@ --      require a fixup. -- handleComponent delta instr-        (CyclicSCC ((DigraphNode vreg (Loc (InReg sreg) scls) ((Loc (InReg dreg) dcls: _))) : rest))+        (CyclicSCC ((DigraphNode vreg (InReg (RealRegUsage sreg scls)) ((InReg (RealRegUsage dreg dcls): _))) : rest))         -- dest list may have more than one element, if the reg is also InMem.  = do         -- spill the source into its slot@@ -348,7 +338,7 @@         instrLoad       <- loadR (RegWithFormat (RegReal dreg) dcls) slot          remainingFixUps <- mapM (handleComponent delta instr)-                                (movementGraphSCCs rest)+                                (stronglyConnCompFromEdgedVerticesOrdR rest)          -- make sure to do all the reloads after all the spills,         --      so we don't end up clobbering the source values.@@ -357,37 +347,29 @@ handleComponent _ _ (CyclicSCC _)  = panic "Register Allocator: handleComponent cyclic" --- Helper functions that use the @Ord (IgnoreFormat Loc)@ instance. -equalIgnoringFormats :: [(Unique, Loc)] -> [(Unique, Loc)] -> Bool-equalIgnoringFormats =-  coerce $ (==) @[(Unique, IgnoreFormat Loc)]-movementGraphSCCs :: [Node Loc Unique] -> [SCC (Node Loc Unique)]-movementGraphSCCs =-  coerce $ stronglyConnCompFromEdgedVerticesOrdR @(IgnoreFormat Loc) @Unique- -- | Move a vreg between these two locations. -- makeMove     :: Instruction instr-    => Int           -- ^ current C stack delta-    -> Unique        -- ^ unique of the vreg that we're moving-    -> Loc -- ^ source location-    -> Loc -- ^ destination location-    -> RegM freeRegs [instr]  -- ^ move instruction+    => Int      -- ^ current C stack delta.+    -> Unique   -- ^ unique of the vreg that we're moving.+    -> Loc      -- ^ source location.+    -> Loc      -- ^ destination location.+    -> RegM freeRegs [instr]  -- ^ move instruction. -makeMove delta vreg (Loc src _srcFmt) (Loc dst dstFmt)+makeMove delta vreg src dst  = do config <- getConfig       case (src, dst) of-          (InReg s, InReg d) ->+          (InReg (RealRegUsage s _), InReg (RealRegUsage d fmt)) ->               do recordSpill (SpillJoinRR vreg)-                 return $ [mkRegRegMoveInstr config dstFmt (RegReal s) (RegReal d)]-          (InMem s, InReg d) ->+                 return $ [mkRegRegMoveInstr config fmt (RegReal s) (RegReal d)]+          (InMem s, InReg (RealRegUsage d cls)) ->               do recordSpill (SpillJoinRM vreg)-                 return $ mkLoadInstr config (RegWithFormat (RegReal d) dstFmt) delta s-          (InReg s, InMem d) ->+                 return $ mkLoadInstr config (RegWithFormat (RegReal d) cls) delta s+          (InReg (RealRegUsage s cls), InMem d) ->               do recordSpill (SpillJoinRM vreg)-                 return $ mkSpillInstr config (RegWithFormat (RegReal s) dstFmt) delta d+                 return $ mkSpillInstr config (RegWithFormat (RegReal s) cls) delta d           _ ->               -- we don't handle memory to memory moves.               -- they shouldn't happen because we don't share
+ GHC/CmmToAsm/Reg/Linear/LA64.hs view
@@ -0,0 +1,71 @@+module GHC.CmmToAsm.Reg.Linear.LA64 where++import GHC.Prelude++import Data.Word+import GHC.CmmToAsm.LA64.Regs+import GHC.Platform+import GHC.Platform.Reg+import GHC.Platform.Reg.Class+import GHC.Platform.Reg.Class.Separate+import GHC.Stack+import GHC.Utils.Outputable+import GHC.Utils.Panic++data FreeRegs = FreeRegs !Word32 !Word32++noFreeRegs :: FreeRegs+noFreeRegs = FreeRegs 0 0++instance Show FreeRegs where+  show (FreeRegs g f) = "FreeRegs 0b" ++ showBits g ++ " 0b" ++ showBits f++-- | Show bits as a `String` of @1@s and @0@s+showBits :: Word32 -> String+showBits w = map (\i -> if testBit w i then '1' else '0') [0 .. 31]++instance Outputable FreeRegs where+  ppr (FreeRegs g f) =+         text "   " <+> foldr (\i x -> pad_int i <+> x) (text "") [0 .. 31]+      $$ text "GPR" <+> foldr (\i x -> show_bit g i <+> x) (text "") [0 .. 31]+      $$ text "FPR" <+> foldr (\i x -> show_bit f i <+> x) (text "") [0 .. 31]+    where+      pad_int i | i < 10 = char ' ' <> int i+      pad_int i = int i+      -- remember bit = 1 means it's available.+      show_bit bits bit | testBit bits bit = text "  "+      show_bit _ _ = text " x"++-- | Set bits of all allocatable registers to 1+initFreeRegs :: Platform -> FreeRegs+initFreeRegs platform = foldl' (flip releaseReg) noFreeRegs (allocatableRegs platform)++-- | Get all free `RealReg`s (i.e. those where the corresponding bit is 1)+getFreeRegs :: RegClass -> FreeRegs -> [RealReg]+getFreeRegs cls (FreeRegs g f)+  | RcInteger <- cls = go 0 g allocatableIntRegs+  | RcFloat   <- cls = go 32 f allocatableDoubleRegs+  | RcVector  <- cls = sorry "Linear.LA64.getFreeRegs: vector registers are not supported"+  where+    go _ _ [] = []+    go off x (i : is)+      | testBit x i = RealRegSingle (off + i) : (go off x $! is)+      | otherwise = go off x $! is+    allocatableIntRegs = [4 .. 11] ++ [12 .. 19]+    allocatableDoubleRegs = [0 .. 7] ++ [8 .. 23]++-- | Set corresponding register bit to 0+allocateReg :: (HasCallStack) => RealReg -> FreeRegs -> FreeRegs+allocateReg (RealRegSingle r) (FreeRegs g f)+  | r > 31 && testBit f (r - 32) = FreeRegs g (clearBit f (r - 32))+  | r < 32 && testBit g r = FreeRegs (clearBit g r) f+  | r > 31 = panic $ "Linear.LA64.allocReg: double allocation of float reg v" ++ show (r - 32) ++ "; " ++ showBits f+  | otherwise = pprPanic "Linear.LA64.allocReg" $ text ("double allocation of gp reg x" ++ show r ++ "; " ++ showBits g)++-- | Set corresponding register bit to 1+releaseReg :: (HasCallStack) => RealReg -> FreeRegs -> FreeRegs+releaseReg (RealRegSingle r) (FreeRegs g f)+  | r > 31 && testBit f (r - 32) = pprPanic "Linear.LA64.releaseReg" (text "can't release non-allocated reg v" <> int (r - 32))+  | r < 32 && testBit g r = pprPanic "Linear.LA64.releaseReg" (text "can't release non-allocated reg x" <> int r)+  | r > 31 = FreeRegs g (setBit f (r - 32))+  | otherwise = FreeRegs (setBit g r) f
GHC/CmmToAsm/Reg/Linear/StackMap.hs view
@@ -37,11 +37,7 @@            -- See Note [UniqFM and the register allocator]           -- | Assignment of vregs to stack slots.-          ---          -- We record not just the slot, but also how many stack slots the vreg-          -- takes up, in order to avoid re-using a stack slot for a register-          -- that has grown but already had a stack slot (#26668).-        , stackMapAssignment    :: UniqFM Unique (StackSlot, Int) }+        , stackMapAssignment    :: UniqFM Unique StackSlot }   -- | An empty stack map, with all slots available.@@ -54,19 +50,14 @@ -- getStackSlotFor :: StackMap -> Format -> Unique -> (StackMap, Int) -getStackSlotFor fs@(StackMap freeSlot reserved) fmt regUnique-  -- The register already has a stack slot; try to re-use it.-  | Just (slot, nbSlots) <- lookupUFM reserved regUnique-  -- Make sure the slot is big enough for this format, in case the register-  -- has grown (#26668).-  , nbNeededSlots <= nbSlots-  = (fs, slot)-  | otherwise-  = (StackMap (freeSlot+nbNeededSlots) (addToUFM reserved regUnique (freeSlot, nbNeededSlots)), freeSlot)-    -- NB: this can create fragmentation if a register keeps growing.-    -- That's probably OK, as this is only happens very rarely.-  where-    !nbNeededSlots = (formatInBytes fmt + 7) `div` 8+getStackSlotFor fs@(StackMap _ reserved) _fmt regUnique+  | Just slot <- lookupUFM reserved regUnique  =  (fs, slot)++getStackSlotFor (StackMap freeSlot reserved) fmt regUnique =+  let+    nbSlots = (formatInBytes fmt + 7) `div` 8+  in+    (StackMap (freeSlot+nbSlots) (addToUFM reserved regUnique freeSlot), freeSlot)  -- | Return the number of stack slots that were allocated getStackUse :: StackMap -> Int
GHC/CmmToAsm/Reg/Liveness.hs view
@@ -1,8 +1,5 @@ {-# LANGUAGE TypeFamilies #-} --{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-}- ----------------------------------------------------------------------------- -- -- The register liveness determinator@@ -33,9 +30,7 @@         patchRegsLiveInstr,         reverseBlocksInTops,         regLiveness,-        cmmTopLiveness,--        module GHC.CmmToAsm.Reg.Regs+        cmmTopLiveness   ) where import GHC.Prelude @@ -46,14 +41,13 @@ import GHC.CmmToAsm.Format import GHC.CmmToAsm.Types import GHC.CmmToAsm.Utils-import GHC.CmmToAsm.Reg.Regs  import GHC.Cmm.BlockId import GHC.Cmm.Dataflow.Label import GHC.Cmm+import GHC.CmmToAsm.Reg.Target  import GHC.Data.Graph.Directed-import GHC.Data.OrdList import GHC.Utils.Monad import GHC.Utils.Outputable import GHC.Utils.Panic@@ -65,7 +59,7 @@ import GHC.Data.Bag import GHC.Utils.Monad.State.Strict -import Data.List (mapAccumL, partition)+import Data.List (mapAccumL, sortOn) import Data.Maybe import Data.IntSet              (IntSet) import GHC.Utils.Misc@@ -194,9 +188,9 @@  data Liveness         = Liveness-        { liveBorn      :: Regs      -- ^ registers born in this instruction (written to for first time).-        , liveDieRead   :: Regs      -- ^ registers that died because they were read for the last time.-        , liveDieWrite  :: Regs }    -- ^ registers that died because they were clobbered by something.+        { liveBorn      :: UniqSet RegWithFormat      -- ^ registers born in this instruction (written to for first time).+        , liveDieRead   :: UniqSet RegWithFormat      -- ^ registers that died because they were read for the last time.+        , liveDieWrite  :: UniqSet RegWithFormat}     -- ^ registers that died because they were clobbered by something.   -- | Stash regs live on entry to each basic block in the info part of the cmm code.@@ -205,7 +199,7 @@                 (LabelMap RawCmmStatics)  -- cmm info table static stuff                 [BlockId]                 -- entry points (first one is the                                           -- entry point for the proc).-                (BlockMap Regs)       -- argument locals live on entry to this block+                (BlockMap (UniqSet RegWithFormat))         -- argument locals live on entry to this block                 (BlockMap IntSet)         -- stack slots live on entry to this block  @@ -251,8 +245,8 @@                         , pprRegs (text "# w_dying: ") (liveDieWrite live) ]                     $+$ space) -         where  pprRegs :: SDoc -> Regs -> SDoc-                pprRegs name ( Regs regs )+         where  pprRegs :: SDoc -> UniqSet RegWithFormat -> SDoc+                pprRegs name regs                  | isEmptyUniqSet regs  = empty                  | otherwise            = name <>                      (pprUFM (getUniqSet regs) (hcat . punctuate space . map ppr))@@ -335,7 +329,7 @@         :: Instruction instr         => Platform         -> LiveCmmDecl statics instr-        -> (Bag Regs, Bag (Reg, Reg))+        -> (Bag (UniqSet RegWithFormat), Bag (Reg, Reg))  slurpConflicts platform live         = slurpCmm (emptyBag, emptyBag) live@@ -369,22 +363,23 @@          = let                 -- regs that die because they are read for the last time at the start of an instruction                 --      are not live across it.-                rsLiveAcross    = rsLiveEntry `minusRegs` (liveDieRead live)+                rsLiveAcross    = rsLiveEntry `minusUniqSet` (liveDieRead live)                  -- regs live on entry to the next instruction.                 --      be careful of orphans, make sure to delete dying regs _after_ unioning                 --      in the ones that are born here.-                rsLiveNext      = (rsLiveAcross `unionRegsMaxFmt`  (liveBorn     live))-                                                `minusCoveredRegs` (liveDieWrite live)+                rsLiveNext      = (rsLiveAcross `unionUniqSets` (liveBorn     live))+                                                `minusUniqSet`  (liveDieWrite live)                  -- orphan vregs are the ones that die in the same instruction they are born in.                 --      these are likely to be results that are never used, but we still                 --      need to assign a hreg to them..-                rsOrphans       = intersectRegsMaxFmt+                rsOrphans       = intersectUniqSets                                         (liveBorn live)-                                        (unionRegsMaxFmt (liveDieWrite live) (liveDieRead live))+                                        (unionUniqSets (liveDieWrite live) (liveDieRead live)) -                rsConflicts     = unionRegsMaxFmt rsLiveNext rsOrphans+                --+                rsConflicts     = unionUniqSets rsLiveNext rsOrphans            in    case takeRegRegMoveInstr platform instr of                  Just rr        -> slurpLIs rsLiveNext@@ -532,11 +527,10 @@                 -- make sure the block that was first in the input list                 --      stays at the front of the output. This is the entry point                 --      of the proc, and it needs to come first.-                ((first':_), rest')-                                = partition ((== first_id) . blockId) final_blocks+                final_blocks' = sortOn ((/= first_id) . blockId) final_blocks -           in   CmmProc info label live-                          (ListGraph $ map (stripLiveBlock config) $ first' : rest')+           in   CmmProc info label live $ ListGraph $+                map (stripLiveBlock config) final_blocks'          -- If the proc has blocks but we don't know what the first one was, then we're dead.         stripCmm proc@@ -568,28 +562,32 @@  =      BasicBlock i instrs'   where  (instrs', _)-                = runState (spillNat nilOL lis) 0+                = runState (spillNat [] lis) 0 -        spillNat :: Instruction instr => OrdList instr -> [LiveInstr instr] -> State Int [instr]+        -- spillNat :: [instr] -> [LiveInstr instr] -> State Int [instr]+        spillNat :: Instruction instr => [instr] -> [LiveInstr instr] -> State Int [instr]         spillNat acc []-         =      return (fromOL acc)+         =      return (reverse acc) +        -- The SPILL/RELOAD cases do not appear to be exercised by our codegens+        --         spillNat acc (LiveInstr (SPILL reg slot) _ : instrs)          = do   delta   <- get-                spillNat (acc `appOL` toOL (mkSpillInstr config reg delta slot)) instrs+                spillNat (mkSpillInstr config reg delta slot ++ acc) instrs          spillNat acc (LiveInstr (RELOAD slot reg) _ : instrs)          = do   delta   <- get-                spillNat (acc `appOL` toOL (mkLoadInstr config reg delta slot)) instrs+                spillNat (mkLoadInstr config reg delta slot ++ acc) instrs          spillNat acc (LiveInstr (Instr instr) _ : instrs)          | Just i <- takeDeltaInstr instr          = do   put i                 spillNat acc instrs-         | otherwise-         =      spillNat (acc `snocOL` instr) instrs +        spillNat acc (LiveInstr (Instr instr) _ : instrs)+         =      spillNat (instr : acc) instrs + -- | Erase Delta instructions.  eraseDeltasLive@@ -624,7 +622,7 @@          | LiveInfo static id blockMap mLiveSlots <- info          = let                   -- See Note [Unique Determinism and code generation]-                blockMap'       = mapMap (mapRegs patchF) blockMap+                blockMap'       = mapMap (mapRegFormatSet patchF) blockMap                  info'           = LiveInfo static id blockMap' mLiveSlots            in   CmmProc info' label live $ map patchSCC sccs@@ -653,8 +651,8 @@                 | r1 == r2      = True                  -- destination reg is never used-                | r2 `elemRegs` liveBorn live-                , r2 `elemRegs` liveDieRead live || r2 `elemRegs` liveDieWrite live+                | elemUniqSet_Directly (getUnique r2) (liveBorn live)+                , elemUniqSet_Directly (getUnique r2) (liveDieRead live) || elemUniqSet_Directly (getUnique r2) (liveDieWrite live)                 = True                  | otherwise     = False@@ -678,9 +676,9 @@                 (patchRegsOfInstr platform instr patchF)                 (Just live                         { -- WARNING: have to go via lists here because patchF changes the uniq in the Reg-                          liveBorn      = mapRegs patchF $ liveBorn live-                        , liveDieRead   = mapRegs patchF $ liveDieRead live-                        , liveDieWrite  = mapRegs patchF $ liveDieWrite live })+                          liveBorn      = mapRegFormatSet patchF $ liveBorn live+                        , liveDieRead   = mapRegFormatSet patchF $ liveDieRead live+                        , liveDieWrite  = mapRegFormatSet patchF $ liveDieWrite live })                           -- See Note [Unique Determinism and code generation]  --------------------------------------------------------------------------------@@ -870,7 +868,7 @@         -> [SCC (LiveBasicBlock instr)]         -> ([SCC (LiveBasicBlock instr)],       -- instructions annotated with list of registers                                                 -- which are "dead after this instruction".-               BlockMap Regs)               -- blocks annotated with set of live registers+               BlockMap (UniqSet RegWithFormat))                 -- blocks annotated with set of live registers                                                 -- on entry to the block.  computeLiveness platform sccs@@ -885,11 +883,11 @@ livenessSCCs        :: Instruction instr        => Platform-       -> BlockMap Regs+       -> BlockMap (UniqSet RegWithFormat)        -> [SCC (LiveBasicBlock instr)]          -- accum        -> [SCC (LiveBasicBlock instr)]        -> ( [SCC (LiveBasicBlock instr)]-          , BlockMap Regs)+          , BlockMap (UniqSet RegWithFormat))  livenessSCCs _ blockmap done []         = (done, blockmap)@@ -918,14 +916,13 @@              linearLiveness                 :: Instruction instr-                => BlockMap Regs -> [LiveBasicBlock instr]-                -> (BlockMap Regs, [LiveBasicBlock instr])+                => BlockMap (UniqSet RegWithFormat) -> [LiveBasicBlock instr]+                -> (BlockMap (UniqSet RegWithFormat), [LiveBasicBlock instr])              linearLiveness = mapAccumL (livenessBlock platform)                  -- probably the least efficient way to compare two                 -- BlockMaps for equality.-            equalBlockMaps :: BlockMap Regs -> BlockMap Regs -> Bool             equalBlockMaps a b                 = a' == b'               where a' = mapToList a@@ -939,14 +936,14 @@ livenessBlock         :: Instruction instr         => Platform-        -> BlockMap Regs+        -> BlockMap (UniqSet RegWithFormat)         -> LiveBasicBlock instr-        -> (BlockMap Regs, LiveBasicBlock instr)+        -> (BlockMap (UniqSet RegWithFormat), LiveBasicBlock instr)  livenessBlock platform blockmap (BasicBlock block_id instrs)  = let         (regsLiveOnEntry, instrs1)-            = livenessBack platform noRegs blockmap [] (reverse instrs)+            = livenessBack platform emptyUniqSet blockmap [] (reverse instrs)         blockmap'       = mapInsert block_id regsLiveOnEntry blockmap          instrs2         = livenessForward platform regsLiveOnEntry instrs1@@ -961,26 +958,23 @@ livenessForward         :: Instruction instr         => Platform-        -> Regs -- regs live on this instr+        -> UniqSet RegWithFormat -- regs live on this instr         -> [LiveInstr instr] -> [LiveInstr instr]  livenessForward _        _           []  = [] livenessForward platform rsLiveEntry (li@(LiveInstr instr mLive) : lis)         | Just live <- mLive         = let-                RU _ rsWritten  = regUsageOfInstr platform instr+                RU _ written  = regUsageOfInstr platform instr                 -- Regs that are written to but weren't live on entry to this instruction                 --      are recorded as being born here.-                rsBorn          = mkRegsMaxFmt-                                    [ reg-                                    | reg@( RegWithFormat r _ ) <- rsWritten-                                    , not $ r `elemRegs` rsLiveEntry-                                    ]+                rsBorn          = mkUniqSet+                                $ filter (\ r -> not $ elemUniqSet_Directly (getUnique r) rsLiveEntry)+                                $ written -                   -- See Note [Register formats in liveness analysis]-                rsLiveNext      = (rsLiveEntry `addRegsMaxFmt` rsWritten)-                                        `minusRegs` (liveDieRead live)  -- (FmtFwd1)-                                        `minusRegs` (liveDieWrite live) -- (FmtFwd2)+                rsLiveNext      = (rsLiveEntry `unionUniqSets` rsBorn)+                                        `minusUniqSet` (liveDieRead live)+                                        `minusUniqSet` (liveDieWrite live)          in LiveInstr instr (Just live { liveBorn = rsBorn })                 : livenessForward platform rsLiveNext lis@@ -995,11 +989,11 @@ livenessBack         :: Instruction instr         => Platform-        -> Regs           -- ^ regs live on this instr-        -> BlockMap Regs  -- ^ regs live on entry to other BBs-        -> [LiveInstr instr]  -- ^ instructions (accum)-        -> [LiveInstr instr]  -- ^ instructions-        -> (Regs, [LiveInstr instr])+        -> UniqSet RegWithFormat            -- regs live on this instr+        -> BlockMap (UniqSet RegWithFormat) -- regs live on entry to other BBs+        -> [LiveInstr instr]            -- instructions (accum)+        -> [LiveInstr instr]            -- instructions+        -> (UniqSet RegWithFormat, [LiveInstr instr])  livenessBack _        liveregs _        done []  = (liveregs, done) @@ -1007,14 +1001,15 @@  = let  !(!liveregs', instr')     = liveness1 platform liveregs blockmap instr    in   livenessBack platform liveregs' blockmap (instr' : acc) instrs + -- don't bother tagging comments or deltas with liveness liveness1         :: Instruction instr         => Platform-        -> Regs-        -> BlockMap Regs+        -> UniqSet RegWithFormat+        -> BlockMap (UniqSet RegWithFormat)         -> LiveInstr instr-        -> (Regs, LiveInstr instr)+        -> (UniqSet RegWithFormat, LiveInstr instr)  liveness1 _ liveregs _ (LiveInstr instr _)         | isMetaInstr instr@@ -1025,14 +1020,14 @@         | not_a_branch         = (liveregs1, LiveInstr instr                         (Just $ Liveness-                        { liveBorn      = noRegs+                        { liveBorn      = emptyUniqSet                         , liveDieRead   = r_dying                         , liveDieWrite  = w_dying }))          | otherwise         = (liveregs_br, LiveInstr instr                         (Just $ Liveness-                        { liveBorn      = noRegs+                        { liveBorn      = emptyUniqSet                         , liveDieRead   = r_dying_br                         , liveDieWrite  = w_dying })) @@ -1041,22 +1036,21 @@              -- registers that were written here are dead going backwards.             -- registers that were read here are live going backwards.-            -- As for the formats, see Note [Register formats in liveness analysis]-            liveregs1   = (liveregs `minusCoveredRegs` mkRegsMaxFmt written) -- (FmtBwd2)-                                    `addRegsMaxFmt` read                     -- (FmtBwd1)+            liveregs1   = (liveregs `delListFromUniqSet` written)+                                    `addListToUniqSet` read -            -- registers that are not live beyond this point are recorded-            -- as dying here.-            r_dying     = mkRegsMaxFmt+            -- registers that are not live beyond this point, are recorded+            --  as dying here.+            r_dying     = mkUniqSet                           [ reg                           | reg@(RegWithFormat r _) <- read                           , not $ any (\ w -> getUnique w == getUnique r) written-                          , not $ r `elemRegs` liveregs ]+                          , not (elementOfUniqSet reg liveregs) ] -            w_dying     = mkRegsMaxFmt+            w_dying     = mkUniqSet                           [ reg-                          | reg@(RegWithFormat r _) <- written-                          , not $ r `elemRegs` liveregs ]+                          | reg <- written+                          , not (elementOfUniqSet reg liveregs) ]              -- union in the live regs from all the jump destinations of this             -- instruction.@@ -1066,91 +1060,14 @@             targetLiveRegs target                   = case mapLookup target blockmap of                                 Just ra -> ra-                                Nothing -> noRegs--            -- registers that are live only in the branch targets should-            -- be listed as dying here.-            live_from_branch = unionManyRegsMaxFmt (map targetLiveRegs targets)-            liveregs_br = liveregs1 `unionRegsMaxFmt` live_from_branch-            live_branch_only = live_from_branch `minusRegs` liveregs-            r_dying_br  = r_dying `unionRegsMaxFmt` live_branch_only-              -- NB: we treat registers live in branches similar to any other-              -- registers read by the instruction, so the logic here matches-              -- the logic in the definition of 'r_dying' above.--{- Note [Register formats in liveness analysis]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-We keep track of which format each virtual register is live at, and make use-of this information during liveness analysis.--First, we do backwards liveness analysis:--  (FmtBwd1) Take the larger format when computing registers live going backwards.--    Suppose for example that we have:--      <previous instructions>-      movps  %v0 %v1-      movupd %v0 %v2--    Here we read %v0 both at format F64 and F64x2, so we must consider it live-    at format F64x2, going backwards, in the previous instructions.-    Not doing so caused #26411.--  (FmtBwd2) Only consider fully clobbered registers to be dead going backwards.--    Consider for example the liveness of %v0 going backwards in the following-    instruction block:--      movlhps %v5 %v0  -- write the upper F64 of %v0-      movupd  %v1 %v2  -- some unrelated instruction-      movsd   %v3 %v0  -- write the lower F64 of %v0-      movupd  %v0 %v4  -- read %v0 at format F64x2--    We must not consider %v0 to be dead going backwards from 'movsd %v3 %v0'.-    If we do, that means we think %v0 is dead during 'movupd %v1 %v2', and thus-    that we can assign both %v0 and %v2 to the same real register. However, this-    would be catastrophic, as 'movupd %v1 %v2' would then clobber the data-    written to '%v0' in 'movlhps %v5 %v0'.--    Wrinkle [Don't allow scalar partial writes]--      We don't allow partial writes within scalar registers, for many reasons:--        - partial writes can cause partial register stalls, which can have-          disastrous performance implications (as seen in #20405)-        - partial writes makes register allocation more difficult, as they can-          require preserving the contents of a register across many instructions,-          as in:--            mulw %v0             -- 32-bit write to %rax-            <many instructions>-            mulb %v1             -- 16-bit partial write to %rax--          The current register allocator is not equipped for spilling real-          registers (only virtual registers), which means that e.g. on i386 we-          end up with only 2 allocatable real GP registers for <many instructions>,-          which is insufficient for instructions that require 3 registers.--      We could allow this to be customised depending on the architecture, but-      currently we simply never allow scalar partial writes.--The forwards analysis is a bit simpler:--  (FmtFwd1) Remove without considering format when dead going forwards.--    If a register is no longer read after an instruction, then it is dead-    going forwards. The format doesn't matter.+                                Nothing -> emptyUniqSet -  (FmtFwd2) Consider all writes as making a register dead going forwards.+            live_from_branch = unionManyUniqSets (map targetLiveRegs targets) -    If we write to the lower 64 bits of a 128 bit register, we don't currently-    have a way to say "the lower 64 bits are dead but the top 64 bits are still live".-    We would need a notion of partial register, similar to 'VirtualRegHi' for-    the top 32 bits of a I32x2 virtual register.+            liveregs_br = liveregs1 `unionUniqSets` live_from_branch -    As a result, the current approach is to consider the entire register to-    be dead. This might cause us to unnecessarily spill/reload an entire vector-    register to avoid its lower bits getting clobbered even though later-    instructions might only care about its upper bits.--}+            -- registers that are live only in the branch targets should+            -- be listed as dying here.+            live_branch_only = live_from_branch `minusUniqSet` liveregs+            r_dying_br  = (r_dying `unionUniqSets` live_branch_only)+                          -- See Note [Unique Determinism and code generation]
− GHC/CmmToAsm/Reg/Regs.hs
@@ -1,119 +0,0 @@-{-# LANGUAGE DerivingStrategies #-}--module GHC.CmmToAsm.Reg.Regs (-        Regs(..),-        noRegs,-        addRegMaxFmt, addRegsMaxFmt,-        mkRegsMaxFmt,-        minusCoveredRegs,-        minusRegs,-        unionRegsMaxFmt,-        unionManyRegsMaxFmt,-        intersectRegsMaxFmt,-        shrinkingRegs,-        mapRegs,-        elemRegs, lookupReg,--  ) where--import GHC.Prelude--import GHC.Platform.Reg     ( Reg )-import GHC.CmmToAsm.Format  ( Format, RegWithFormat(..), isVecFormat )--import GHC.Utils.Outputable ( Outputable )-import GHC.Types.Unique     ( Uniquable(..) )-import GHC.Types.Unique.Set--import Data.Coerce ( coerce )----------------------------------------------------------------------------------- | A set of registers, with their respective formats, mostly for use in--- register liveness analysis.  See Note [Register formats in liveness analysis]--- in GHC.CmmToAsm.Reg.Liveness.-newtype Regs = Regs { getRegs :: UniqSet RegWithFormat }-  deriving newtype (Eq, Outputable)--maxRegWithFormat :: RegWithFormat -> RegWithFormat -> RegWithFormat-maxRegWithFormat r1@(RegWithFormat _ fmt1) r2@(RegWithFormat _ fmt2)-  = if fmt1 >= fmt2-    then r1-    else r2-  -- Re-using one of the arguments avoids allocating a new 'RegWithFormat',-  -- compared with returning 'RegWithFormat r1 (max fmt1 fmt2)'.--noRegs :: Regs-noRegs = Regs emptyUniqSet--addRegsMaxFmt :: Regs -> [RegWithFormat] -> Regs-addRegsMaxFmt = foldl' addRegMaxFmt--mkRegsMaxFmt :: [RegWithFormat] -> Regs-mkRegsMaxFmt = addRegsMaxFmt noRegs--addRegMaxFmt :: Regs -> RegWithFormat -> Regs-addRegMaxFmt = coerce $ strictAddOneToUniqSet_C maxRegWithFormat-  -- Don't build up thunks when combining with 'maxRegWithFormat'---- | Remove 2nd argument registers from the 1st argument, but only--- if the format in the second argument is at least as large as the format--- in the first argument.-minusCoveredRegs :: Regs -> Regs -> Regs-minusCoveredRegs = coerce $ minusUniqSet_C f-  where-    f :: RegWithFormat -> RegWithFormat -> Maybe RegWithFormat-    f r1@(RegWithFormat _ fmt1) (RegWithFormat _ fmt2) =-      if fmt2 >= fmt1-           ||-         not ( isVecFormat fmt1 )-          -- See Wrinkle [Don't allow scalar partial writes]-          -- in Note [Register formats in liveness analysis] in GHC.CmmToAsm.Reg.Liveness.-      then Nothing-      else Just r1---- | Remove 2nd argument registers from the 1st argument, regardless of format.------ See also 'minusCoveredRegs', which looks at the formats.-minusRegs :: Regs -> Regs -> Regs-minusRegs = coerce $ minusUniqSet @RegWithFormat--unionRegsMaxFmt :: Regs -> Regs -> Regs-unionRegsMaxFmt = coerce $ strictUnionUniqSets_C maxRegWithFormat-  -- Don't build up thunks when combining with 'maxRegWithFormat'--unionManyRegsMaxFmt :: [Regs] -> Regs-unionManyRegsMaxFmt = coerce $ strictUnionManyUniqSets_C maxRegWithFormat-  -- Don't build up thunks when combining with 'maxRegWithFormat'--intersectRegsMaxFmt :: Regs -> Regs -> Regs-intersectRegsMaxFmt = coerce $ strictIntersectUniqSets_C maxRegWithFormat-  -- Don't build up thunks when combining with 'maxRegWithFormat'---- | Computes the set of registers in both arguments whose size is smaller in--- the second argument than in the first.-shrinkingRegs :: Regs -> Regs -> Regs-shrinkingRegs = coerce $ minusUniqSet_C f-  where-    f :: RegWithFormat -> RegWithFormat -> Maybe RegWithFormat-    f (RegWithFormat _ fmt1) r2@(RegWithFormat _ fmt2)-      | fmt2 < fmt1-      = Just r2-      | otherwise-      = Nothing---- | Map a function that may change the 'Unique' of the register,--- which entails going via lists.------ See Note [UniqSet invariant] in GHC.Types.Unique.Set.-mapRegs :: (Reg -> Reg) -> Regs -> Regs-mapRegs f (Regs live) =-  Regs $-    mapUniqSet (\ (RegWithFormat r fmt) -> RegWithFormat (f r) fmt) live--elemRegs :: Reg -> Regs -> Bool-elemRegs r (Regs live) = elemUniqSet_Directly (getUnique r) live--lookupReg :: Reg -> Regs -> Maybe Format-lookupReg r (Regs live) =-  regWithFormat_format <$> lookupUniqSet_Directly live (getUnique r)
GHC/CmmToAsm/Reg/Target.hs view
@@ -15,6 +15,7 @@         targetMkVirtualReg,         targetRegDotColor,         targetClassOfReg,+        mapRegFormatSet, )  where@@ -26,8 +27,10 @@ import GHC.CmmToAsm.Format  import GHC.Utils.Outputable+import GHC.Utils.Misc import GHC.Utils.Panic import GHC.Types.Unique+import GHC.Types.Unique.Set import GHC.Platform  import qualified GHC.CmmToAsm.X86.Regs       as X86@@ -35,6 +38,7 @@ import qualified GHC.CmmToAsm.PPC.Regs       as PPC import qualified GHC.CmmToAsm.AArch64.Regs   as AArch64 import qualified GHC.CmmToAsm.RV64.Regs   as RV64+import qualified GHC.CmmToAsm.LA64.Regs      as LA64  targetVirtualRegSqueeze :: Platform -> RegClass -> VirtualReg -> Int targetVirtualRegSqueeze platform@@ -50,7 +54,7 @@       ArchMipseb    -> panic "targetVirtualRegSqueeze ArchMipseb"       ArchMipsel    -> panic "targetVirtualRegSqueeze ArchMipsel"       ArchRISCV64   -> RV64.virtualRegSqueeze-      ArchLoongArch64->panic "targetVirtualRegSqueeze ArchLoongArch64"+      ArchLoongArch64 -> LA64.virtualRegSqueeze       ArchJavaScript-> panic "targetVirtualRegSqueeze ArchJavaScript"       ArchWasm32    -> panic "targetVirtualRegSqueeze ArchWasm32"       ArchUnknown   -> panic "targetVirtualRegSqueeze ArchUnknown"@@ -70,7 +74,7 @@       ArchMipseb    -> panic "targetRealRegSqueeze ArchMipseb"       ArchMipsel    -> panic "targetRealRegSqueeze ArchMipsel"       ArchRISCV64   -> RV64.realRegSqueeze-      ArchLoongArch64->panic "targetRealRegSqueeze ArchLoongArch64"+      ArchLoongArch64 -> LA64.realRegSqueeze       ArchJavaScript-> panic "targetRealRegSqueeze ArchJavaScript"       ArchWasm32    -> panic "targetRealRegSqueeze ArchWasm32"       ArchUnknown   -> panic "targetRealRegSqueeze ArchUnknown"@@ -89,7 +93,7 @@       ArchMipseb    -> panic "targetClassOfRealReg ArchMipseb"       ArchMipsel    -> panic "targetClassOfRealReg ArchMipsel"       ArchRISCV64   -> RV64.classOfRealReg-      ArchLoongArch64->panic "targetClassOfRealReg ArchLoongArch64"+      ArchLoongArch64 -> LA64.classOfRealReg       ArchJavaScript-> panic "targetClassOfRealReg ArchJavaScript"       ArchWasm32    -> panic "targetClassOfRealReg ArchWasm32"       ArchUnknown   -> panic "targetClassOfRealReg ArchUnknown"@@ -108,7 +112,7 @@       ArchMipseb    -> panic "targetMkVirtualReg ArchMipseb"       ArchMipsel    -> panic "targetMkVirtualReg ArchMipsel"       ArchRISCV64   -> RV64.mkVirtualReg-      ArchLoongArch64->panic "targetMkVirtualReg ArchLoongArch64"+      ArchLoongArch64 -> LA64.mkVirtualReg       ArchJavaScript-> panic "targetMkVirtualReg ArchJavaScript"       ArchWasm32    -> panic "targetMkVirtualReg ArchWasm32"       ArchUnknown   -> panic "targetMkVirtualReg ArchUnknown"@@ -127,7 +131,7 @@       ArchMipseb    -> panic "targetRegDotColor ArchMipseb"       ArchMipsel    -> panic "targetRegDotColor ArchMipsel"       ArchRISCV64   -> RV64.regDotColor-      ArchLoongArch64->panic "targetRegDotColor ArchLoongArch64"+      ArchLoongArch64 -> LA64.regDotColor       ArchJavaScript-> panic "targetRegDotColor ArchJavaScript"       ArchWasm32    -> panic "targetRegDotColor ArchWasm32"       ArchUnknown   -> panic "targetRegDotColor ArchUnknown"@@ -138,3 +142,6 @@  = case reg of    RegVirtual vr -> classOfVirtualReg (platformArch platform) vr    RegReal rr -> targetClassOfRealReg platform rr++mapRegFormatSet :: HasDebugCallStack => (Reg -> Reg) -> UniqSet RegWithFormat -> UniqSet RegWithFormat+mapRegFormatSet f = mapUniqSet (\ ( RegWithFormat r fmt ) -> RegWithFormat ( f r ) fmt)
GHC/CmmToAsm/Wasm/FromCmm.hs view
@@ -113,7 +113,7 @@ -- | Calculate a data section's kind, see haddock docs of -- 'DataSectionKind' for more explanation. dataSectionKindFromCmmSection :: Section -> DataSectionKind-dataSectionKindFromCmmSection (Section t _) = case sectionProtection t of+dataSectionKindFromCmmSection s = case sectionProtection s of   ReadWriteSection -> SectionData   _ -> SectionROData 
GHC/CmmToAsm/X86/CodeGen.hs view
@@ -6,5115 +6,6252 @@ {-# LANGUAGE TupleSections #-} {-# LANGUAGE NondecreasingIndentation #-} -{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-}------------------------------------------------------------------------------------- Generating machine code (instruction selection)------ (c) The University of Glasgow 1996-2004------------------------------------------------------------------------------------- This is a big module, but, if you pay attention to--- (a) the sectioning, and (b) the type signatures, the--- structure should not be too overwhelming.--module GHC.CmmToAsm.X86.CodeGen (-        cmmTopCodeGen,-        generateJumpTableForInstr,-        extractUnwindPoints,-        invertCondBranches,-        InstrBlock-)--where---- NCG stuff:-import GHC.Prelude--import GHC.CmmToAsm.X86.Instr-import GHC.CmmToAsm.X86.Cond-import GHC.CmmToAsm.X86.Regs-import GHC.CmmToAsm.X86.Ppr-import GHC.CmmToAsm.X86.RegInfo--import GHC.Platform.Regs-import GHC.CmmToAsm.CPrim-import GHC.CmmToAsm.Types-import GHC.Cmm.DebugBlock-   ( DebugBlock(..), UnwindPoint(..), UnwindTable-   , UnwindExpr(UwReg), toUnwindExpr-   )-import GHC.CmmToAsm.PIC-import GHC.CmmToAsm.Monad-   ( NatM, getNewRegNat, getNewLabelNat, setDeltaNat-   , getDeltaNat, getBlockIdNat, getPicBaseNat-   , Reg64(..), RegCode64(..), getNewReg64, localReg64-   , getPicBaseMaybeNat, getDebugBlock, getFileId-   , addImmediateSuccessorNat, updateCfgNat, getConfig, getPlatform-   , getCfgWeights-   )-import GHC.CmmToAsm.CFG-import GHC.CmmToAsm.Format-import GHC.CmmToAsm.Config-import GHC.Platform.Reg-import GHC.CmmToAsm.Reg.Target (targetClassOfReg)-import GHC.Platform-import GHC.Platform.Reg.Class.Unified (RegClass(..))---- Our intermediate code:-import GHC.Types.Basic-import GHC.Cmm.BlockId-import GHC.Unit.Types ( primUnitId )-import GHC.Cmm.Utils-import GHC.Cmm.Switch-import GHC.Cmm-import GHC.Cmm.Dataflow.Block-import GHC.Cmm.Dataflow.Graph-import GHC.Cmm.Dataflow.Label-import GHC.Cmm.CLabel-import GHC.Types.Tickish ( GenTickish(..) )-import GHC.Types.SrcLoc  ( srcSpanFile, srcSpanStartLine, srcSpanStartCol )---- The rest:-import GHC.Data.Maybe ( expectJust )-import GHC.Types.ForeignCall ( CCallConv(..) )-import GHC.Data.OrdList-import GHC.Utils.Outputable-import GHC.Utils.Constants (debugIsOn)-import GHC.Utils.Monad ( foldMapM )-import GHC.Utils.Panic-import GHC.Data.FastString-import GHC.Utils.Misc-import GHC.Types.Unique.DSM ( getUniqueM )--import qualified Data.Semigroup as S--import Control.Monad-import Control.Monad.Trans.State.Strict-  ( StateT, evalStateT, get, put )-import Control.Monad.Trans.Class (lift)-import Data.Foldable (fold)-import Data.Int-import Data.Maybe-import Data.Word--import qualified Data.Map as Map--is32BitPlatform :: NatM Bool-is32BitPlatform = do-    platform <- getPlatform-    return $ target32Bit platform--sse4_1Enabled :: NatM Bool-sse4_1Enabled = do-  config <- getConfig-  return (ncgSseVersion config >= Just SSE4)--sse4_2Enabled :: NatM Bool-sse4_2Enabled = do-  config <- getConfig-  return (ncgSseVersion config >= Just SSE42)--avxEnabled :: NatM Bool-avxEnabled = do-  config <- getConfig-  return (ncgAvxEnabled config)--cmmTopCodeGen-        :: RawCmmDecl-        -> NatM [NatCmmDecl (Alignment, RawCmmStatics) Instr]--cmmTopCodeGen (CmmProc info lab live graph) = do-  let blocks = toBlockListEntryFirst graph-  (nat_blocks,statics) <- mapAndUnzipM basicBlockCodeGen blocks-  picBaseMb <- getPicBaseMaybeNat-  platform <- getPlatform-  let proc = CmmProc info lab live (ListGraph $ concat nat_blocks)-      tops = proc : concat statics-      os   = platformOS platform--  case picBaseMb of-      Just picBase -> initializePicBase_x86 os picBase tops-      Nothing -> return tops--cmmTopCodeGen (CmmData sec dat) =-  return [CmmData sec (mkAlignment 1, dat)]  -- no translation, we just use CmmStatic--{- Note [Verifying basic blocks]-   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-   We want to guarantee a few things about the results-   of instruction selection.--   Namely that each basic blocks consists of:-    * A (potentially empty) sequence of straight line instructions-  followed by-    * A (potentially empty) sequence of jump like instructions.--    We can verify this by going through the instructions and-    making sure that any non-jumpish instruction can't appear-    after a jumpish instruction.--    There are gotchas however:-    * CALLs are strictly speaking control flow but here we care-      not about them. Hence we treat them as regular instructions.--      It's safe for them to appear inside a basic block-      as (ignoring side effects inside the call) they will result in-      straight line code.--    * NEWBLOCK marks the start of a new basic block so can-      be followed by any instructions.--}---- Verifying basic blocks is cheap, but not cheap enough to enable it unconditionally.-verifyBasicBlock :: Platform -> [Instr] -> ()-verifyBasicBlock platform instrs-  | debugIsOn     = go False instrs-  | otherwise     = ()-  where-    go _     [] = ()-    go atEnd (i:instr)-        = case i of-            -- Start a new basic block-            NEWBLOCK {} -> go False instr-            -- Calls are not viable block terminators-            CALL {}     | atEnd -> faultyBlockWith i-                        | not atEnd -> go atEnd instr-            -- All instructions ok, check if we reached the end and continue.-            _ | not atEnd -> go (isJumpishInstr i) instr-              -- Only jumps allowed at the end of basic blocks.-              | otherwise -> if isJumpishInstr i-                                then go True instr-                                else faultyBlockWith i-    faultyBlockWith i-        = pprPanic "Non control flow instructions after end of basic block."-                   (pprInstr platform i <+> text "in:" $$ vcat (map (pprInstr platform) instrs))--basicBlockCodeGen-        :: CmmBlock-        -> NatM ( [NatBasicBlock Instr]-                , [NatCmmDecl (Alignment, RawCmmStatics) Instr])--basicBlockCodeGen block = do-  let (_, nodes, tail)  = blockSplit block-      id = entryLabel block-      stmts = blockToList nodes-  -- Generate location directive-  dbg <- getDebugBlock (entryLabel block)-  loc_instrs <- case dblSourceTick =<< dbg of-    Just (SourceNote span (LexicalFastString name))-      -> do fileId <- getFileId (srcSpanFile span)-            let line = srcSpanStartLine span; col = srcSpanStartCol span-            return $ unitOL $ LOCATION fileId line col (unpackFS name)-    _ -> return nilOL-  (mid_instrs,mid_bid) <- stmtsToInstrs id stmts-  (!tail_instrs,_) <- stmtToInstrs mid_bid tail-  let instrs = loc_instrs `appOL` mid_instrs `appOL` tail_instrs-  platform <- getPlatform-  return $! verifyBasicBlock platform (fromOL instrs)-  instrs' <- fold <$> traverse addSpUnwindings instrs-  -- code generation may introduce new basic block boundaries, which-  -- are indicated by the NEWBLOCK instruction.  We must split up the-  -- instruction stream into basic blocks again.  Also, we extract-  -- LDATAs here too.-  let-        (top,other_blocks,statics) = foldrOL mkBlocks ([],[],[]) instrs'--        mkBlocks (NEWBLOCK id) (instrs,blocks,statics)-          = ([], BasicBlock id instrs : blocks, statics)-        mkBlocks (LDATA sec dat) (instrs,blocks,statics)-          = (instrs, blocks, CmmData sec dat:statics)-        mkBlocks instr (instrs,blocks,statics)-          = (instr:instrs, blocks, statics)-  return (BasicBlock id top : other_blocks, statics)---- | Convert 'DELTA' instructions into 'UNWIND' instructions to capture changes--- in the @sp@ register. See Note [What is this unwinding business?] in "GHC.Cmm.DebugBlock"--- for details.-addSpUnwindings :: Instr -> NatM (OrdList Instr)-addSpUnwindings instr@(DELTA d) = do-    config <- getConfig-    let platform = ncgPlatform config-    if ncgDwarfUnwindings config-        then do lbl <- mkAsmTempLabel <$> getUniqueM-                let unwind = Map.singleton MachSp (Just $ UwReg (GlobalRegUse MachSp (bWord platform)) $ negate d)-                return $ toOL [ instr, UNWIND lbl unwind ]-        else return (unitOL instr)-addSpUnwindings instr = return $ unitOL instr--{- Note [Keeping track of the current block]-   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-When generating instructions for Cmm we sometimes require-the current block for things like retry loops.--We also sometimes change the current block, if a MachOP-results in branching control flow.--Issues arise if we have two statements in the same block,-which both depend on the current block id *and* change the-basic block after them. This happens for atomic primops-in the X86 backend where we want to update the CFG data structure-when introducing new basic blocks.--For example in #17334 we got this Cmm code:--        c3Bf: // global-            (_s3t1::I64) = call MO_AtomicRMW W64 AMO_And(_s3sQ::P64 + 88, 18);-            (_s3t4::I64) = call MO_AtomicRMW W64 AMO_Or(_s3sQ::P64 + 88, 0);-            _s3sT::I64 = _s3sV::I64;-            goto c3B1;--This resulted in two new basic blocks being inserted:--        c3Bf:-                movl $18,%vI_n3Bo-                movq 88(%vI_s3sQ),%rax-                jmp _n3Bp-        n3Bp:-                ...-                cmpxchgq %vI_n3Bq,88(%vI_s3sQ)-                jne _n3Bp-                ...-                jmp _n3Bs-        n3Bs:-                ...-                cmpxchgq %vI_n3Bt,88(%vI_s3sQ)-                jne _n3Bs-                ...-                jmp _c3B1-        ...--Based on the Cmm we called stmtToInstrs we translated both atomic operations under-the assumption they would be placed into their Cmm basic block `c3Bf`.-However for the retry loop we introduce new labels, so this is not the case-for the second statement.-This resulted in a desync between the explicit control flow graph-we construct as a separate data type and the actual control flow graph in the code.--Instead we now return the new basic block if a statement causes a change-in the current block and use the block for all following statements.--For this reason genForeignCall is also split into two parts.  One for calls which-*won't* change the basic blocks in which successive instructions will be-placed (since they only evaluate CmmExpr, which can only contain MachOps, which-cannot introduce basic blocks in their lowerings).  A different one for calls-which *are* known to change the basic block.---}---- See Note [Keeping track of the current block] for why--- we pass the BlockId.-stmtsToInstrs :: BlockId -- ^ Basic block these statement will start to be placed in.-              -> [CmmNode O O] -- ^ Cmm Statement-              -> NatM (InstrBlock, BlockId) -- ^ Resulting instruction-stmtsToInstrs bid stmts =-    go bid stmts nilOL-  where-    go bid  []        instrs = return (instrs,bid)-    go bid (s:stmts)  instrs = do-      (instrs',bid') <- stmtToInstrs bid s-      -- If the statement introduced a new block, we use that one-      let !newBid = fromMaybe bid bid'-      go newBid stmts (instrs `appOL` instrs')---- | `bid` refers to the current block and is used to update the CFG---   if new blocks are inserted in the control flow.--- See Note [Keeping track of the current block] for more details.-stmtToInstrs :: BlockId -- ^ Basic block this statement will start to be placed in.-             -> CmmNode e x-             -> NatM (InstrBlock, Maybe BlockId)-             -- ^ Instructions, and bid of new block if successive-             -- statements are placed in a different basic block.-stmtToInstrs bid stmt = do-  is32Bit <- is32BitPlatform-  platform <- getPlatform-  case stmt of-    CmmUnsafeForeignCall target result_regs args-       -> genForeignCall target result_regs args bid--    _ -> (,Nothing) <$> case stmt of-      CmmComment s   -> return (unitOL (COMMENT s))-      CmmTick {}     -> return nilOL--      CmmUnwind regs -> do-        let to_unwind_entry :: (GlobalReg, Maybe CmmExpr) -> UnwindTable-            to_unwind_entry (reg, expr) = Map.singleton reg (fmap (toUnwindExpr platform) expr)-        case foldMap to_unwind_entry regs of-          tbl | Map.null tbl -> return nilOL-              | otherwise    -> do-                  lbl <- mkAsmTempLabel <$> getUniqueM-                  return $ unitOL $ UNWIND lbl tbl--      CmmAssign reg src-        | isFloatType ty         -> assignReg_FltCode reg src-        | is32Bit && isWord64 ty -> assignReg_I64Code reg src-        | isVecType ty           -> assignReg_VecCode reg src-        | otherwise              -> assignReg_IntCode reg src-          where ty = cmmRegType reg--      CmmStore addr src _alignment-        | isFloatType ty         -> assignMem_FltCode format addr src-        | is32Bit && isWord64 ty -> assignMem_I64Code        addr src-        | isVecType ty           -> assignMem_VecCode format addr src-        | otherwise              -> assignMem_IntCode format addr src-          where ty = cmmExprType platform src-                format = cmmTypeFormat ty--      CmmBranch id          -> return $ genBranch id--      --We try to arrange blocks such that the likely branch is the fallthrough-      --in GHC.Cmm.ContFlowOpt. So we can assume the condition is likely false here.-      CmmCondBranch arg true false _ -> genCondBranch bid true false arg-      CmmSwitch arg ids -> genSwitch arg ids-      CmmCall { cml_target = arg-              , cml_args_regs = gregs } -> genJump arg (jumpRegs platform gregs)-      _ ->-        panic "stmtToInstrs: statement should have been cps'd away"---jumpRegs :: Platform -> [GlobalRegUse] -> [RegWithFormat]-jumpRegs platform gregs =-  [ RegWithFormat (RegReal r) (cmmTypeFormat ty)-  | GlobalRegUse gr ty <- gregs-  , Just r <- [globalRegMaybe platform gr] ]------------------------------------------------------------------------------------- | 'InstrBlock's are the insn sequences generated by the insn selectors.---      They are really trees of insns to facilitate fast appending, where a---      left-to-right traversal yields the insns in the correct order.----type InstrBlock-        = OrdList Instr----- | Condition codes passed up the tree.----data CondCode-        = CondCode Bool Cond InstrBlock----- | Register's passed up the tree.  If the stix code forces the register---      to live in a pre-decided machine register, it comes out as @Fixed@;---      otherwise, it comes out as @Any@, and the parent can decide which---      register to put it in.----data Register-        = Fixed Format Reg InstrBlock-        | Any   Format (Reg -> InstrBlock)---swizzleRegisterRep :: Register -> Format -> Register-swizzleRegisterRep (Fixed _ reg code) format = Fixed format reg code-swizzleRegisterRep (Any _ codefn)     format = Any   format codefn--getLocalRegReg :: LocalReg -> Reg-getLocalRegReg (LocalReg u ty)-  = -- by assuming SSE2, Int, Word, Float, Double and vectors all can be register allocated-    RegVirtual (mkVirtualReg u (cmmTypeFormat ty))---- | Grab the Reg for a CmmReg-getRegisterReg :: Platform  -> CmmReg -> Reg--getRegisterReg _   (CmmLocal lreg) = getLocalRegReg lreg--getRegisterReg platform  (CmmGlobal mid)-  = case globalRegMaybe platform $ globalRegUse_reg mid of-        Just reg -> RegReal $ reg-        Nothing  -> pprPanic "getRegisterReg-memory" (ppr $ CmmGlobal mid)-        -- By this stage, the only MagicIds remaining should be the-        -- ones which map to a real machine register on this-        -- platform.  Hence ...---- | Memory addressing modes passed up the tree.-data Amode-        = Amode AddrMode InstrBlock--{--Now, given a tree (the argument to a CmmLoad) that references memory,-produce a suitable addressing mode.--A Rule of the Game (tm) for Amodes: use of the addr bit must-immediately follow use of the code part, since the code part puts-values in registers which the addr then refers to.  So you can't put-anything in between, lest it overwrite some of those registers.  If-you need to do some other computation between the code part and use of-the addr bit, first store the effective address from the amode in a-temporary, then do the other computation, and then use the temporary:--    code-    LEA amode, tmp-    ... other computation ...-    ... (tmp) ...--}--{--Note [%rip-relative addressing on x86-64]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-On x86-64 GHC produces code for use in the "small" or, when `-fPIC` is set,-"small PIC" code models defined by the x86-64 System V ABI (section 3.5.1 of-specification version 0.99).--In general the small code model would allow us to assume that code is located-between 0 and 2^31 - 1. However, this is not true on Windows which, due to-high-entropy ASLR, may place the executable image anywhere in 64-bit address-space. This is problematic since immediate operands in x86-64 are generally-32-bit sign-extended values (with the exception of the 64-bit MOVABS encoding).-Consequently, to avoid overflowing we use %rip-relative addressing universally.-Since %rip-relative addressing comes essentially for free and makes linking far-easier, we use it even on non-Windows platforms.--See also: the documentation for GCC's `-mcmodel=small` flag.--}----- | Check whether an integer will fit in 32 bits.---      A CmmInt is intended to be truncated to the appropriate---      number of bits, so here we truncate it to Int64.  This is---      important because e.g. -1 as a CmmInt might be either---      -1 or 18446744073709551615.----is32BitInteger :: Integer -> Bool-is32BitInteger i = i64 <= 0x7fffffff && i64 >= -0x80000000-  where i64 = fromIntegral i :: Int64----- | Convert a BlockId to some CmmStatic data-jumpTableEntry :: NCGConfig -> Maybe BlockId -> CmmStatic-jumpTableEntry config Nothing = CmmStaticLit (CmmInt 0 (ncgWordWidth config))-jumpTableEntry _ (Just blockid) = CmmStaticLit (CmmLabel blockLabel)-    where blockLabel = blockLbl blockid----- -------------------------------------------------------------------------------- General things for putting together code sequences---- Expand CmmRegOff.  ToDo: should we do it this way around, or convert--- CmmExprs into CmmRegOff?-mangleIndexTree :: CmmReg -> Int -> CmmExpr-mangleIndexTree reg off-  = CmmMachOp (MO_Add width) [CmmReg reg, CmmLit (CmmInt (fromIntegral off) width)]-  where width = typeWidth (cmmRegType reg)---- | The dual to getAnyReg: compute an expression into a register, but---      we don't mind which one it is.-getSomeReg :: CmmExpr -> NatM (Reg, InstrBlock)-getSomeReg expr = do-  r <- getRegister expr-  case r of-    Any rep code -> do-        tmp <- getNewRegNat rep-        return (tmp, code tmp)-    Fixed _ reg code ->-        return (reg, code)--assignMem_I64Code :: CmmExpr -> CmmExpr -> NatM InstrBlock-assignMem_I64Code addrTree valueTree = do-  Amode addr addr_code <- getAmode addrTree-  RegCode64 vcode rhi rlo <- iselExpr64 valueTree-  let-        -- Little-endian store-        mov_lo = MOV II32 (OpReg rlo) (OpAddr addr)-        mov_hi = MOV II32 (OpReg rhi) (OpAddr (fromJust (addrOffset addr 4)))-  return (vcode `appOL` addr_code `snocOL` mov_lo `snocOL` mov_hi)---assignReg_I64Code :: CmmReg  -> CmmExpr -> NatM InstrBlock-assignReg_I64Code (CmmLocal dst) valueTree = do-   RegCode64 vcode r_src_hi r_src_lo <- iselExpr64 valueTree-   let-         Reg64 r_dst_hi r_dst_lo = localReg64 dst-         mov_lo = MOV II32 (OpReg r_src_lo) (OpReg r_dst_lo)-         mov_hi = MOV II32 (OpReg r_src_hi) (OpReg r_dst_hi)-   return (-        vcode `snocOL` mov_lo `snocOL` mov_hi-     )--assignReg_I64Code _ _-   = panic "assignReg_I64Code(i386): invalid lvalue"--iselExpr64 :: HasDebugCallStack => CmmExpr -> NatM (RegCode64 InstrBlock)-iselExpr64 (CmmLit (CmmInt i _)) = do-  Reg64 rhi rlo <- getNewReg64-  let-        r = fromIntegral (fromIntegral i :: Word32)-        q = fromIntegral (fromIntegral (i `shiftR` 32) :: Word32)-        code = toOL [-                MOV II32 (OpImm (ImmInteger r)) (OpReg rlo),-                MOV II32 (OpImm (ImmInteger q)) (OpReg rhi)-                ]-  return (RegCode64 code rhi rlo)--iselExpr64 (CmmLoad addrTree ty _) | isWord64 ty = do-   Amode addr addr_code <- getAmode addrTree-   Reg64 rhi rlo <- getNewReg64-   let-        mov_lo = MOV II32 (OpAddr addr) (OpReg rlo)-        mov_hi = MOV II32 (OpAddr (fromJust (addrOffset addr 4))) (OpReg rhi)-   return (-            RegCode64 (addr_code `snocOL` mov_lo `snocOL` mov_hi) rhi rlo-     )--iselExpr64 (CmmReg (CmmLocal local_reg)) = do-  let Reg64 hi lo = localReg64 local_reg-  return (RegCode64 nilOL hi lo)--iselExpr64 (CmmMachOp (MO_Add _) [e1, CmmLit (CmmInt i _)]) = do-   RegCode64 code1 r1hi r1lo <- iselExpr64 e1-   Reg64 rhi rlo <- getNewReg64-   let-        r = fromIntegral (fromIntegral i :: Word32)-        q = fromIntegral (fromIntegral (i `shiftR` 32) :: Word32)-        code =  code1 `appOL`-                toOL [ MOV II32 (OpReg r1lo) (OpReg rlo),-                       ADD II32 (OpImm (ImmInteger r)) (OpReg rlo),-                       MOV II32 (OpReg r1hi) (OpReg rhi),-                       ADC II32 (OpImm (ImmInteger q)) (OpReg rhi) ]-   return (RegCode64 code rhi rlo)--iselExpr64 (CmmMachOp (MO_Add _) [e1,e2]) = do-   RegCode64 code1 r1hi r1lo <- iselExpr64 e1-   RegCode64 code2 r2hi r2lo <- iselExpr64 e2-   Reg64 rhi rlo <- getNewReg64-   let-        code =  code1 `appOL`-                code2 `appOL`-                toOL [ MOV II32 (OpReg r1lo) (OpReg rlo),-                       ADD II32 (OpReg r2lo) (OpReg rlo),-                       MOV II32 (OpReg r1hi) (OpReg rhi),-                       ADC II32 (OpReg r2hi) (OpReg rhi) ]-   return (RegCode64 code rhi rlo)--iselExpr64 (CmmMachOp (MO_Sub _) [e1,e2]) = do-   RegCode64 code1 r1hi r1lo <- iselExpr64 e1-   RegCode64 code2 r2hi r2lo <- iselExpr64 e2-   Reg64 rhi rlo <- getNewReg64-   let-        code =  code1 `appOL`-                code2 `appOL`-                toOL [ MOV II32 (OpReg r1lo) (OpReg rlo),-                       SUB II32 (OpReg r2lo) (OpReg rlo),-                       MOV II32 (OpReg r1hi) (OpReg rhi),-                       SBB II32 (OpReg r2hi) (OpReg rhi) ]-   return (RegCode64 code rhi rlo)--iselExpr64 (CmmMachOp (MO_UU_Conv W32 W64) [expr]) = do-     code <- getAnyReg expr-     Reg64 r_dst_hi r_dst_lo <- getNewReg64-     return $ RegCode64 (code r_dst_lo `snocOL`-                          XOR II32 (OpReg r_dst_hi) (OpReg r_dst_hi))-                          r_dst_hi-                          r_dst_lo--iselExpr64 (CmmMachOp (MO_UU_Conv W16 W64) [expr]) = do-     (rsrc, code) <- getByteReg expr-     Reg64 r_dst_hi r_dst_lo <- getNewReg64-     return $ RegCode64 (code `appOL` toOL [-                          MOVZxL II16 (OpReg rsrc) (OpReg r_dst_lo),-                          XOR    II32 (OpReg r_dst_hi) (OpReg r_dst_hi)-                          ])-                          r_dst_hi-                          r_dst_lo--iselExpr64 (CmmMachOp (MO_UU_Conv W8 W64) [expr]) = do-     (rsrc, code) <- getByteReg expr-     Reg64 r_dst_hi r_dst_lo <- getNewReg64-     return $ RegCode64 (code `appOL` toOL [-                          MOVZxL II8 (OpReg rsrc) (OpReg r_dst_lo),-                          XOR    II32 (OpReg r_dst_hi) (OpReg r_dst_hi)-                          ])-                          r_dst_hi-                          r_dst_lo--iselExpr64 (CmmMachOp (MO_SS_Conv W32 W64) [expr]) = do-     code <- getAnyReg expr-     Reg64 r_dst_hi r_dst_lo <- getNewReg64-     return $ RegCode64 (code r_dst_lo `snocOL`-                          MOV II32 (OpReg r_dst_lo) (OpReg eax) `snocOL`-                          CLTD II32 `snocOL`-                          MOV II32 (OpReg eax) (OpReg r_dst_lo) `snocOL`-                          MOV II32 (OpReg edx) (OpReg r_dst_hi))-                          r_dst_hi-                          r_dst_lo--iselExpr64 (CmmMachOp (MO_SS_Conv W16 W64) [expr]) = do-     (r, code) <- getByteReg expr-     Reg64 r_dst_hi r_dst_lo <- getNewReg64-     return $ RegCode64 (code `appOL` toOL [-                          MOVSxL II16 (OpReg r) (OpReg eax),-                          CLTD II32,-                          MOV II32 (OpReg eax) (OpReg r_dst_lo),-                          MOV II32 (OpReg edx) (OpReg r_dst_hi)])-                          r_dst_hi-                          r_dst_lo--iselExpr64 (CmmMachOp (MO_SS_Conv W8 W64) [expr]) = do-     (r, code) <- getByteReg expr-     Reg64 r_dst_hi r_dst_lo <- getNewReg64-     return $ RegCode64 (code `appOL` toOL [-                          MOVSxL II8 (OpReg r) (OpReg eax),-                          CLTD II32,-                          MOV II32 (OpReg eax) (OpReg r_dst_lo),-                          MOV II32 (OpReg edx) (OpReg r_dst_hi)])-                          r_dst_hi-                          r_dst_lo--iselExpr64 (CmmMachOp (MO_S_Neg _) [expr]) = do-   RegCode64 code rhi rlo <- iselExpr64 expr-   Reg64 rohi rolo <- getNewReg64-   let-        ocode = code `appOL`-                toOL [ MOV II32 (OpReg rlo) (OpReg rolo),-                       XOR II32 (OpReg rohi) (OpReg rohi),-                       NEGI II32 (OpReg rolo),-                       SBB II32 (OpReg rhi) (OpReg rohi) ]-   return (RegCode64 ocode rohi rolo)---- To multiply two 64-bit numbers we use the following decomposition (in C notation):------     ((r1hi << 32) + r1lo) * ((r2hi << 32) + r2lo)---      = ((r2lo * r1hi) << 32)---      + ((r1lo * r2hi) << 32)---      + r1lo * r2lo------ Note that @(r1hi * r2hi) << 64@ can be dropped because it overflows completely.--iselExpr64 (CmmMachOp (MO_Mul _) [e1,e2]) = do-   RegCode64 code1 r1hi r1lo <- iselExpr64 e1-   RegCode64 code2 r2hi r2lo <- iselExpr64 e2-   Reg64 rhi rlo <- getNewReg64-   tmp <- getNewRegNat II32-   let-        code =  code1 `appOL`-                code2 `appOL`-                toOL [ MOV  II32 (OpReg r1lo) (OpReg eax),-                       MOV  II32 (OpReg r2lo) (OpReg tmp),-                       MOV  II32 (OpReg r1hi) (OpReg rhi),-                       IMUL II32 (OpReg tmp) (OpReg rhi),-                       MOV  II32 (OpReg r2hi) (OpReg rlo),-                       IMUL II32 (OpReg eax) (OpReg rlo),-                       ADD  II32 (OpReg rlo) (OpReg rhi),-                       MUL2 II32 (OpReg tmp),-                       ADD  II32 (OpReg edx) (OpReg rhi),-                       MOV  II32 (OpReg eax) (OpReg rlo)-                     ]-   return (RegCode64 code rhi rlo)--iselExpr64 (CmmMachOp (MO_S_MulMayOflo W64) _) = do-   -- Performance sensitive users won't use 32 bit so let's keep it simple:-   -- We always return a (usually false) positive.-   Reg64 rhi rlo <- getNewReg64-   let code = toOL   [-                       MOV II32 (OpImm (ImmInt 1)) (OpReg rhi),-                       MOV II32 (OpImm (ImmInt 1)) (OpReg rlo)-                     ]-   return (RegCode64 code rhi rlo)----- To shift a 64-bit number to the left we use the SHLD and SHL instructions.--- We use SHLD to shift the bits in @rhi@ to the left while copying--- high bits from @rlo@ to fill the new space in the low bits of @rhi@.--- That leaves @rlo@ unchanged, so we use SHL to shift the bits of @rlo@ left.--- However, both these instructions only use the lowest 5 bits from %cl to do--- their shifting. So if the sixth bit (0x32) is set then we additionally move--- the contents of @rlo@ to @rhi@ and clear @rlo@.--iselExpr64 (CmmMachOp (MO_Shl _) [e1,e2]) = do-   RegCode64 code1 r1hi r1lo <- iselExpr64 e1-   code2 <- getAnyReg e2-   Reg64 rhi rlo <- getNewReg64-   lbl1 <- newBlockId-   lbl2 <- newBlockId-   let-        code =  code1 `appOL`-                code2 ecx `appOL`-                toOL [ MOV II32 (OpReg r1lo) (OpReg rlo),-                       MOV II32 (OpReg r1hi) (OpReg rhi),-                       SHLD II32 (OpReg ecx) (OpReg rlo) (OpReg rhi),-                       SHL II32 (OpReg ecx) (OpReg rlo),-                       TEST II32 (OpImm (ImmInt 32)) (OpReg ecx),-                       JXX EQQ lbl2,-                       JXX ALWAYS lbl1,-                       NEWBLOCK lbl1,-                       MOV II32 (OpReg rlo) (OpReg rhi),-                       XOR II32 (OpReg rlo) (OpReg rlo),-                       JXX ALWAYS lbl2,-                       NEWBLOCK lbl2-                     ]-   return (RegCode64 code rhi rlo)---- Similar to above, however now we're shifting to the right--- and we're doing a signed shift which means that @rhi@ needs--- to be set to either 0 if @rhi@ is positive or 0xffffffff otherwise,--- and if the sixth bit of %cl is set (so the shift amount is more than 32).--- To accomplish that we shift @rhi@ by 31.--iselExpr64 (CmmMachOp (MO_S_Shr _) [e1,e2]) = do-   RegCode64 code1 r1hi r1lo <- iselExpr64 e1-   (r2, code2) <- getSomeReg e2-   Reg64 rhi rlo <- getNewReg64-   lbl1 <- newBlockId-   lbl2 <- newBlockId-   let-        code =  code1 `appOL`-                code2 `appOL`-                toOL [ MOV II32 (OpReg r1lo) (OpReg rlo),-                       MOV II32 (OpReg r1hi) (OpReg rhi),-                       MOV II32 (OpReg r2) (OpReg ecx),-                       SHRD II32 (OpReg ecx) (OpReg rhi) (OpReg rlo),-                       SAR II32 (OpReg ecx) (OpReg rhi),-                       TEST II32 (OpImm (ImmInt 32)) (OpReg ecx),-                       JXX EQQ lbl2,-                       JXX ALWAYS lbl1,-                       NEWBLOCK lbl1,-                       MOV II32 (OpReg rhi) (OpReg rlo),-                       SAR II32 (OpImm (ImmInt 31)) (OpReg rhi),-                       JXX ALWAYS lbl2,-                       NEWBLOCK lbl2-                     ]-   return (RegCode64 code rhi rlo)---- Similar to the above.--iselExpr64 (CmmMachOp (MO_U_Shr _) [e1,e2]) = do-   RegCode64 code1 r1hi r1lo <- iselExpr64 e1-   (r2, code2) <- getSomeReg e2-   Reg64 rhi rlo <- getNewReg64-   lbl1 <- newBlockId-   lbl2 <- newBlockId-   let-        code =  code1 `appOL`-                code2 `appOL`-                toOL [ MOV II32 (OpReg r1lo) (OpReg rlo),-                       MOV II32 (OpReg r1hi) (OpReg rhi),-                       MOV II32 (OpReg r2) (OpReg ecx),-                       SHRD II32 (OpReg ecx) (OpReg rhi) (OpReg rlo),-                       SHR II32 (OpReg ecx) (OpReg rhi),-                       TEST II32 (OpImm (ImmInt 32)) (OpReg ecx),-                       JXX EQQ lbl2,-                       JXX ALWAYS lbl1,-                       NEWBLOCK lbl1,-                       MOV II32 (OpReg rhi) (OpReg rlo),-                       XOR II32 (OpReg rhi) (OpReg rhi),-                       JXX ALWAYS lbl2,-                       NEWBLOCK lbl2-                     ]-   return (RegCode64 code rhi rlo)--iselExpr64 (CmmMachOp (MO_And _) [e1,e2]) = iselExpr64ParallelBin AND e1 e2-iselExpr64 (CmmMachOp (MO_Or  _) [e1,e2]) = iselExpr64ParallelBin OR  e1 e2-iselExpr64 (CmmMachOp (MO_Xor _) [e1,e2]) = iselExpr64ParallelBin XOR e1 e2--iselExpr64 (CmmMachOp (MO_Not _) [e1]) = do-   RegCode64 code1 r1hi r1lo <- iselExpr64 e1-   Reg64 rhi rlo <- getNewReg64-   let-        code =  code1 `appOL`-                toOL [ MOV II32 (OpReg r1lo) (OpReg rlo),-                       MOV II32 (OpReg r1hi) (OpReg rhi),-                       NOT II32 (OpReg rlo),-                       NOT II32 (OpReg rhi)-                     ]-   return (RegCode64 code rhi rlo)--iselExpr64 (CmmRegOff r i) = iselExpr64 (mangleIndexTree r i)--iselExpr64 expr-   = do-      platform <- getPlatform-      pprPanic "iselExpr64(i386)" (pdoc platform expr $+$ text (show expr))--iselExpr64ParallelBin :: (Format -> Operand -> Operand -> Instr)-                      -> CmmExpr -> CmmExpr -> NatM (RegCode64 (OrdList Instr))-iselExpr64ParallelBin op e1 e2 = do-   RegCode64 code1 r1hi r1lo <- iselExpr64 e1-   RegCode64 code2 r2hi r2lo <- iselExpr64 e2-   Reg64 rhi rlo <- getNewReg64-   let-        code =  code1 `appOL`-                code2 `appOL`-                toOL [ MOV II32 (OpReg r1lo) (OpReg rlo),-                       MOV II32 (OpReg r1hi) (OpReg rhi),-                       op  II32 (OpReg r2lo) (OpReg rlo),-                       op  II32 (OpReg r2hi) (OpReg rhi)-                     ]-   return (RegCode64 code rhi rlo)-------------------------------------------------------------------------------------- This is a helper data type which helps reduce the code duplication for--- the code generation of arithmetic operations. This is not specifically--- targetted for any particular type like Int8, Int32 etc-data VectorArithInstns = VA_Add | VA_Sub | VA_Mul | VA_Div | VA_Min | VA_Max--getRegister :: HasDebugCallStack => CmmExpr -> NatM Register-getRegister e = do platform <- getPlatform-                   is32Bit <- is32BitPlatform-                   getRegister' platform is32Bit e--getRegister' :: HasDebugCallStack => Platform -> Bool -> CmmExpr -> NatM Register--getRegister' platform is32Bit (CmmReg reg)-  = case reg of-        CmmGlobal (GlobalRegUse PicBaseReg _)-         | is32Bit ->-            -- on x86_64, we have %rip for PicBaseReg, but it's not-            -- a full-featured register, it can only be used for-            -- rip-relative addressing.-            do reg' <- getPicBaseNat (archWordFormat is32Bit)-               return (Fixed (archWordFormat is32Bit) reg' nilOL)-        _ ->-          let ty = cmmRegType reg-              reg_fmt = cmmTypeFormat ty-          in return $ Fixed reg_fmt (getRegisterReg platform reg) nilOL--getRegister' platform is32Bit (CmmRegOff r n)-  = getRegister' platform is32Bit $ mangleIndexTree r n--getRegister' platform is32Bit (CmmMachOp (MO_RelaxedRead w) [e])-  = getRegister' platform is32Bit (CmmLoad e (cmmBits w) NaturallyAligned)--getRegister' platform is32Bit (CmmMachOp (MO_AlignmentCheck align _) [e])-  = addAlignmentCheck align <$> getRegister' platform is32Bit e---- for 32-bit architectures, support some 64 -> 32 bit conversions:--- TO_W_(x), TO_W_(x >> 32)--getRegister' _ is32Bit (CmmMachOp (MO_UU_Conv W64 W32)-                     [CmmMachOp (MO_U_Shr W64) [x,CmmLit (CmmInt 32 _)]])- | is32Bit = do-  RegCode64 code rhi _rlo <- iselExpr64 x-  return $ Fixed II32 rhi code--getRegister' _ is32Bit (CmmMachOp (MO_SS_Conv W64 W32)-                     [CmmMachOp (MO_U_Shr W64) [x,CmmLit (CmmInt 32 _)]])- | is32Bit = do-  RegCode64 code rhi _rlo <- iselExpr64 x-  return $ Fixed II32 rhi code--getRegister' _ is32Bit (CmmMachOp (MO_UU_Conv W64 W32) [x])- | is32Bit = do-  RegCode64 code _rhi rlo <- iselExpr64 x-  return $ Fixed II32 rlo code--getRegister' _ is32Bit (CmmMachOp (MO_SS_Conv W64 W32) [x])- | is32Bit = do-  RegCode64 code _rhi rlo <- iselExpr64 x-  return $ Fixed II32 rlo code--getRegister' _ is32Bit (CmmMachOp (MO_UU_Conv W64 W8) [x])- | is32Bit = do-  RegCode64 code _rhi rlo <- iselExpr64 x-  ro <- getNewRegNat II8-  return $ Fixed II8 ro (code `appOL` toOL [ MOVZxL II8 (OpReg rlo) (OpReg ro) ])--getRegister' _ is32Bit (CmmMachOp (MO_UU_Conv W64 W16) [x])- | is32Bit = do-  RegCode64 code _rhi rlo <- iselExpr64 x-  ro <- getNewRegNat II16-  return $ Fixed II16 ro (code `appOL` toOL [ MOVZxL II16 (OpReg rlo) (OpReg ro) ])---- catch simple cases of zero- or sign-extended load-getRegister' _ _ (CmmMachOp (MO_UU_Conv W8 W32) [CmmLoad addr _ _]) = do-  code <- intLoadCode (MOVZxL II8) addr-  return (Any II32 code)--getRegister' _ _ (CmmMachOp (MO_SS_Conv W8 W32) [CmmLoad addr _ _]) = do-  code <- intLoadCode (MOVSxL II8) addr-  return (Any II32 code)--getRegister' _ _ (CmmMachOp (MO_UU_Conv W16 W32) [CmmLoad addr _ _]) = do-  code <- intLoadCode (MOVZxL II16) addr-  return (Any II32 code)--getRegister' _ _ (CmmMachOp (MO_SS_Conv W16 W32) [CmmLoad addr _ _]) = do-  code <- intLoadCode (MOVSxL II16) addr-  return (Any II32 code)---- catch simple cases of zero- or sign-extended load-getRegister' _ is32Bit (CmmMachOp (MO_UU_Conv W8 W64) [CmmLoad addr _ _])- | not is32Bit = do-  code <- intLoadCode (MOVZxL II8) addr-  return (Any II64 code)--getRegister' _ is32Bit (CmmMachOp (MO_SS_Conv W8 W64) [CmmLoad addr _ _])- | not is32Bit = do-  code <- intLoadCode (MOVSxL II8) addr-  return (Any II64 code)--getRegister' _ is32Bit (CmmMachOp (MO_UU_Conv W16 W64) [CmmLoad addr _ _])- | not is32Bit = do-  code <- intLoadCode (MOVZxL II16) addr-  return (Any II64 code)--getRegister' _ is32Bit (CmmMachOp (MO_SS_Conv W16 W64) [CmmLoad addr _ _])- | not is32Bit = do-  code <- intLoadCode (MOVSxL II16) addr-  return (Any II64 code)--getRegister' _ is32Bit (CmmMachOp (MO_UU_Conv W32 W64) [CmmLoad addr _ _])- | not is32Bit = do-  code <- intLoadCode (MOV II32) addr -- 32-bit loads zero-extend-  return (Any II64 code)--getRegister' _ is32Bit (CmmMachOp (MO_SS_Conv W32 W64) [CmmLoad addr _ _])- | not is32Bit = do-  code <- intLoadCode (MOVSxL II32) addr-  return (Any II64 code)--getRegister' _ is32Bit (CmmMachOp (MO_Add W64) [CmmReg (CmmGlobal (GlobalRegUse PicBaseReg _)),-                                     CmmLit displacement])- | not is32Bit =-      return $ Any II64 (\dst -> unitOL $-        LEA II64 (OpAddr (ripRel (litToImm displacement))) (OpReg dst))--getRegister' _ _ (CmmMachOp mop []) =-  pprPanic "getRegister(x86): nullary MachOp" (text $ show mop)--getRegister' platform is32Bit (CmmMachOp mop [x]) = do -- unary MachOps-    avx    <- avxEnabled-    case mop of-      MO_F_Neg w  -> sse2NegCode w x---      MO_S_Neg w -> triv_ucode NEGI (intFormat w)-      MO_Not w   -> triv_ucode NOT  (intFormat w)--      -- Nop conversions-      MO_UU_Conv W32 W8  -> toI8Reg  W32 x-      MO_SS_Conv W32 W8  -> toI8Reg  W32 x-      MO_XX_Conv W32 W8  -> toI8Reg  W32 x-      MO_UU_Conv W16 W8  -> toI8Reg  W16 x-      MO_SS_Conv W16 W8  -> toI8Reg  W16 x-      MO_XX_Conv W16 W8  -> toI8Reg  W16 x-      MO_UU_Conv W32 W16 -> toI16Reg W32 x-      MO_SS_Conv W32 W16 -> toI16Reg W32 x-      MO_XX_Conv W32 W16 -> toI16Reg W32 x--      MO_UU_Conv W64 W32 | not is32Bit -> conversionNop II64 x-      MO_SS_Conv W64 W32 | not is32Bit -> conversionNop II64 x-      MO_XX_Conv W64 W32 | not is32Bit -> conversionNop II64 x-      MO_UU_Conv W64 W16 | not is32Bit -> toI16Reg W64 x-      MO_SS_Conv W64 W16 | not is32Bit -> toI16Reg W64 x-      MO_XX_Conv W64 W16 | not is32Bit -> toI16Reg W64 x-      MO_UU_Conv W64 W8  | not is32Bit -> toI8Reg  W64 x-      MO_SS_Conv W64 W8  | not is32Bit -> toI8Reg  W64 x-      MO_XX_Conv W64 W8  | not is32Bit -> toI8Reg  W64 x--      MO_UU_Conv rep1 rep2 | rep1 == rep2 -> conversionNop (intFormat rep1) x-      MO_SS_Conv rep1 rep2 | rep1 == rep2 -> conversionNop (intFormat rep1) x-      MO_XX_Conv rep1 rep2 | rep1 == rep2 -> conversionNop (intFormat rep1) x--      MO_FW_Bitcast W32 -> bitcast FF32 II32 x-      MO_WF_Bitcast W32 -> bitcast II32 FF32 x-      MO_FW_Bitcast W64 -> bitcast FF64 II64 x-      MO_WF_Bitcast W64 -> bitcast II64 FF64 x-      MO_WF_Bitcast {}  -> incorrectOperands-      MO_FW_Bitcast {}  -> incorrectOperands--      -- widenings-      MO_UU_Conv W8  W32 -> integerExtend W8  W32 MOVZxL x-      MO_UU_Conv W16 W32 -> integerExtend W16 W32 MOVZxL x-      MO_UU_Conv W8  W16 -> integerExtend W8  W16 MOVZxL x--      MO_SS_Conv W8  W32 -> integerExtend W8  W32 MOVSxL x-      MO_SS_Conv W16 W32 -> integerExtend W16 W32 MOVSxL x-      MO_SS_Conv W8  W16 -> integerExtend W8  W16 MOVSxL x--      -- We don't care about the upper bits for MO_XX_Conv, so MOV is enough. However, on 32-bit we-      -- have 8-bit registers only for a few registers (as opposed to x86-64 where every register-      -- has 8-bit version). So for 32-bit code, we'll just zero-extend.-      MO_XX_Conv W8  W32-          | is32Bit   -> integerExtend W8 W32 MOVZxL x-          | otherwise -> integerExtend W8 W32 MOV x-      MO_XX_Conv W8  W16-          | is32Bit   -> integerExtend W8 W16 MOVZxL x-          | otherwise -> integerExtend W8 W16 MOV x-      MO_XX_Conv W16 W32 -> integerExtend W16 W32 MOV x--      MO_UU_Conv W8  W64 | not is32Bit -> integerExtend W8  W64 MOVZxL x-      MO_UU_Conv W16 W64 | not is32Bit -> integerExtend W16 W64 MOVZxL x-      MO_UU_Conv W32 W64 | not is32Bit -> integerExtend W32 W64 MOVZxL x-      MO_SS_Conv W8  W64 | not is32Bit -> integerExtend W8  W64 MOVSxL x-      MO_SS_Conv W16 W64 | not is32Bit -> integerExtend W16 W64 MOVSxL x-      MO_SS_Conv W32 W64 | not is32Bit -> integerExtend W32 W64 MOVSxL x-      -- For 32-to-64 bit zero extension, amd64 uses an ordinary movl.-      -- However, we don't want the register allocator to throw it-      -- away as an unnecessary reg-to-reg move, so we keep it in-      -- the form of a movzl and print it as a movl later.-      -- This doesn't apply to MO_XX_Conv since in this case we don't care about-      -- the upper bits. So we can just use MOV.-      MO_XX_Conv W8  W64 | not is32Bit -> integerExtend W8  W64 MOV x-      MO_XX_Conv W16 W64 | not is32Bit -> integerExtend W16 W64 MOV x-      MO_XX_Conv W32 W64 | not is32Bit -> integerExtend W32 W64 MOV x--      MO_FF_Conv W32 W64 -> coerceFP2FP W64 x-      MO_FF_Conv W64 W32 -> coerceFP2FP W32 x--      MO_FF_Conv from to -> invalidConversion from to-      MO_UU_Conv from to -> invalidConversion from to-      MO_SS_Conv from to -> invalidConversion from to-      MO_XX_Conv from to -> invalidConversion from to--      MO_FS_Truncate from to -> coerceFP2Int from to x-      MO_SF_Round    from to -> coerceInt2FP from to x--      MO_VF_Neg l w  | avx       -> vector_float_negate_avx l w x-                     | otherwise -> vector_float_negate_sse l w x-      -- SIMD NCG TODO: add integer negation-      MO_VS_Neg {} -> needLlvm mop--      MO_VF_Broadcast l w-        | avx-        -> vector_float_broadcast_avx l w x-        | otherwise-        -> vector_float_broadcast_sse l w x-      MO_V_Broadcast l w-        -> vector_int_broadcast l w x--      -- Binary MachOps-      MO_Add {}    -> incorrectOperands-      MO_Sub {}    -> incorrectOperands-      MO_Eq {}     -> incorrectOperands-      MO_Ne {}     -> incorrectOperands-      MO_Mul {}    -> incorrectOperands-      MO_S_MulMayOflo {} -> incorrectOperands-      MO_S_Quot {} -> incorrectOperands-      MO_S_Rem {}  -> incorrectOperands-      MO_U_Quot {} -> incorrectOperands-      MO_U_Rem {}  -> incorrectOperands-      MO_S_Ge {}   -> incorrectOperands-      MO_S_Le {}   -> incorrectOperands-      MO_S_Gt {}   -> incorrectOperands-      MO_S_Lt {}   -> incorrectOperands-      MO_U_Ge {}   -> incorrectOperands-      MO_U_Le {}   -> incorrectOperands-      MO_U_Gt {}   -> incorrectOperands-      MO_U_Lt {}   -> incorrectOperands-      MO_F_Add {}  -> incorrectOperands-      MO_F_Sub {}  -> incorrectOperands-      MO_F_Mul {}  -> incorrectOperands-      MO_F_Quot {} -> incorrectOperands-      MO_F_Eq {}   -> incorrectOperands-      MO_F_Ne {}   -> incorrectOperands-      MO_F_Ge {}   -> incorrectOperands-      MO_F_Le {}   -> incorrectOperands-      MO_F_Gt {}   -> incorrectOperands-      MO_F_Lt {}   -> incorrectOperands-      MO_F_Min {}  -> incorrectOperands-      MO_F_Max {}  -> incorrectOperands-      MO_And {}    -> incorrectOperands-      MO_Or {}     -> incorrectOperands-      MO_Xor {}    -> incorrectOperands-      MO_Shl {}    -> incorrectOperands-      MO_U_Shr {}  -> incorrectOperands-      MO_S_Shr {}  -> incorrectOperands--      MO_V_Extract {}     -> incorrectOperands-      MO_V_Add {}         -> incorrectOperands-      MO_V_Sub {}         -> incorrectOperands-      MO_V_Mul {}         -> incorrectOperands-      MO_VS_Quot {}       -> incorrectOperands-      MO_VS_Rem {}        -> incorrectOperands-      MO_VU_Quot {}       -> incorrectOperands-      MO_VU_Rem {}        -> incorrectOperands-      MO_V_Shuffle {}     -> incorrectOperands-      MO_VF_Shuffle {}    -> incorrectOperands-      MO_VU_Min {}  -> incorrectOperands-      MO_VU_Max {}  -> incorrectOperands-      MO_VS_Min {}  -> incorrectOperands-      MO_VS_Max {}  -> incorrectOperands-      MO_VF_Min {}  -> incorrectOperands-      MO_VF_Max {}  -> incorrectOperands--      MO_VF_Extract {}    -> incorrectOperands-      MO_VF_Add {}        -> incorrectOperands-      MO_VF_Sub {}        -> incorrectOperands-      MO_VF_Mul {}        -> incorrectOperands-      MO_VF_Quot {}       -> incorrectOperands--      -- Ternary MachOps-      MO_FMA {}           -> incorrectOperands-      MO_VF_Insert {}     -> incorrectOperands-      MO_V_Insert {}      -> incorrectOperands--      --_other -> pprPanic "getRegister" (pprMachOp mop)-   where-        triv_ucode :: (Format -> Operand -> Instr) -> Format -> NatM Register-        triv_ucode instr format = trivialUCode format (instr format) x--        -- signed or unsigned extension.-        integerExtend :: Width -> Width-                      -> (Format -> Operand -> Operand -> Instr)-                      -> CmmExpr -> NatM Register-        integerExtend from to instr expr = do-            (reg,e_code) <- if from == W8 then getByteReg expr-                                          else getSomeReg expr-            let-                code dst =-                  e_code `snocOL`-                  instr (intFormat from) (OpReg reg) (OpReg dst)-            return (Any (intFormat to) code)--        bitcast :: Format -> Format -> CmmExpr -> NatM Register-        bitcast fmt rfmt expr =-          do (src, e_code) <- getSomeReg expr-             let code = \dst -> e_code `snocOL` (MOVD fmt rfmt (OpReg src) (OpReg dst))-             return (Any rfmt code)--        toI8Reg :: Width -> CmmExpr -> NatM Register-        toI8Reg new_rep expr-            = do codefn <- getAnyReg expr-                 return (Any (intFormat new_rep) codefn)-                -- HACK: use getAnyReg to get a byte-addressable register.-                -- If the source was a Fixed register, this will add the-                -- mov instruction to put it into the desired destination.-                -- We're assuming that the destination won't be a fixed-                -- non-byte-addressable register; it won't be, because all-                -- fixed registers are word-sized.--        toI16Reg = toI8Reg -- for now--        conversionNop :: Format -> CmmExpr -> NatM Register-        conversionNop new_format expr-            = do e_code <- getRegister' platform is32Bit expr-                 return (swizzleRegisterRep e_code new_format)--        vector_float_negate_avx :: Length -> Width -> CmmExpr -> NatM Register-        vector_float_negate_avx l w expr = do-          let fmt :: Format-              mask :: CmmLit-              (fmt, mask) = case w of-                       W32 -> (VecFormat l FmtFloat , CmmInt (bit 31) w) -- TODO: these should be negative 0 floating point literals,-                       W64 -> (VecFormat l FmtDouble, CmmInt (bit 63) w) -- but we don't currently have those in Cmm.-                       _ -> panic "AVX floating-point negation: elements must be FF32 or FF64"-          (maskReg, maskCode) <- getSomeReg (CmmLit $ CmmVec $ replicate l mask)-          (reg, exp) <- getSomeReg expr-          let code dst = maskCode `appOL`-                         exp `snocOL`-                         (VMOVU fmt (OpReg reg) (OpReg dst)) `snocOL`-                         (VXOR fmt (OpReg maskReg) dst dst)-          return (Any fmt code)--        vector_float_negate_sse :: Length -> Width -> CmmExpr -> NatM Register-        vector_float_negate_sse l w expr = do-          let fmt :: Format-              mask :: CmmLit-              (fmt, mask) = case w of-                       W32 -> (VecFormat l FmtFloat , CmmInt (bit 31) w) -- Same comment as for vector_float_negate_avx,-                       W64 -> (VecFormat l FmtDouble, CmmInt (bit 63) w) -- these should be -0.0 CmmFloat values.-                       _ -> panic "SSE floating-point negation: elements must be FF32 or FF64"-          (maskReg, maskCode) <- getSomeReg (CmmLit $ CmmVec $ replicate l mask)-          (reg, exp) <- getSomeReg expr-          let code dst = maskCode `appOL`-                         exp `snocOL`-                         (MOVU fmt (OpReg reg) (OpReg dst)) `snocOL`-                         (XOR  fmt (OpReg maskReg) (OpReg dst))-          return (Any fmt code)--        -------------------------        -- TODO: we could use VBROADCASTSS/SD when AVX2 is available.-        vector_float_broadcast_avx :: Length-                                   -> Width-                                   -> CmmExpr-                                   -> NatM Register-        vector_float_broadcast_avx len w expr = do-          (dst, exp) <- getSomeReg expr-          let fmt = VecFormat len (floatScalarFormat w)-              code = VSHUF fmt (ImmInt 0) (OpReg dst) dst dst-          return $ Fixed fmt dst (exp `snocOL` code)--        vector_float_broadcast_sse :: Length-                                   -> Width-                                   -> CmmExpr-                                   -> NatM Register-        vector_float_broadcast_sse len w expr = do-          (dst, exp) <- getSomeReg expr-          let fmt = VecFormat len (floatScalarFormat w)-              code = SHUF fmt (ImmInt 0) (OpReg dst) dst-          return $ Fixed fmt dst (exp `snocOL` code)--        vector_int_broadcast :: Length-                             -> Width-                             -> CmmExpr-                             -> NatM Register-        vector_int_broadcast len W64 expr = do-          (reg, exp) <- getNonClobberedReg expr-          let fmt = VecFormat len FmtInt64-          return $ Any fmt (\dst -> exp `snocOL`-                                    (MOVD II64 fmt (OpReg reg) (OpReg dst)) `snocOL`-                                    (PUNPCKLQDQ fmt (OpReg dst) dst)-                                    )-        vector_int_broadcast len W32 expr = do-          (reg, exp) <- getNonClobberedReg expr-          let fmt = VecFormat len FmtInt32-          return $ Any fmt (\dst -> exp `snocOL`-                                    (MOVD II32 fmt (OpReg reg) (OpReg dst)) `snocOL`-                                    (PSHUFD fmt (ImmInt 0x00) (OpReg dst) dst)-                                    )-        vector_int_broadcast _ _ _ =-          sorry "Unsupported Integer vector broadcast operation; please use -fllvm."---getRegister' platform is32Bit (CmmMachOp mop [x, y]) = do -- dyadic MachOps-  avx <- avxEnabled-  case mop of-      MO_F_Eq _ -> condFltReg is32Bit EQQ x y-      MO_F_Ne _ -> condFltReg is32Bit NE  x y-      MO_F_Gt _ -> condFltReg is32Bit GTT x y-      MO_F_Ge _ -> condFltReg is32Bit GE  x y-      -- Invert comparison condition and swap operands-      -- See Note [SSE Parity Checks]-      MO_F_Lt _ -> condFltReg is32Bit GTT  y x-      MO_F_Le _ -> condFltReg is32Bit GE   y x--      MO_Eq _   -> condIntReg EQQ x y-      MO_Ne _   -> condIntReg NE  x y--      MO_S_Gt _ -> condIntReg GTT x y-      MO_S_Ge _ -> condIntReg GE  x y-      MO_S_Lt _ -> condIntReg LTT x y-      MO_S_Le _ -> condIntReg LE  x y--      MO_U_Gt _ -> condIntReg GU  x y-      MO_U_Ge _ -> condIntReg GEU x y-      MO_U_Lt _ -> condIntReg LU  x y-      MO_U_Le _ -> condIntReg LEU x y--      MO_F_Add  w -> trivialFCode_sse2 w ADD  x y-      MO_F_Sub  w -> trivialFCode_sse2 w SUB  x y-      MO_F_Quot w -> trivialFCode_sse2 w FDIV x y-      MO_F_Mul  w -> trivialFCode_sse2 w MUL  x y-      MO_F_Min  w -> trivialFCode_sse2 w (MINMAX Min FloatMinMax) x y-      MO_F_Max  w -> trivialFCode_sse2 w (MINMAX Max FloatMinMax) x y--      MO_Add rep -> add_code rep x y-      MO_Sub rep -> sub_code rep x y--      MO_S_Quot rep -> div_code rep True  True  x y-      MO_S_Rem  rep -> div_code rep True  False x y-      MO_U_Quot rep -> div_code rep False True  x y-      MO_U_Rem  rep -> div_code rep False False x y--      MO_S_MulMayOflo rep -> imulMayOflo rep x y--      MO_Mul W8  -> imulW8 x y-      MO_Mul rep -> triv_op rep IMUL-      MO_And rep -> triv_op rep AND-      MO_Or  rep -> triv_op rep OR-      MO_Xor rep -> triv_op rep XOR--        {- Shift ops on x86s have constraints on their source, it-           either has to be Imm, CL or 1-            => trivialCode is not restrictive enough (sigh.)-        -}-      MO_Shl rep   -> shift_code rep SHL x y {-False-}-      MO_U_Shr rep -> shift_code rep SHR x y {-False-}-      MO_S_Shr rep -> shift_code rep SAR x y {-False-}--      MO_VF_Shuffle l w is-        | l * widthInBits w == 128-        -> if-            | avx-            -> vector_shuffle_float l w x y is-            | otherwise-            -> sorry "Please enable the -mavx flag"-        | otherwise-        -> sorry "Please use -fllvm for wide shuffle instructions"--      MO_VF_Extract l W32   | avx       -> vector_float_extract l W32 x y-                            | otherwise -> vector_float_extract_sse l W32 x y-      MO_VF_Extract l W64               -> vector_float_extract l W64 x y-      MO_VF_Extract {} -> incorrectOperands--      MO_V_Extract l W64                -> vector_int_extract_sse l W64 x y-      -- SIMD NCG TODO: W32, W16, W8-      MO_V_Extract {} -> needLlvm mop--      MO_VF_Add l w         | avx       -> vector_float_op_avx VA_Add l w x y-                            | otherwise -> vector_float_op_sse VA_Add l w x y--      MO_VF_Sub l w         | avx       -> vector_float_op_avx VA_Sub l w x y-                            | otherwise -> vector_float_op_sse VA_Sub l w x y--      MO_VF_Mul l w         | avx       -> vector_float_op_avx VA_Mul l w x y-                            | otherwise -> vector_float_op_sse VA_Mul l w x y--      MO_VF_Quot l w        | avx       -> vector_float_op_avx VA_Div l w x y-                            | otherwise -> vector_float_op_sse VA_Div l w x y--      MO_VF_Min l w         | avx       -> vector_float_op_avx VA_Min l w x y-                            | otherwise -> vector_float_op_sse VA_Min l w x y--      MO_VF_Max l w         | avx       -> vector_float_op_avx VA_Max l w x y-                            | otherwise -> vector_float_op_sse VA_Max l w x y--      -- SIMD NCG TODO: integer vector operations-      MO_V_Shuffle {} -> needLlvm mop-      MO_V_Add {} -> needLlvm mop-      MO_V_Sub {} -> needLlvm mop-      MO_V_Mul {} -> needLlvm mop-      MO_VS_Quot {} -> needLlvm mop-      MO_VS_Rem {} -> needLlvm mop-      MO_VU_Quot {} -> needLlvm mop-      MO_VU_Rem {} -> needLlvm mop--      MO_VU_Min {} -> needLlvm mop-      MO_VU_Max {} -> needLlvm mop-      MO_VS_Min {} -> needLlvm mop-      MO_VS_Max {} -> needLlvm mop--      -- Unary MachOps-      MO_S_Neg {} -> incorrectOperands-      MO_F_Neg {} -> incorrectOperands-      MO_Not {} -> incorrectOperands-      MO_SF_Round {} -> incorrectOperands-      MO_FS_Truncate {} -> incorrectOperands-      MO_SS_Conv {} -> incorrectOperands-      MO_XX_Conv {} -> incorrectOperands-      MO_FF_Conv {} -> incorrectOperands-      MO_UU_Conv {} -> incorrectOperands-      MO_WF_Bitcast {} -> incorrectOperands-      MO_FW_Bitcast  {} -> incorrectOperands-      MO_RelaxedRead {} -> incorrectOperands-      MO_AlignmentCheck {} -> incorrectOperands-      MO_VS_Neg {} -> incorrectOperands-      MO_VF_Neg {} -> incorrectOperands-      MO_V_Broadcast {} -> incorrectOperands-      MO_VF_Broadcast {} -> incorrectOperands--      -- Ternary MachOps-      MO_FMA {} -> incorrectOperands-      MO_V_Insert {} -> incorrectOperands-      MO_VF_Insert {} -> incorrectOperands--  where-    ---------------------    triv_op width instr = trivialCode width op (Just op) x y-                        where op   = instr (intFormat width)--    -- Special case for IMUL for bytes, since the result of IMULB will be in-    -- %ax, the split to %dx/%edx/%rdx and %ax/%eax/%rax happens only for wider-    -- values.-    imulW8 :: CmmExpr -> CmmExpr -> NatM Register-    imulW8 arg_a arg_b = do-        (a_reg, a_code) <- getNonClobberedReg arg_a-        b_code <- getAnyReg arg_b--        let code = a_code `appOL` b_code eax `appOL`-                   toOL [ IMUL2 format (OpReg a_reg) ]-            format = intFormat W8--        return (Fixed format eax code)--    imulMayOflo :: Width -> CmmExpr -> CmmExpr -> NatM Register-    imulMayOflo W8 a b = do-         -- The general case (W16, W32, W64) doesn't work for W8 as its-         -- multiplication doesn't use two registers.-         ---         -- The plan is:-         -- 1. truncate and sign-extend a and b to 8bit width-         -- 2. multiply a' = a * b in 32bit width-         -- 3. copy and sign-extend 8bit from a' to c-         -- 4. compare a' and c: they are equal if there was no overflow-         (a_reg, a_code) <- getNonClobberedReg a-         (b_reg, b_code) <- getNonClobberedReg b-         let-             code = a_code `appOL` b_code `appOL`-                        toOL [-                           MOVSxL II8 (OpReg a_reg) (OpReg a_reg),-                           MOVSxL II8 (OpReg b_reg) (OpReg b_reg),-                           IMUL II32 (OpReg b_reg) (OpReg a_reg),-                           MOVSxL II8 (OpReg a_reg) (OpReg eax),-                           CMP II16 (OpReg a_reg) (OpReg eax),-                           SETCC NE (OpReg eax)-                        ]-         return (Fixed II8 eax code)-    imulMayOflo rep a b = do-         (a_reg, a_code) <- getNonClobberedReg a-         b_code <- getAnyReg b-         let-             shift_amt  = case rep of-                           W16 -> 15-                           W32 -> 31-                           W64 -> 63-                           w -> panic ("shift_amt: " ++ show w)--             format = intFormat rep-             code = a_code `appOL` b_code eax `appOL`-                        toOL [-                           IMUL2 format (OpReg a_reg),   -- result in %edx:%eax-                           SAR format (OpImm (ImmInt shift_amt)) (OpReg eax),-                                -- sign extend lower part-                           SUB format (OpReg edx) (OpReg eax)-                                -- compare against upper-                           -- eax==0 if high part == sign extended low part-                        ]-         return (Fixed format eax code)--    ---------------------    shift_code :: Width-               -> (Format -> Operand -> Operand -> Instr)-               -> CmmExpr-               -> CmmExpr-               -> NatM Register--    {- Case1: shift length as immediate -}-    shift_code width instr x (CmmLit lit)-      -- Handle the case of a shift larger than the width of the shifted value.-      -- This is necessary since x86 applies a mask of 0x1f to the shift-      -- amount, meaning that, e.g., `shr 47, $eax` will actually shift by-      -- `47 & 0x1f == 15`. See #20626.-      | CmmInt n _ <- lit-      , n >= fromIntegral (widthInBits width)-      = getRegister $ CmmLit $ CmmInt 0 width--      | otherwise = do-          x_code <- getAnyReg x-          let-               format = intFormat width-               code dst-                  = x_code dst `snocOL`-                    instr format (OpImm (litToImm lit)) (OpReg dst)-          return (Any format code)--    {- Case2: shift length is complex (non-immediate)-      * y must go in %ecx.-      * we cannot do y first *and* put its result in %ecx, because-        %ecx might be clobbered by x.-      * if we do y second, then x cannot be-        in a clobbered reg.  Also, we cannot clobber x's reg-        with the instruction itself.-      * so we can either:-        - do y first, put its result in a fresh tmp, then copy it to %ecx later-        - do y second and put its result into %ecx.  x gets placed in a fresh-          tmp.  This is likely to be better, because the reg alloc can-          eliminate this reg->reg move here (it won't eliminate the other one,-          because the move is into the fixed %ecx).-      * in the case of C calls the use of ecx here can interfere with arguments.-        We avoid this with the hack described in Note [Evaluate C-call-        arguments before placing in destination registers]-    -}-    shift_code width instr x y{-amount-} = do-        x_code <- getAnyReg x-        let format = intFormat width-        tmp <- getNewRegNat format-        y_code <- getAnyReg y-        let-           code = x_code tmp `appOL`-                  y_code ecx `snocOL`-                  instr format (OpReg ecx) (OpReg tmp)-        return (Fixed format tmp code)--    ---------------------    add_code :: Width -> CmmExpr -> CmmExpr -> NatM Register-    add_code rep x (CmmLit (CmmInt y _))-        | is32BitInteger y-        , rep /= W8 -- LEA doesn't support byte size (#18614)-        = add_int rep x y-    add_code rep x y = trivialCode rep (ADD format) (Just (ADD format)) x y-      where format = intFormat rep-    -- TODO: There are other interesting patterns we want to replace-    --     with a LEA, e.g. `(x + offset) + (y << shift)`.--    ---------------------    sub_code :: Width -> CmmExpr -> CmmExpr -> NatM Register-    sub_code rep x (CmmLit (CmmInt y _))-        | is32BitInteger (-y)-        , rep /= W8 -- LEA doesn't support byte size (#18614)-        = add_int rep x (-y)-    sub_code rep x y = trivialCode rep (SUB (intFormat rep)) Nothing x y--    -- our three-operand add instruction:-    add_int width x y = do-        (x_reg, x_code) <- getSomeReg x-        let-            format = intFormat width-            imm = ImmInt (fromInteger y)-            code dst-               = x_code `snocOL`-                 LEA format-                        (OpAddr (AddrBaseIndex (EABaseReg x_reg) EAIndexNone imm))-                        (OpReg dst)-        ---        return (Any format code)--    ------------------------    -- See Note [DIV/IDIV for bytes]-    div_code W8 signed quotient x y = do-        let widen | signed    = MO_SS_Conv W8 W16-                  | otherwise = MO_UU_Conv W8 W16-        div_code-            W16-            signed-            quotient-            (CmmMachOp widen [x])-            (CmmMachOp widen [y])--    div_code width signed quotient x y = do-           (y_op, y_code) <- getRegOrMem y -- cannot be clobbered-           x_code <- getAnyReg x-           let-             format = intFormat width-             widen | signed    = CLTD format-                   | otherwise = XOR format (OpReg edx) (OpReg edx)--             instr | signed    = IDIV-                   | otherwise = DIV--             code = y_code `appOL`-                    x_code eax `appOL`-                    toOL [widen, instr format y_op]--             result | quotient  = eax-                    | otherwise = edx--           return (Fixed format result code)--    ------------------------    -- Vector operations----    vector_float_op_avx :: VectorArithInstns-                        -> Length-                        -> Width-                        -> CmmExpr-                        -> CmmExpr-                        -> NatM Register-    vector_float_op_avx op l w expr1 expr2 = do-      (reg1, exp1) <- getSomeReg expr1-      (reg2, exp2) <- getSomeReg expr2-      let format   = case w of-                       W32 -> VecFormat l FmtFloat-                       W64 -> VecFormat l FmtDouble-                       _ -> pprPanic "Floating-point AVX vector operation not supported at this width"-                             (text "width:" <+> ppr w)-          code dst = case op of-            VA_Add -> arithInstr VADD-            VA_Sub -> arithInstr VSUB-            VA_Mul -> arithInstr VMUL-            VA_Div -> arithInstr VDIV-            VA_Min -> arithInstr (VMINMAX Min FloatMinMax)-            VA_Max -> arithInstr (VMINMAX Max FloatMinMax)-            where-              -- opcode src2 src1 dst <==> dst = src1 `opcode` src2-              arithInstr instr = exp1 `appOL` exp2 `snocOL`-                                 (instr format (OpReg reg2) reg1 dst)-      return (Any format code)--    vector_float_op_sse :: VectorArithInstns-                        -> Length-                        -> Width-                        -> CmmExpr-                        -> CmmExpr-                        -> NatM Register-    vector_float_op_sse op l w expr1 expr2 = do-      -- This function is similar to genTrivialCode, but re-using it would require-      -- handling alignment correctly: SSE vector instructions typically require 16-byte-      -- alignment for their memory operand (this restriction is relaxed with VEX-encoded-      -- instructions).-      -- For now, we always load the value into a register and avoid the alignment issue.-      exp1_code <- getAnyReg expr1-      (reg2, exp2_code) <- getSomeReg expr2-      let format   = case w of-                       W32 -> VecFormat l FmtFloat-                       W64 -> VecFormat l FmtDouble-                       _ -> pprPanic "Floating-point SSE vector operation not supported at this width"-                             (text "width:" <+> ppr w)-      tmp <- getNewRegNat format-      let code dst = case op of-            VA_Add -> arithInstr ADD-            VA_Sub -> arithInstr SUB-            VA_Mul -> arithInstr MUL-            VA_Div -> arithInstr FDIV-            VA_Min -> arithInstr (MINMAX Min FloatMinMax)-            VA_Max -> arithInstr (MINMAX Max FloatMinMax)-            where-              -- opcode src2 src1 <==> src1 = src1 `opcode` src2-              arithInstr instr-                | dst == reg2 = exp2_code `snocOL`-                                (MOVU format (OpReg reg2) (OpReg tmp)) `appOL`-                                exp1_code dst `snocOL`-                                instr format (OpReg tmp) (OpReg dst)-                | otherwise = exp2_code `appOL`-                              exp1_code dst `snocOL`-                              instr format (OpReg reg2) (OpReg dst)-      return (Any format code)-    ---------------------    vector_float_extract :: Length-                         -> Width-                         -> CmmExpr-                         -> CmmExpr-                         -> NatM Register-    vector_float_extract l W32 expr (CmmLit lit) = do-      (r, exp) <- getSomeReg expr-      let format   = VecFormat l FmtFloat-          imm      = litToImm lit-          code dst-            = case lit of-                CmmInt 0 _ -> exp `snocOL` (MOV FF32 (OpReg r) (OpReg dst))-                CmmInt _ _ -> exp `snocOL` (VPSHUFD format imm (OpReg r) dst)-                _          -> pprPanic "Unsupported AVX floating-point vector extract offset" (ppr lit)-      return (Any FF32 code)-    vector_float_extract l W64 expr (CmmLit lit) = do-      (r, exp) <- getSomeReg expr-      let format   = VecFormat l FmtDouble-          code dst-            = case lit of-                CmmInt 0 _ -> exp `snocOL`-                              (MOV FF64 (OpReg r) (OpReg dst))-                CmmInt 1 _ -> exp `snocOL`-                              (MOVHLPS format r dst)-                _          -> pprPanic "Unsupported AVX floating-point vector extract offset" (ppr lit)-      return (Any FF64 code)-    vector_float_extract _ w c e =-      pprPanic "Unsupported AVX floating-point vector extract" (pdoc platform c $$ pdoc platform e $$ ppr w)-    -------------------------    vector_float_extract_sse :: Length-                             -> Width-                             -> CmmExpr-                             -> CmmExpr-                             -> NatM Register-    vector_float_extract_sse l W32 expr (CmmLit lit)-      = do-      (r,exp) <- getSomeReg expr-      let format   = VecFormat l FmtFloat-          imm      = litToImm lit-          code dst-            = case lit of-                CmmInt 0 _ -> exp `snocOL` (MOVU format (OpReg r) (OpReg dst))-                CmmInt _ _ -> exp `snocOL` (PSHUFD format imm (OpReg r) dst)-                _          -> pprPanic "Unsupported SSE floating-point vector extract offset" (ppr lit)-      return (Any FF32 code)-    vector_float_extract_sse _ w c e-      = pprPanic "Unsupported SSE floating-point vector extract" (pdoc platform c $$ pdoc platform e $$ ppr w)-    -------------------------    vector_int_extract_sse :: Length-                           -> Width-                           -> CmmExpr-                           -> CmmExpr-                           -> NatM Register-    vector_int_extract_sse l@2 W64 expr (CmmLit lit)-      = do-      (r, exp) <- getSomeReg expr-      let fmt = VecFormat l FmtInt64-      tmp <- getNewRegNat fmt-      let code dst =-            case lit of-              CmmInt 0 _ -> exp `snocOL`-                            (MOVD fmt II64 (OpReg r) (OpReg dst))-              CmmInt 1 _ -> exp `snocOL`-                            (MOVHLPS fmt r tmp) `snocOL`-                            (MOVD fmt II64 (OpReg tmp) (OpReg dst))-              _          -> panic "Error in offset while unpacking"-      return (Any II64 code)-    vector_int_extract_sse _ w c e-      = pprPanic "Unsupported SSE floating-point vector extract" (pdoc platform c $$ pdoc platform e $$ ppr w)--    vector_shuffle_float :: Length -> Width -> CmmExpr -> CmmExpr -> [Int] -> NatM Register-    vector_shuffle_float l w v1 v2 is = do-      (r1, exp1) <- getSomeReg v1-      (r2, exp2) <- getSomeReg v2-      let fmt = VecFormat l (if w == W32 then FmtFloat else FmtDouble)-          code dst-            = exp1 `appOL` (exp2 `appOL` shuffleInstructions fmt r1 r2 is dst)-      return (Any fmt code)--    shuffleInstructions :: Format -> Reg -> Reg -> [Int] -> Reg -> OrdList Instr-    shuffleInstructions fmt v1 v2 is dst =-      case fmt of-        VecFormat 2 FmtDouble ->-          case is of-            [i1, i2] -> case (i1, i2) of-              (0,0) -> unitOL (VSHUF fmt (ImmInt 0b00) (OpReg v1) v1 dst)-              (1,1) -> unitOL (VSHUF fmt (ImmInt 0b11) (OpReg v1) v1 dst)-              (2,2) -> unitOL (VSHUF fmt (ImmInt 0b00) (OpReg v2) v2 dst)-              (3,3) -> unitOL (VSHUF fmt (ImmInt 0b11) (OpReg v2) v2 dst)-              (0,1) -> unitOL (VMOVU fmt (OpReg v1) (OpReg dst))-              (2,3) -> unitOL (VMOVU fmt (OpReg v2) (OpReg dst))-              (1,0) -> unitOL (VSHUF fmt (ImmInt 0b01) (OpReg v1) v1 dst)-              (3,2) -> unitOL (VSHUF fmt (ImmInt 0b01) (OpReg v2) v2 dst)-              (0,2) -> unitOL (VSHUF fmt (ImmInt 0b00) (OpReg v2) v1 dst)-              (2,0) -> unitOL (VSHUF fmt (ImmInt 0b00) (OpReg v1) v2 dst)-              (0,3) -> unitOL (VSHUF fmt (ImmInt 0b10) (OpReg v2) v1 dst)-              (3,0) -> unitOL (VSHUF fmt (ImmInt 0b01) (OpReg v1) v2 dst)-              (1,2) -> unitOL (VSHUF fmt (ImmInt 0b01) (OpReg v2) v1 dst)-              (2,1) -> unitOL (VSHUF fmt (ImmInt 0b10) (OpReg v1) v2 dst)-              (1,3) -> unitOL (VSHUF fmt (ImmInt 0b11) (OpReg v2) v1 dst)-              (3,1) -> unitOL (VSHUF fmt (ImmInt 0b11) (OpReg v1) v2 dst)-              _ -> pprPanic "vector shuffle: indices out of bounds 0 <= i <= 3" (ppr is)-            _ -> pprPanic "vector shuffle: wrong number of indices (expected 2)" (ppr is)-        VecFormat 4 FmtFloat-          -- indices 0 <= i <= 7-          | all ( (>= 0) <&&> (<= 7) ) is ->-          case is of-            [i1, i2, i3, i4]-              | all ( <= 3 ) is-              , let imm = i1 + i2 `shiftL` 2 + i3 `shiftL` 4 + i4 `shiftL` 6-              -> unitOL (VSHUF fmt (ImmInt imm) (OpReg v1) v1 dst)-              | all ( >= 4 ) is-              , let [j1, j2, j3, j4] = map ( subtract 4 ) is-                    imm = j1 + j2 `shiftL` 2 + j3 `shiftL` 4 + j4 `shiftL` 6-              -> unitOL (VSHUF fmt (ImmInt imm) (OpReg v2) v2 dst)-              | i1 <= 3, i2 <= 3-              , i3 >= 4, i4 >= 4-              , let imm = i1 + i2 `shiftL` 2 + (i3 - 4) `shiftL` 4 + (i4 - 4) `shiftL` 6-              -> unitOL (VSHUF fmt (ImmInt imm) (OpReg v2) v1 dst)-              | i1 >= 4, i2 >= 4-              , i3 <= 3, i4 <= 3-              , let imm = (i1 - 4) + (i2 - 4) `shiftL` 2 + i3 `shiftL` 4 + i4 `shiftL` 6-              -> unitOL (VSHUF fmt (ImmInt imm) (OpReg v1) v2 dst)-              | otherwise-              ->-              -- Fall-back code with 4 INSERTPS operations.-              -- SIMD NCG TODO: handle more cases with better lowering.-              let -- bits: ss_dd_zzzz-                  -- ss: pick source location-                  -- dd: pick destination location-                  -- zzzz: pick locations to be zeroed-                  insertImm src dst = shiftL   ( src `mod` 4 ) 6-                                    .|. shiftL dst 4-                  vec src = if src >= 4 then v2 else v1-              in unitOL-                (INSERTPS fmt (ImmInt $ insertImm i1 0 .|. 0b1110) (OpReg $ vec i1) dst)-                `snocOL`-                (INSERTPS fmt (ImmInt $ insertImm i2 1) (OpReg $ vec i2) dst)-                `snocOL`-                (INSERTPS fmt (ImmInt $ insertImm i3 2) (OpReg $ vec i3) dst)-                `snocOL`-                (INSERTPS fmt (ImmInt $ insertImm i4 3) (OpReg $ vec i4) dst)-            _ -> pprPanic "vector shuffle: wrong number of indices (expected 4)" (ppr is)-          | otherwise-          -> pprPanic "vector shuffle: indices out of bounds 0 <= i <= 7" (ppr is)-        _ ->-          pprPanic "vector shuffle: unsupported format" (ppr fmt)--getRegister' platform _is32Bit (CmmMachOp mop [x, y, z]) = do -- ternary MachOps-  avx    <- avxEnabled-  sse4_1 <- sse4_1Enabled-  case mop of-      -- Floating point fused multiply-add operations @ ± x*y ± z@-      MO_FMA var l w-        | l * widthInBits w > 256-        -> sorry "Please use -fllvm for wide vector FMA support"-        | otherwise-        -> genFMA3Code l w var x y z--      -- Ternary vector operations-      MO_VF_Insert l W32  | l == 4 -> vector_floatx4_insert_sse sse4_1 x y z-                          | otherwise ->-         sorry $ "FloatX" ++ show l ++ "# insert operations require -fllvm"-           -- SIMD NCG TODO:-           ---           --   - add support for FloatX8, FloatX16.-      MO_VF_Insert l W64  -> vector_double_insert avx l x y z-      MO_V_Insert l W64   -> vector_int_insert_sse l W64 x y z--      _other -> pprPanic "getRegister(x86) - ternary CmmMachOp (1)"-                  (pprMachOp mop)--  where-    -- SIMD NCG TODO:-    ---    --   - add support for FloatX8, FloatX16.-    vector_floatx4_insert_sse :: Bool-                              -> CmmExpr-                              -> CmmExpr-                              -> CmmExpr-                              -> NatM Register-    vector_floatx4_insert_sse sse4_1 vecExpr valExpr (CmmLit (CmmInt offset _))-      | sse4_1 = do-        (r, exp)    <- getNonClobberedReg valExpr-        fn          <- getAnyReg vecExpr-        let fmt      = VecFormat 4 FmtFloat-            imm      = litToImm (CmmInt (offset `shiftL` 4) W32)-            code dst = exp `appOL`-                      (fn dst) `snocOL`-                      (INSERTPS fmt imm (OpReg r) dst)-         in return $ Any fmt code-      | otherwise = do -- SSE <= 3-        (r, exp)    <- getNonClobberedReg valExpr-        fn          <- getAnyReg vecExpr-        let fmt      = VecFormat 4 FmtFloat-        tmp <- getNewRegNat fmt-        let code dst-              = case offset of-                  0 -> exp `appOL`-                      (fn dst) `snocOL`-                      -- The following MOV compiles to MOVSS instruction and merges two vectors-                      (MOV fmt (OpReg r) (OpReg dst))  -- dst <- (r[0],dst[1],dst[2],dst[3])-                  1 -> exp `appOL`-                      (fn dst) `snocOL`-                      (MOVU fmt (OpReg dst) (OpReg tmp)) `snocOL`  -- tmp <- dst-                      (UNPCKL fmt (OpReg r) dst) `snocOL`          -- dst <- (dst[0],r[0],dst[1],r[1])-                      (SHUF fmt (ImmInt 0xe4) (OpReg tmp) dst)     -- dst <- (dst[0],dst[1],tmp[2],tmp[3])-                  2 -> exp `appOL`-                       (fn dst) `snocOL`-                       (MOVU fmt (OpReg dst) (OpReg tmp)) `snocOL`  -- tmp <- dst-                       (MOV fmt (OpReg r) (OpReg tmp)) `snocOL`     -- tmp <- (r[0],tmp[1],tmp[2],tmp[3]) with MOVSS-                       (SHUF fmt (ImmInt 0xc4) (OpReg tmp) dst)     -- dst <- (dst[0],dst[1],tmp[0],tmp[3])-                  3 -> exp `appOL`-                       (fn dst) `snocOL`-                       (MOVU fmt (OpReg dst) (OpReg tmp)) `snocOL`  -- tmp <- dst-                       (MOV fmt (OpReg r) (OpReg tmp)) `snocOL`     -- tmp <- (r[0],tmp[1],tmp[2],tmp[3]) with MOVSS-                       (SHUF fmt (ImmInt 0x24) (OpReg tmp) dst)     -- dst <- (dst[0],dst[1],tmp[2],tmp[0])-                  _ -> panic "MO_VF_Insert FloatX4: unsupported offset"-         in return $ Any fmt code-    vector_floatx4_insert_sse _ _ _ offset-      = pprPanic "Unsupported vector insert operation" $-          vcat-            [ text "FloatX4#"-            , text "offset:" <+> pdoc platform offset ]---    -- SIMD NCG TODO:-    ---    --   - add support for DoubleX4#, DoubleX8#.-    vector_double_insert :: Bool-                         -> Length-                         -> CmmExpr-                         -> CmmExpr-                         -> CmmExpr-                         -> NatM Register-    -- DoubleX2-    vector_double_insert avx len@2 vecExpr valExpr (CmmLit offset)-      = do-        (valReg, valExp) <- getNonClobberedReg valExpr-        (vecReg, vecExp) <- getSomeReg vecExpr -- NB: vector regs never clobbered by instruction-        let movu = if avx then VMOVU else MOVU-            fmt = VecFormat len FmtDouble-            code dst-              = case offset of-                  CmmInt 0 _ -> valExp `appOL`-                                vecExp `snocOL`-                                (movu (VecFormat 2 FmtDouble) (OpReg vecReg) (OpReg dst)) `snocOL`-                                -- The following MOV compiles to MOVSD instruction and merges two vectors-                                (MOV (VecFormat 2 FmtDouble) (OpReg valReg) (OpReg dst))-                  CmmInt 1 _ -> valExp `appOL`-                                vecExp `snocOL`-                                (movu (VecFormat 2 FmtDouble) (OpReg vecReg) (OpReg dst)) `snocOL`-                                (SHUF fmt (ImmInt 0b00) (OpReg valReg) dst)-                  _ -> pprPanic "MO_VF_Insert DoubleX2: unsupported offset" (ppr offset)-         in return $ Any fmt code-    vector_double_insert _ _ _ _ _ =-      sorry "Unsupported floating-point vector insert operation; please use -fllvm"-    -- For DoubleX4: use VSHUFPD.-    -- For DoubleX8: use something like vinsertf64x2 followed by vpblendd?--    -- SIMD NCG TODO:-    ---    --   - only supports Int64X2, add support for everything else:-    --     (Int32X{4,2}, Int16X{8,4,2}, Int8X{16,8,4,2})-    vector_int_insert_sse :: HasCallStack => Length-                          -> Width-                          -> CmmExpr-                          -> CmmExpr-                          -> CmmExpr-                          -> NatM Register-    -- Int64X2-    vector_int_insert_sse len@2 W64 vecExpr valExpr (CmmLit offset)-      = do-        (valReg, valExp) <- getNonClobberedReg valExpr-        (vecReg, vecExp) <- getSomeReg vecExpr -- NB: vector regs never clobbered by instruction-        let fmt = VecFormat len FmtInt64-        tmp <- getNewRegNat fmt-        let code dst-              = case offset of-                  CmmInt 0 _ -> valExp `appOL`-                                vecExp `snocOL`-                                (MOVHLPS fmt vecReg tmp) `snocOL`-                                (MOVD II64 fmt (OpReg valReg) (OpReg dst)) `snocOL`-                                (PUNPCKLQDQ fmt (OpReg tmp) dst)-                  CmmInt 1 _ -> valExp `appOL`-                                vecExp `snocOL`-                                (MOVDQU fmt (OpReg vecReg) (OpReg dst)) `snocOL`-                                (MOVD II64 fmt (OpReg valReg) (OpReg tmp)) `snocOL`-                                (PUNPCKLQDQ fmt (OpReg tmp) dst)-                  _ -> pprPanic "MO_V_Insert Int64X2: unsupported offset" (ppr offset)-         in return $ Any fmt code-    vector_int_insert_sse _ _ _ _ _ =-      sorry "Unsupported integer vector insert operation; please use -fllvm"--getRegister' _ _ (CmmMachOp mop (_:_:_:_:_)) =-  pprPanic "getRegister(x86): MachOp with >= 4 arguments" (text $ show mop)--getRegister' platform is32Bit load@(CmmLoad mem ty _)-  | isVecType ty-  = do-    config <- getConfig-    Amode addr mem_code <- getAmode mem-    let code dst =-          mem_code `snocOL`-            movInstr config format (OpAddr addr) (OpReg dst)-    return (Any format code)-  | isFloatType ty-  = do-    Amode addr mem_code <- getAmode mem-    loadAmode (floatFormat width) addr mem_code--  | is32Bit && not (isWord64 ty)-  = do-    let-      instr = case width of-                W8     -> MOVZxL II8-                  -- We always zero-extend 8-bit loads, if we-                  -- can't think of anything better.  This is because-                  -- we can't guarantee access to an 8-bit variant of every register-                  -- (esi and edi don't have 8-bit variants), so to make things-                  -- simpler we do our 8-bit arithmetic with full 32-bit registers.-                _other -> MOV format-    code <- intLoadCode instr mem-    return (Any format code)--  | not is32Bit-  -- Simpler memory load code on x86_64-  = do-    code <- intLoadCode (MOV format) mem-    return (Any format code)--  | otherwise-  = pprPanic "getRegister(x86) CmmLoad" (pdoc platform load)-  where-    format = cmmTypeFormat ty-    width = typeWidth ty---- Handle symbol references with LEA and %rip-relative addressing.--- See Note [%rip-relative addressing on x86-64].-getRegister' platform is32Bit (CmmLit lit)-  | is_label lit-  , not is32Bit-  = do let format = cmmTypeFormat (cmmLitType platform lit)-           imm = litToImm lit-           op = OpAddr (AddrBaseIndex EABaseRip EAIndexNone imm)-           code dst = unitOL (LEA format op (OpReg dst))-       return (Any format code)-  where-    is_label (CmmLabel {})        = True-    is_label (CmmLabelOff {})     = True-    is_label (CmmLabelDiffOff {}) = True-    is_label _                    = False--getRegister' platform is32Bit (CmmLit lit) = do-  avx <- avxEnabled--  -- NB: it is important that the code produced here (to load a literal into-  -- a register) doesn't clobber any registers other than the destination-  -- register; the code for generating C calls relies on this property.-  ---  -- In particular, we have:-  ---  -- > loadIntoRegMightClobberOtherReg (CmmLit _) = False-  ---  -- which means that we assume that loading a literal into a register-  -- will not clobber any other registers.--  -- TODO: this function mishandles floating-point negative zero,-  -- because -0.0 == 0.0 returns True and because we represent CmmFloat as-  -- Rational, which can't properly represent negative zero.--  if-    -- Zero: use XOR.-    | isZeroLit lit-    -> let code dst-             | isIntFormat fmt-             = let fmt'-                     | is32Bit-                     = fmt-                     | otherwise-                     -- x86_64: 32-bit xor is one byte shorter,-                     -- and zero-extends to 64 bits-                     = case fmt of-                         II64 -> II32-                         _ -> fmt-               in unitOL (XOR fmt' (OpReg dst) (OpReg dst))-             | avx-             = if float_or_floatvec-               then unitOL (VXOR fmt (OpReg dst) dst dst)-               else unitOL (VPXOR fmt dst dst dst)-             | otherwise-             = if float_or_floatvec-               then unitOL (XOR fmt (OpReg dst) (OpReg dst))-               else unitOL (PXOR fmt (OpReg dst) dst)-       in return $ Any fmt code--    -- Constant vector: use broadcast.-    | VecFormat l sFmt <- fmt-    , CmmVec (f:fs) <- lit-    , all (== f) fs-    -> do let w = scalarWidth sFmt-              broadcast = if isFloatScalarFormat sFmt-                          then MO_VF_Broadcast l w-                          else MO_V_Broadcast l w-          valCode <- getAnyReg (CmmMachOp broadcast [CmmLit f])-          return $ Any fmt valCode--    -- Optimisation for loading small literals on x86_64: take advantage-    -- of the automatic zero-extension from 32 to 64 bits, because the 32-bit-    -- instruction forms are shorter.-    | not is32Bit, isWord64 cmmTy, not (isBigLit lit)-    -> let-          imm = litToImm lit-          code dst = unitOL (MOV II32 (OpImm imm) (OpReg dst))-      in-          return (Any II64 code)--    -- Scalar integer: use an immediate.-    | isIntFormat fmt-    -> let imm = litToImm lit-           code dst = unitOL (MOV fmt (OpImm imm) (OpReg dst))-       in return (Any fmt code)--    -- General case: load literal from data address.-    | otherwise-    -> do let w = formatToWidth fmt-          Amode addr addr_code <- memConstant (mkAlignment $ widthInBytes w) lit-          loadAmode fmt addr addr_code--    where-      cmmTy = cmmLitType platform lit-      fmt = cmmTypeFormat cmmTy-      float_or_floatvec = isFloatOrFloatVecFormat fmt-      isZeroLit (CmmInt i _) = i == 0-      isZeroLit (CmmFloat f _) = f == 0 -- TODO: mishandles negative zero-      isZeroLit (CmmVec fs) = all isZeroLit fs-      isZeroLit _ = False--      isBigLit (CmmInt i _) = i < 0 || i > 0xffffffff-      isBigLit _ = False-        -- note1: not the same as (not.is32BitLit), because that checks for-        -- signed literals that fit in 32 bits, but we want unsigned-        -- literals here.-        -- note2: all labels are small, because we're assuming the-        -- small memory model. See Note [%rip-relative addressing on x86-64].--getRegister' platform _ slot@(CmmStackSlot {}) =-  pprPanic "getRegister(x86) CmmStackSlot" (pdoc platform slot)--intLoadCode :: (Operand -> Operand -> Instr) -> CmmExpr-   -> NatM (Reg -> InstrBlock)-intLoadCode instr mem = do-  Amode src mem_code <- getAmode mem-  return (\dst -> mem_code `snocOL` instr (OpAddr src) (OpReg dst))---- Compute an expression into *any* register, adding the appropriate--- move instruction if necessary.-getAnyReg :: HasDebugCallStack => CmmExpr -> NatM (Reg -> InstrBlock)-getAnyReg expr = do-  r <- getRegister expr-  anyReg r--anyReg :: HasDebugCallStack => Register -> NatM (Reg -> InstrBlock)-anyReg (Any _ code)          = return code-anyReg (Fixed rep reg fcode) = do-  config <- getConfig-  return (\dst -> fcode `snocOL` mkRegRegMoveInstr config rep reg dst)---- A bit like getSomeReg, but we want a reg that can be byte-addressed.--- Fixed registers might not be byte-addressable, so we make sure we've--- got a temporary, inserting an extra reg copy if necessary.-getByteReg :: HasDebugCallStack => CmmExpr -> NatM (Reg, InstrBlock)-getByteReg expr = do-  config <- getConfig-  is32Bit <- is32BitPlatform-  if is32Bit-      then do r <- getRegister expr-              case r of-                Any rep code -> do-                    tmp <- getNewRegNat rep-                    return (tmp, code tmp)-                Fixed rep reg code-                    | isVirtualReg reg -> return (reg,code)-                    | otherwise -> do-                        tmp <- getNewRegNat rep-                        return (tmp, code `snocOL` mkRegRegMoveInstr config rep reg tmp)-                    -- ToDo: could optimise slightly by checking for-                    -- byte-addressable real registers, but that will-                    -- happen very rarely if at all.-      else getSomeReg expr -- all regs are byte-addressable on x86_64---- Another variant: this time we want the result in a register that cannot--- be modified by code to evaluate an arbitrary expression.-getNonClobberedReg :: HasDebugCallStack => CmmExpr -> NatM (Reg, InstrBlock)-getNonClobberedReg expr = do-  r <- getRegister expr-  config <- getConfig-  let platform = ncgPlatform config-  case r of-    Any rep code -> do-        tmp <- getNewRegNat rep-        return (tmp, code tmp)-    Fixed rep reg code-        -- only certain regs can be clobbered-        | reg `elem` instrClobberedRegs platform-        -> do-                tmp <- getNewRegNat rep-                return (tmp, code `snocOL` mkRegRegMoveInstr config rep reg tmp)-        | otherwise ->-                return (reg, code)-------------------------------------------------------------------------------------- | Convert a 'CmmExpr' representing a memory address into an 'Amode'.------ An 'Amode' is a datatype representing a valid address form for the target--- (e.g. "Base + Index + disp" or immediate) and the code to compute it.-getAmode :: CmmExpr -> NatM Amode-getAmode e = do-   platform <- getPlatform-   let is32Bit = target32Bit platform--   case e of-      CmmRegOff r n-         -> getAmode $ mangleIndexTree r n--      CmmMachOp (MO_Add W64) [CmmReg (CmmGlobal (GlobalRegUse PicBaseReg _)), CmmLit displacement]-         | not is32Bit-         -> return $ Amode (ripRel (litToImm displacement)) nilOL--      -- This is all just ridiculous, since it carefully undoes-      -- what mangleIndexTree has just done.-      CmmMachOp (MO_Sub _rep) [x, CmmLit lit@(CmmInt i _)]-         | is32BitLit platform lit-         -- assert (rep == II32)???-         -> do-            (x_reg, x_code) <- getSomeReg x-            let off = ImmInt (-(fromInteger i))-            return (Amode (AddrBaseIndex (EABaseReg x_reg) EAIndexNone off) x_code)--      CmmMachOp (MO_Add _rep) [x, CmmLit lit]-         | is32BitLit platform lit-         -- assert (rep == II32)???-         -> do-            (x_reg, x_code) <- getSomeReg x-            let off = litToImm lit-            return (Amode (AddrBaseIndex (EABaseReg x_reg) EAIndexNone off) x_code)--      -- Turn (lit1 << n  + lit2) into  (lit2 + lit1 << n) so it will be-      -- recognised by the next rule.-      CmmMachOp (MO_Add rep) [a@(CmmMachOp (MO_Shl _) _), b@(CmmLit _)]-         -> getAmode (CmmMachOp (MO_Add rep) [b,a])--      -- Matches: (x + offset) + (y << shift)-      CmmMachOp (MO_Add _) [CmmRegOff x offset, CmmMachOp (MO_Shl _) [y, CmmLit (CmmInt shift _)]]-         | shift == 0 || shift == 1 || shift == 2 || shift == 3-         -> x86_complex_amode (CmmReg x) y shift (fromIntegral offset)--      CmmMachOp (MO_Add _) [x, CmmMachOp (MO_Shl _) [y, CmmLit (CmmInt shift _)]]-         | shift == 0 || shift == 1 || shift == 2 || shift == 3-         -> x86_complex_amode x y shift 0--      CmmMachOp (MO_Add _) [x, CmmMachOp (MO_Add _) [CmmMachOp (MO_Shl _)-                                                    [y, CmmLit (CmmInt shift _)], CmmLit (CmmInt offset _)]]-         | shift == 0 || shift == 1 || shift == 2 || shift == 3-         && is32BitInteger offset-         -> x86_complex_amode x y shift offset--      CmmMachOp (MO_Add _) [x,y]-         | not (isLit y) -- we already handle valid literals above.-         -> x86_complex_amode x y 0 0--      CmmLit lit@(CmmFloat {})-        -> pprPanic "X86 CodeGen: attempt to use floating-point value as a memory address"-             (ppr lit)--      -- Handle labels with %rip-relative addressing since in general the image-      -- may be loaded anywhere in the 64-bit address space (e.g. on Windows-      -- with high-entropy ASLR). See Note [%rip-relative addressing on x86-64].-      CmmLit lit-         | not is32Bit-         , is_label lit-         -> return (Amode (AddrBaseIndex EABaseRip EAIndexNone (litToImm lit)) nilOL)--      CmmLit lit-         | is32BitLit platform lit-         -> return (Amode (ImmAddr (litToImm lit) 0) nilOL)--      -- Literal with offsets too big (> 32 bits) fails during the linking phase-      -- (#15570). We already handled valid literals above so we don't have to-      -- test anything here.-      CmmLit (CmmLabelOff l off)-         -> getAmode (CmmMachOp (MO_Add W64) [ CmmLit (CmmLabel l)-                                             , CmmLit (CmmInt (fromIntegral off) W64)-                                             ])-      CmmLit (CmmLabelDiffOff l1 l2 off w)-         -> getAmode (CmmMachOp (MO_Add W64) [ CmmLit (CmmLabelDiffOff l1 l2 0 w)-                                             , CmmLit (CmmInt (fromIntegral off) W64)-                                             ])--      -- in case we can't do something better, we just compute the expression-      -- and put the result in a register-      _ -> do-        (reg,code) <- getSomeReg e-        return (Amode (AddrBaseIndex (EABaseReg reg) EAIndexNone (ImmInt 0)) code)-  where-    is_label (CmmLabel{}) = True-    is_label (CmmLabelOff{}) = True-    is_label (CmmLabelDiffOff{}) = True-    is_label _ = False----- | Like 'getAmode', but on 32-bit use simple register addressing--- (i.e. no index register). This stops us from running out of--- registers on x86 when using instructions such as cmpxchg, which can--- use up to three virtual registers and one fixed register.-getSimpleAmode :: CmmExpr -> NatM Amode-getSimpleAmode addr = is32BitPlatform >>= \case-  False -> getAmode addr-  True  -> do-    addr_code <- getAnyReg addr-    config <- getConfig-    addr_r <- getNewRegNat (intFormat (ncgWordWidth config))-    let amode = AddrBaseIndex (EABaseReg addr_r) EAIndexNone (ImmInt 0)-    return $! Amode amode (addr_code addr_r)--x86_complex_amode :: CmmExpr -> CmmExpr -> Integer -> Integer -> NatM Amode-x86_complex_amode base index shift offset-  = do (x_reg, x_code) <- getNonClobberedReg base-        -- x must be in a temp, because it has to stay live over y_code-        -- we could compare x_reg and y_reg and do something better here...-       (y_reg, y_code) <- getSomeReg index-       let-           code = x_code `appOL` y_code-           base = case shift of 0 -> 1; 1 -> 2; 2 -> 4; 3 -> 8;-                                n -> panic $ "x86_complex_amode: unhandled shift! (" ++ show n ++ ")"-       return (Amode (AddrBaseIndex (EABaseReg x_reg) (EAIndex y_reg base) (ImmInt (fromIntegral offset)))-               code)------- -------------------------------------------------------------------------------- getOperand: sometimes any operand will do.---- getNonClobberedOperand: the value of the operand will remain valid across--- the computation of an arbitrary expression, unless the expression--- is computed directly into a register which the operand refers to--- (see trivialCode where this function is used for an example).--getNonClobberedOperand :: CmmExpr -> NatM (Operand, InstrBlock)-getNonClobberedOperand (CmmLit lit) =-  if isSuitableFloatingPointLit lit-  then do-    let CmmFloat _ w = lit-    Amode addr code <- memConstant (mkAlignment $ widthInBytes w) lit-    return (OpAddr addr, code)-  else do-    platform <- getPlatform-    if is32BitLit platform lit && isIntFormat (cmmTypeFormat (cmmLitType platform lit))-    then return (OpImm (litToImm lit), nilOL)-    else getNonClobberedOperand_generic (CmmLit lit)--getNonClobberedOperand (CmmLoad mem ty _) = do-  is32Bit <- is32BitPlatform-  -- this logic could be simplified-  -- TODO FIXME-  if   (if is32Bit then not (isWord64 ty) else True)-      -- if 32bit and ty is at float/double/simd value-      -- or if 64bit-      --  this could use some eyeballs or i'll need to stare at it more later-    then do-      platform <- ncgPlatform <$> getConfig-      Amode src mem_code <- getAmode mem-      (src',save_code) <--        if (amodeCouldBeClobbered platform src)-                then do-                   tmp <- getNewRegNat (archWordFormat is32Bit)-                   return (AddrBaseIndex (EABaseReg tmp) EAIndexNone (ImmInt 0),-                           unitOL (LEA (archWordFormat is32Bit)-                                       (OpAddr src)-                                       (OpReg tmp)))-                else-                   return (src, nilOL)-      return (OpAddr src', mem_code `appOL` save_code)-    else-      -- if its a word or gcptr on 32bit?-      getNonClobberedOperand_generic (CmmLoad mem ty NaturallyAligned)--getNonClobberedOperand e = getNonClobberedOperand_generic e--getNonClobberedOperand_generic :: CmmExpr -> NatM (Operand, InstrBlock)-getNonClobberedOperand_generic e = do-  (reg, code) <- getNonClobberedReg e-  return (OpReg reg, code)--amodeCouldBeClobbered :: Platform -> AddrMode -> Bool-amodeCouldBeClobbered platform amode = any (regClobbered platform) (addrModeRegs amode)--regClobbered :: Platform -> Reg -> Bool-regClobbered platform (RegReal (RealRegSingle rr)) = freeReg platform rr-regClobbered _ _ = False---- getOperand: the operand is not required to remain valid across the--- computation of an arbitrary expression.-getOperand :: CmmExpr -> NatM (Operand, InstrBlock)--getOperand (CmmLit lit) = do-  if isSuitableFloatingPointLit lit-    then do-      let CmmFloat _ w = lit-      Amode addr code <- memConstant (mkAlignment $ widthInBytes w) lit-      return (OpAddr addr, code)-    else do--  platform <- getPlatform-  if is32BitLit platform lit && (isIntFormat $ cmmTypeFormat (cmmLitType platform lit))-    then return (OpImm (litToImm lit), nilOL)-    else getOperand_generic (CmmLit lit)--getOperand (CmmLoad mem ty _) = do-  is32Bit <- is32BitPlatform-  if isIntFormat (cmmTypeFormat ty) && (if is32Bit then not (isWord64 ty) else True)-     then do-       Amode src mem_code <- getAmode mem-       return (OpAddr src, mem_code)-     else-       getOperand_generic (CmmLoad mem ty NaturallyAligned)--getOperand e = getOperand_generic e--getOperand_generic :: CmmExpr -> NatM (Operand, InstrBlock)-getOperand_generic e = do-    (reg, code) <- getSomeReg e-    return (OpReg reg, code)--isOperand :: Platform -> CmmExpr -> Bool-isOperand _ (CmmLoad _ _ _) = True-isOperand platform (CmmLit lit)-                          = is32BitLit platform lit-                          || isSuitableFloatingPointLit lit-isOperand _ _            = False---- | Given a 'Register', produce a new 'Register' with an instruction block--- which will check the value for alignment. Used for @-falignment-sanitisation@.-addAlignmentCheck :: Int -> Register -> Register-addAlignmentCheck align reg =-    case reg of-      Fixed fmt reg code -> Fixed fmt reg (code `appOL` check fmt reg)-      Any fmt f          -> Any fmt (\reg -> f reg `appOL` check fmt reg)-  where-    check :: Format -> Reg -> InstrBlock-    check fmt reg =-        assert (isIntFormat fmt) $-        toOL [ TEST fmt (OpImm $ ImmInt $ align-1) (OpReg reg)-             , JXX_GBL NE $ ImmCLbl mkBadAlignmentLabel-             ]--memConstant :: Alignment -> CmmLit -> NatM Amode-memConstant align lit = do-  lbl <- getNewLabelNat-  let rosection = Section ReadOnlyData lbl-  config <- getConfig-  platform <- getPlatform-  (addr, addr_code) <- if target32Bit platform-                       then do dynRef <- cmmMakeDynamicReference-                                             config-                                             DataReference-                                             lbl-                               Amode addr addr_code <- getAmode dynRef-                               return (addr, addr_code)-                       else return (ripRel (ImmCLbl lbl), nilOL)-  let code =-        LDATA rosection (align, CmmStaticsRaw lbl [CmmStaticLit lit])-        `consOL` addr_code-  return (Amode addr code)---- | Load the value at the given address into any register.-loadAmode :: Format -> AddrMode -> InstrBlock -> NatM Register-loadAmode fmt addr addr_code = do-  config <- getConfig-  let load dst = movInstr config fmt (OpAddr addr) (OpReg dst)-  return $ Any fmt (\ dst -> addr_code `snocOL` load dst)---- if we want a floating-point literal as an operand, we can--- use it directly from memory.  However, if the literal is--- zero, we're better off generating it into a register using--- xor.-isSuitableFloatingPointLit :: CmmLit -> Bool-isSuitableFloatingPointLit (CmmFloat f _) = f /= 0.0-isSuitableFloatingPointLit _ = False--getRegOrMem :: CmmExpr -> NatM (Operand, InstrBlock)-getRegOrMem e@(CmmLoad mem ty _) = do-  is32Bit <- is32BitPlatform-  if isIntFormat (cmmTypeFormat ty) && (if is32Bit then not (isWord64 ty) else True)-     then do-       Amode src mem_code <- getAmode mem-       return (OpAddr src, mem_code)-     else do-       (reg, code) <- getNonClobberedReg e-       return (OpReg reg, code)-getRegOrMem e = do-    (reg, code) <- getNonClobberedReg e-    return (OpReg reg, code)--is32BitLit :: Platform -> CmmLit -> Bool-is32BitLit platform _lit-   | target32Bit platform = True-is32BitLit platform lit =-   case lit of-      CmmInt i W64              -> is32BitInteger i-      -- Except on Windows, assume that labels are in the range 0-2^31-1: this-      -- assumes the small memory model. Note [%rip-relative addressing on-      -- x86-64].-      CmmLabel _                -> low_image-      -- however we can't assume that label offsets are in this range-      -- (see #15570)-      CmmLabelOff _ off         -> low_image && is32BitInteger (fromIntegral off)-      CmmLabelDiffOff _ _ off _ -> low_image && is32BitInteger (fromIntegral off)-      _                         -> True-  where-    -- Is the executable image certain to be located below 4GB? As noted in-    -- Note [%rip-relative addressing on x86-64], this is not true on Windows.-    low_image =-      case platformOS platform of-        OSMinGW32 -> False   -- See Note [%rip-relative addressing on x86-64]-        _         -> True----- Set up a condition code for a conditional branch.--getCondCode :: CmmExpr -> NatM CondCode---- yes, they really do seem to want exactly the same!--getCondCode (CmmMachOp mop [x, y])-  =-    case mop of-      MO_F_Eq W32 -> condFltCode EQQ x y-      MO_F_Ne W32 -> condFltCode NE  x y-      MO_F_Gt W32 -> condFltCode GTT x y-      MO_F_Ge W32 -> condFltCode GE  x y-      -- Invert comparison condition and swap operands-      -- See Note [SSE Parity Checks]-      MO_F_Lt W32 -> condFltCode GTT  y x-      MO_F_Le W32 -> condFltCode GE   y x--      MO_F_Eq W64 -> condFltCode EQQ x y-      MO_F_Ne W64 -> condFltCode NE  x y-      MO_F_Gt W64 -> condFltCode GTT x y-      MO_F_Ge W64 -> condFltCode GE  x y-      MO_F_Lt W64 -> condFltCode GTT y x-      MO_F_Le W64 -> condFltCode GE  y x--      _ -> condIntCode (machOpToCond mop) x y--getCondCode other = do-   platform <- getPlatform-   pprPanic "getCondCode(2)(x86,x86_64)" (pdoc platform other)--machOpToCond :: MachOp -> Cond-machOpToCond mo = case mo of-  MO_Eq _   -> EQQ-  MO_Ne _   -> NE-  MO_S_Gt _ -> GTT-  MO_S_Ge _ -> GE-  MO_S_Lt _ -> LTT-  MO_S_Le _ -> LE-  MO_U_Gt _ -> GU-  MO_U_Ge _ -> GEU-  MO_U_Lt _ -> LU-  MO_U_Le _ -> LEU-  _other -> pprPanic "machOpToCond" (pprMachOp mo)--{-  Note [64-bit integer comparisons on 32-bit]-    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~--    When doing these comparisons there are 2 kinds of-    comparisons.--    * Comparison for equality (or lack thereof)--    We use xor to check if high/low bits are-    equal. Then combine the results using or.--    * Other comparisons:--    We first compare the low registers-    and use a subtraction with borrow to compare the high registers.--    For signed numbers the condition is determined by-    the sign and overflow flags agreeing or not-    and for unsigned numbers the condition is the carry flag.---}---- @cond(Int|Flt)Code@: Turn a boolean expression into a condition, to be--- passed back up the tree.--condIntCode :: Cond -> CmmExpr -> CmmExpr -> NatM CondCode-condIntCode cond x y = do platform <- getPlatform-                          condIntCode' platform cond x y--condIntCode' :: Platform -> Cond -> CmmExpr -> CmmExpr -> NatM CondCode---- 64-bit integer comparisons on 32-bit--- See Note [64-bit integer comparisons on 32-bit]-condIntCode' platform cond x y-  | target32Bit platform && isWord64 (cmmExprType platform x) = do--  RegCode64 code1 r1hi r1lo <- iselExpr64 x-  RegCode64 code2 r2hi r2lo <- iselExpr64 y--  -- we mustn't clobber r1/r2 so we use temporaries-  tmp1 <- getNewRegNat II32-  tmp2 <- getNewRegNat II32--  let (cond', cmpCode) = intComparison cond r1hi r1lo r2hi r2lo tmp1 tmp2-  return $ CondCode False cond' (code1 `appOL` code2 `appOL` cmpCode)--  where-    intComparison cond r1_hi r1_lo r2_hi r2_lo tmp1 tmp2 =-      case cond of-        -- These don't occur as argument of condIntCode'-        ALWAYS  -> panic "impossible"-        NEG     -> panic "impossible"-        POS     -> panic "impossible"-        CARRY   -> panic "impossible"-        OFLO    -> panic "impossible"-        PARITY  -> panic "impossible"-        NOTPARITY -> panic "impossible"-        -- Special case #1 x == y and x != y-        EQQ -> (EQQ, cmpExact)-        NE  -> (NE, cmpExact)-        -- [x >= y]-        GE  -> (GE, cmpGE)-        GEU -> (GEU, cmpGE)-        -- [x >  y]-        GTT -> (LTT, cmpLE)-        GU  -> (LU, cmpLE)-        -- [x <= y]-        LE  -> (GE, cmpLE)-        LEU -> (GEU, cmpLE)-        -- [x <  y]-        LTT -> (LTT, cmpGE)-        LU  -> (LU, cmpGE)-      where-        cmpExact :: OrdList Instr-        cmpExact =-          toOL-            [ MOV II32 (OpReg r1_hi) (OpReg tmp1)-            , MOV II32 (OpReg r1_lo) (OpReg tmp2)-            , XOR II32 (OpReg r2_hi) (OpReg tmp1)-            , XOR II32 (OpReg r2_lo) (OpReg tmp2)-            , OR  II32 (OpReg tmp1)  (OpReg tmp2)-            ]-        cmpGE = toOL-            [ MOV II32 (OpReg r1_hi) (OpReg tmp1)-            , CMP II32 (OpReg r2_lo) (OpReg r1_lo)-            , SBB II32 (OpReg r2_hi) (OpReg tmp1)-            ]-        cmpLE = toOL-            [ MOV II32 (OpReg r2_hi) (OpReg tmp1)-            , CMP II32 (OpReg r1_lo) (OpReg r2_lo)-            , SBB II32 (OpReg r1_hi) (OpReg tmp1)-            ]---- memory vs immediate-condIntCode' platform cond (CmmLoad x ty _) (CmmLit lit)- | is32BitLit platform lit = do-    Amode x_addr x_code <- getAmode x-    let-        imm  = litToImm lit-        code = x_code `snocOL`-                  CMP (cmmTypeFormat ty) (OpImm imm) (OpAddr x_addr)-    ---    return (CondCode False cond code)---- anything vs zero, using a mask--- TODO: Add some sanity checking!!!!-condIntCode' platform cond (CmmMachOp (MO_And _) [x,o2]) (CmmLit (CmmInt 0 ty))-    | (CmmLit lit@(CmmInt mask _)) <- o2, is32BitLit platform lit-    = do-      (x_reg, x_code) <- getSomeReg x-      let-         code = x_code `snocOL`-                TEST (intFormat ty) (OpImm (ImmInteger mask)) (OpReg x_reg)-      ---      return (CondCode False cond code)---- anything vs zero-condIntCode' _ cond x (CmmLit (CmmInt 0 ty)) = do-    (x_reg, x_code) <- getSomeReg x-    let-        code = x_code `snocOL`-                  TEST (intFormat ty) (OpReg x_reg) (OpReg x_reg)-    ---    return (CondCode False cond code)---- anything vs operand-condIntCode' platform cond x y- | isOperand platform y = do-    (x_reg, x_code) <- getNonClobberedReg x-    (y_op,  y_code) <- getOperand y-    let-        code = x_code `appOL` y_code `snocOL`-                  CMP (cmmTypeFormat (cmmExprType platform x)) y_op (OpReg x_reg)-    return (CondCode False cond code)--- operand vs. anything: invert the comparison so that we can use a--- single comparison instruction.- | isOperand platform x- , Just revcond <- maybeFlipCond cond = do-    (y_reg, y_code) <- getNonClobberedReg y-    (x_op,  x_code) <- getOperand x-    let-        code = y_code `appOL` x_code `snocOL`-                  CMP (cmmTypeFormat (cmmExprType platform x)) x_op (OpReg y_reg)-    return (CondCode False revcond code)---- anything vs anything-condIntCode' platform cond x y = do-  (y_reg, y_code) <- getNonClobberedReg y-  (x_op, x_code) <- getRegOrMem x-  let-        code = y_code `appOL`-               x_code `snocOL`-                  CMP (cmmTypeFormat (cmmExprType platform x)) (OpReg y_reg) x_op-  return (CondCode False cond code)-------------------------------------------------------------------------------------condFltCode :: Cond -> CmmExpr -> CmmExpr -> NatM CondCode--condFltCode cond x y-  =  condFltCode_sse2-  where---  -- in the SSE2 comparison ops (ucomiss, ucomisd) the left arg may be-  -- an operand, but the right must be a reg.  We can probably do better-  -- than this general case...-  condFltCode_sse2 = do-    platform <- getPlatform-    (x_reg, x_code) <- getNonClobberedReg x-    (y_op, y_code) <- getOperand y-    let-        code = x_code `appOL`-               y_code `snocOL`-                  CMP (floatFormat $ cmmExprWidth platform x) y_op (OpReg x_reg)-        -- NB(1): we need to use the unsigned comparison operators on the-        -- result of this comparison.-    return (CondCode True (condToUnsigned cond) code)---- -------------------------------------------------------------------------------- Generating assignments---- Assignments are really at the heart of the whole code generation--- business.  Almost all top-level nodes of any real importance are--- assignments, which correspond to loads, stores, or register--- transfers.  If we're really lucky, some of the register transfers--- will go away, because we can use the destination register to--- complete the code generation for the right hand side.  This only--- fails when the right hand side is forced into a fixed register--- (e.g. the result of a call).--assignMem_IntCode :: Format -> CmmExpr -> CmmExpr -> NatM InstrBlock-assignReg_IntCode ::           CmmReg  -> CmmExpr -> NatM InstrBlock--assignMem_FltCode :: Format -> CmmExpr -> CmmExpr -> NatM InstrBlock-assignReg_FltCode ::           CmmReg  -> CmmExpr -> NatM InstrBlock--assignMem_VecCode :: Format -> CmmExpr -> CmmExpr -> NatM InstrBlock-assignReg_VecCode ::           CmmReg  -> CmmExpr -> NatM InstrBlock---- integer assignment to memory---- specific case of adding/subtracting an integer to a particular address.--- ToDo: catch other cases where we can use an operation directly on a memory--- address.-assignMem_IntCode ty addr (CmmMachOp op [CmmLoad addr2 _ _,-                                                 CmmLit (CmmInt i _)])-   | addr == addr2, ty /= II64 || is32BitInteger i,-     Just instr <- check op-   = do Amode amode code_addr <- getAmode addr-        let code = code_addr `snocOL`-                   instr ty (OpImm (ImmInt (fromIntegral i))) (OpAddr amode)-        return code-   where-        check (MO_Add _) = Just ADD-        check (MO_Sub _) = Just SUB-        check _ = Nothing-        -- ToDo: more?---- general case-assignMem_IntCode ty addr src = do-    platform <- getPlatform-    Amode addr code_addr <- getAmode addr-    (code_src, op_src)   <- get_op_RI platform src-    let-        code = code_src `appOL`-               code_addr `snocOL`-                  MOV ty op_src (OpAddr addr)-        -- NOTE: op_src is stable, so it will still be valid-        -- after code_addr.  This may involve the introduction-        -- of an extra MOV to a temporary register, but we hope-        -- the register allocator will get rid of it.-    ---    return code-  where-    get_op_RI :: Platform -> CmmExpr -> NatM (InstrBlock,Operand)   -- code, operator-    get_op_RI platform (CmmLit lit) | is32BitLit platform lit-      = return (nilOL, OpImm (litToImm lit))-    get_op_RI _ op-      = do (reg,code) <- getNonClobberedReg op-           return (code, OpReg reg)----- Assign; dst is a reg, rhs is mem-assignReg_IntCode reg (CmmLoad src _ _) = do-  let ty = cmmTypeFormat $ cmmRegType reg-  load_code <- intLoadCode (MOV ty) src-  platform <- ncgPlatform <$> getConfig-  return (load_code (getRegisterReg platform reg))---- dst is a reg, but src could be anything-assignReg_IntCode reg src = do-  platform <- ncgPlatform <$> getConfig-  code <- getAnyReg src-  return (code (getRegisterReg platform reg))----- Floating point assignment to memory-assignMem_FltCode ty addr src = do-  (src_reg, src_code) <- getNonClobberedReg src-  Amode addr addr_code <- getAmode addr-  let-        code = src_code `appOL`-               addr_code `snocOL`-               MOV ty (OpReg src_reg) (OpAddr addr)--  return code---- Floating point assignment to a register/temporary-assignReg_FltCode reg src = do-  src_code <- getAnyReg src-  platform <- ncgPlatform <$> getConfig-  return (src_code (getRegisterReg platform reg))---- Vector assignment to a register/temporary-assignMem_VecCode ty addr src = do-  (src_reg, src_code) <- getNonClobberedReg src-  Amode addr addr_code <- getAmode addr-  config <- getConfig-  let-    code = src_code `appOL`-           addr_code `snocOL`-           movInstr config ty (OpReg src_reg) (OpAddr addr)-  return code--assignReg_VecCode reg src = do-  platform <- ncgPlatform <$> getConfig-  src_code <- getAnyReg src-  return (src_code (getRegisterReg platform reg))--genJump :: CmmExpr{-the branch target-} -> [RegWithFormat] -> NatM InstrBlock--genJump (CmmLoad mem _ _) regs = do-  Amode target code <- getAmode mem-  return (code `snocOL` JMP (OpAddr target) regs)--genJump (CmmLit lit) regs =-  return (unitOL (JMP (OpImm (litToImm lit)) regs))--genJump expr regs = do-  (reg,code) <- getSomeReg expr-  return (code `snocOL` JMP (OpReg reg) regs)----- --------------------------------------------------------------------------------  Unconditional branches--genBranch :: BlockId -> InstrBlock-genBranch = toOL . mkJumpInstr------ --------------------------------------------------------------------------------  Conditional jumps/branches--{--Conditional jumps are always to local labels, so we can use branch-instructions.  We peek at the arguments to decide what kind of-comparison to do.--I386: First, we have to ensure that the condition-codes are set according to the supplied comparison operation.--}--genCondBranch-    :: BlockId      -- the source of the jump-    -> BlockId      -- the true branch target-    -> BlockId      -- the false branch target-    -> CmmExpr      -- the condition on which to branch-    -> NatM InstrBlock -- Instructions--genCondBranch bid id false expr = do-  is32Bit <- is32BitPlatform-  genCondBranch' is32Bit bid id false expr---- | We return the instructions generated.-genCondBranch' :: Bool -> BlockId -> BlockId -> BlockId -> CmmExpr-               -> NatM InstrBlock--genCondBranch' _ bid id false bool = do-  CondCode is_float cond cond_code <- getCondCode bool-  if not is_float-    then-        return (cond_code `snocOL` JXX cond id `appOL` genBranch false)-    else do-        -- See Note [SSE Parity Checks]-        let jmpFalse = genBranch false-            code-                = case cond of-                  NE  -> or_unordered-                  GU  -> plain_test-                  GEU -> plain_test-                  -- Use ASSERT so we don't break releases if-                  -- LTT/LE creep in somehow.-                  LTT ->-                    assertPpr False (text "Should have been turned into >")-                    and_ordered-                  LE  ->-                    assertPpr False (text "Should have been turned into >=")-                    and_ordered-                  _   -> and_ordered--            plain_test = unitOL (-                  JXX cond id-                ) `appOL` jmpFalse-            or_unordered = toOL [-                  JXX cond id,-                  JXX PARITY id-                ] `appOL` jmpFalse-            and_ordered = toOL [-                  JXX PARITY false,-                  JXX cond id,-                  JXX ALWAYS false-                ]-        updateCfgNat (\cfg -> adjustEdgeWeight cfg (+3) bid false)-        return (cond_code `appOL` code)--{-  Note [Introducing cfg edges inside basic blocks]-    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~--    During instruction selection a statement `s`-    in a block B with control of the sort: B -> C-    will sometimes result in control-    flow of the sort:--            ┌ < ┐-            v   ^-      B ->  B1  ┴ -> C--    as is the case for some atomic operations.--    Now to keep the CFG in sync when introducing B1 we clearly-    want to insert it between B and C. However there is-    a catch when we have to deal with self loops.--    We might start with code and a CFG of these forms:--    loop:-        stmt1               ┌ < ┐-        ....                v   ^-        stmtX              loop ┘-        stmtY-        ....-        goto loop:--    Now we introduce B1:-                            ┌ ─ ─ ─ ─ ─┐-        loop:               │   ┌ <  ┐ │-        instrs              v   │    │ ^-        ....               loop ┴ B1 ┴ ┘-        instrsFromX-        stmtY-        goto loop:--    This is simple, all outgoing edges from loop now simply-    start from B1 instead and the code generator knows which-    new edges it introduced for the self loop of B1.--    Disaster strikes if the statement Y follows the same pattern.-    If we apply the same rule that all outgoing edges change then-    we end up with:--        loop ─> B1 ─> B2 ┬─┐-          │      │    └─<┤ │-          │      └───<───┘ │-          └───────<────────┘--    This is problematic. The edge B1->B1 is modified as expected.-    However the modification is wrong!--    The assembly in this case looked like this:--    _loop:-        <instrs>-    _B1:-        ...-        cmpxchgq ...-        jne _B1-        <instrs>-        <end _B1>-    _B2:-        ...-        cmpxchgq ...-        jne _B2-        <instrs>-        jmp loop--    There is no edge _B2 -> _B1 here. It's still a self loop onto _B1.--    The problem here is that really B1 should be two basic blocks.-    Otherwise we have control flow in the *middle* of a basic block.-    A contradiction!--    So to account for this we add yet another basic block marker:--    _B:-        <instrs>-    _B1:-        ...-        cmpxchgq ...-        jne _B1-        jmp _B1'-    _B1':-        <instrs>-        <end _B1>-    _B2:-        ...--    Now when inserting B2 we will only look at the outgoing edges of B1' and-    everything will work out nicely.--    You might also wonder why we don't insert jumps at the end of _B1'. There is-    no way another block ends up jumping to the labels _B1 or _B2 since they are-    essentially invisible to other blocks. View them as control flow labels local-    to the basic block if you'd like.--    Not doing this ultimately caused (part 2 of) #17334.--}----- --------------------------------------------------------------------------------  Generating C calls---- Now the biggest nightmare---calls.  Most of the nastiness is buried in--- @get_arg@, which moves the arguments to the correct registers/stack--- locations.  Apart from that, the code is easy.------ (If applicable) Do not fill the delay slots here; you will confuse the--- register allocator.------ See Note [Keeping track of the current block] for information why we need--- to take/return a block id.--genForeignCall-    :: ForeignTarget -- ^ function to call-    -> [CmmFormal]   -- ^ where to put the result-    -> [CmmActual]   -- ^ arguments (of mixed type)-    -> BlockId       -- ^ The block we are in-    -> NatM (InstrBlock, Maybe BlockId)--genForeignCall target dst args bid = do-  case target of-    PrimTarget prim         -> genPrim bid prim dst args-    ForeignTarget addr conv -> (,Nothing) <$> genCCall bid addr conv dst args--genPrim-    :: BlockId       -- ^ The block we are in-    -> CallishMachOp -- ^ MachOp-    -> [CmmFormal]   -- ^ where to put the result-    -> [CmmActual]   -- ^ arguments (of mixed type)-    -> NatM (InstrBlock, Maybe BlockId)---- First we deal with cases which might introduce new blocks in the stream.-genPrim bid (MO_AtomicRMW width amop) [dst] [addr, n]-  = genAtomicRMW bid width amop dst addr n-genPrim bid (MO_Ctz width) [dst] [src]-  = genCtz bid width dst src---- Then we deal with cases which not introducing new blocks in the stream.-genPrim bid prim dst args-  = (,Nothing) <$> genSimplePrim bid prim dst args--genSimplePrim-    :: BlockId       -- ^ the block we are in-    -> CallishMachOp -- ^ MachOp-    -> [CmmFormal]   -- ^ where to put the result-    -> [CmmActual]   -- ^ arguments (of mixed type)-    -> NatM InstrBlock-genSimplePrim bid (MO_Memcpy align)    []      [dst,src,n]    = genMemCpy  bid align dst src n-genSimplePrim bid (MO_Memmove align)   []      [dst,src,n]    = genMemMove bid align dst src n-genSimplePrim bid (MO_Memcmp align)    [res]   [dst,src,n]    = genMemCmp  bid align res dst src n-genSimplePrim bid (MO_Memset align)    []      [dst,c,n]      = genMemSet  bid align dst c n-genSimplePrim _   MO_AcquireFence      []      []             = return nilOL -- barriers compile to no code on x86/x86-64;-genSimplePrim _   MO_ReleaseFence      []      []             = return nilOL -- we keep it this long in order to prevent earlier optimisations.-genSimplePrim _   MO_SeqCstFence       []      []             = return $ unitOL MFENCE-genSimplePrim _   MO_Touch             []      [_]            = return nilOL-genSimplePrim _   (MO_Prefetch_Data n) []      [src]          = genPrefetchData n src-genSimplePrim _   (MO_BSwap width)     [dst]   [src]          = genByteSwap width dst src-genSimplePrim bid (MO_BRev width)      [dst]   [src]          = genBitRev bid width dst src-genSimplePrim bid (MO_PopCnt width)    [dst]   [src]          = genPopCnt bid width dst src-genSimplePrim bid (MO_Pdep width)      [dst]   [src,mask]     = genPdep bid width dst src mask-genSimplePrim bid (MO_Pext width)      [dst]   [src,mask]     = genPext bid width dst src mask-genSimplePrim bid (MO_Clz width)       [dst]   [src]          = genClz bid width dst src-genSimplePrim bid (MO_UF_Conv width)   [dst]   [src]          = genWordToFloat bid width dst src-genSimplePrim _   (MO_AtomicRead w mo)  [dst]  [addr]         = genAtomicRead w mo dst addr-genSimplePrim _   (MO_AtomicWrite w mo) []     [addr,val]     = genAtomicWrite w mo addr val-genSimplePrim bid (MO_Cmpxchg width)   [dst]   [addr,old,new] = genCmpXchg bid width dst addr old new-genSimplePrim _   (MO_Xchg width)      [dst]   [addr, value]  = genXchg width dst addr value-genSimplePrim _   (MO_AddWordC w)      [r,c]   [x,y]          = genAddSubRetCarry w ADD_CC (const Nothing) CARRY r c x y-genSimplePrim _   (MO_SubWordC w)      [r,c]   [x,y]          = genAddSubRetCarry w SUB_CC (const Nothing) CARRY r c x y-genSimplePrim _   (MO_AddIntC w)       [r,c]   [x,y]          = genAddSubRetCarry w ADD_CC (Just . ADD_CC) OFLO  r c x y-genSimplePrim _   (MO_SubIntC w)       [r,c]   [x,y]          = genAddSubRetCarry w SUB_CC (const Nothing) OFLO  r c x y-genSimplePrim _   (MO_Add2 w)          [h,l]   [x,y]          = genAddWithCarry w h l x y-genSimplePrim _   (MO_U_Mul2 w)        [h,l]   [x,y]          = genUnsignedLargeMul w h l x y-genSimplePrim _   (MO_S_Mul2 w)        [c,h,l] [x,y]          = genSignedLargeMul w c h l x y-genSimplePrim _   (MO_S_QuotRem w)     [q,r]   [x,y]          = genQuotRem w True  q r Nothing   x  y-genSimplePrim _   (MO_U_QuotRem w)     [q,r]   [x,y]          = genQuotRem w False q r Nothing   x  y-genSimplePrim _   (MO_U_QuotRem2 w)    [q,r]   [hx,lx,y]      = genQuotRem w False q r (Just hx) lx y-genSimplePrim _   MO_F32_Fabs          [dst]   [src]          = genFloatAbs W32 dst src-genSimplePrim _   MO_F64_Fabs          [dst]   [src]          = genFloatAbs W64 dst src-genSimplePrim _   MO_F32_Sqrt          [dst]   [src]          = genFloatSqrt FF32 dst src-genSimplePrim _   MO_F64_Sqrt          [dst]   [src]          = genFloatSqrt FF64 dst src-genSimplePrim bid MO_F32_Sin           [dst]   [src]          = genLibCCall bid (fsLit "sinf") [dst] [src]-genSimplePrim bid MO_F32_Cos           [dst]   [src]          = genLibCCall bid (fsLit "cosf") [dst] [src]-genSimplePrim bid MO_F32_Tan           [dst]   [src]          = genLibCCall bid (fsLit "tanf") [dst] [src]-genSimplePrim bid MO_F32_Exp           [dst]   [src]          = genLibCCall bid (fsLit "expf") [dst] [src]-genSimplePrim bid MO_F32_ExpM1         [dst]   [src]          = genLibCCall bid (fsLit "expm1f") [dst] [src]-genSimplePrim bid MO_F32_Log           [dst]   [src]          = genLibCCall bid (fsLit "logf") [dst] [src]-genSimplePrim bid MO_F32_Log1P         [dst]   [src]          = genLibCCall bid (fsLit "log1pf") [dst] [src]-genSimplePrim bid MO_F32_Asin          [dst]   [src]          = genLibCCall bid (fsLit "asinf") [dst] [src]-genSimplePrim bid MO_F32_Acos          [dst]   [src]          = genLibCCall bid (fsLit "acosf") [dst] [src]-genSimplePrim bid MO_F32_Atan          [dst]   [src]          = genLibCCall bid (fsLit "atanf") [dst] [src]-genSimplePrim bid MO_F32_Sinh          [dst]   [src]          = genLibCCall bid (fsLit "sinhf") [dst] [src]-genSimplePrim bid MO_F32_Cosh          [dst]   [src]          = genLibCCall bid (fsLit "coshf") [dst] [src]-genSimplePrim bid MO_F32_Tanh          [dst]   [src]          = genLibCCall bid (fsLit "tanhf") [dst] [src]-genSimplePrim bid MO_F32_Pwr           [dst]   [x,y]          = genLibCCall bid (fsLit "powf")  [dst] [x,y]-genSimplePrim bid MO_F32_Asinh         [dst]   [src]          = genLibCCall bid (fsLit "asinhf") [dst] [src]-genSimplePrim bid MO_F32_Acosh         [dst]   [src]          = genLibCCall bid (fsLit "acoshf") [dst] [src]-genSimplePrim bid MO_F32_Atanh         [dst]   [src]          = genLibCCall bid (fsLit "atanhf") [dst] [src]-genSimplePrim bid MO_F64_Sin           [dst]   [src]          = genLibCCall bid (fsLit "sin") [dst] [src]-genSimplePrim bid MO_F64_Cos           [dst]   [src]          = genLibCCall bid (fsLit "cos") [dst] [src]-genSimplePrim bid MO_F64_Tan           [dst]   [src]          = genLibCCall bid (fsLit "tan") [dst] [src]-genSimplePrim bid MO_F64_Exp           [dst]   [src]          = genLibCCall bid (fsLit "exp") [dst] [src]-genSimplePrim bid MO_F64_ExpM1         [dst]   [src]          = genLibCCall bid (fsLit "expm1") [dst] [src]-genSimplePrim bid MO_F64_Log           [dst]   [src]          = genLibCCall bid (fsLit "log") [dst] [src]-genSimplePrim bid MO_F64_Log1P         [dst]   [src]          = genLibCCall bid (fsLit "log1p") [dst] [src]-genSimplePrim bid MO_F64_Asin          [dst]   [src]          = genLibCCall bid (fsLit "asin") [dst] [src]-genSimplePrim bid MO_F64_Acos          [dst]   [src]          = genLibCCall bid (fsLit "acos") [dst] [src]-genSimplePrim bid MO_F64_Atan          [dst]   [src]          = genLibCCall bid (fsLit "atan") [dst] [src]-genSimplePrim bid MO_F64_Sinh          [dst]   [src]          = genLibCCall bid (fsLit "sinh") [dst] [src]-genSimplePrim bid MO_F64_Cosh          [dst]   [src]          = genLibCCall bid (fsLit "cosh") [dst] [src]-genSimplePrim bid MO_F64_Tanh          [dst]   [src]          = genLibCCall bid (fsLit "tanh") [dst] [src]-genSimplePrim bid MO_F64_Pwr           [dst]   [x,y]          = genLibCCall bid (fsLit "pow")  [dst] [x,y]-genSimplePrim bid MO_F64_Asinh         [dst]   [src]          = genLibCCall bid (fsLit "asinh") [dst] [src]-genSimplePrim bid MO_F64_Acosh         [dst]   [src]          = genLibCCall bid (fsLit "acosh") [dst] [src]-genSimplePrim bid MO_F64_Atanh         [dst]   [src]          = genLibCCall bid (fsLit "atanh") [dst] [src]-genSimplePrim bid MO_SuspendThread     [tok]   [rs,i]         = genRTSCCall bid (fsLit "suspendThread") [tok] [rs,i]-genSimplePrim bid MO_ResumeThread      [rs]    [tok]          = genRTSCCall bid (fsLit "resumeThread") [rs] [tok]-genSimplePrim bid MO_I64_Quot          [dst]   [x,y]          = genPrimCCall bid (fsLit "hs_quotInt64") [dst] [x,y]-genSimplePrim bid MO_I64_Rem           [dst]   [x,y]          = genPrimCCall bid (fsLit "hs_remInt64") [dst] [x,y]-genSimplePrim bid MO_W64_Quot          [dst]   [x,y]          = genPrimCCall bid (fsLit "hs_quotWord64") [dst] [x,y]-genSimplePrim bid MO_W64_Rem           [dst]   [x,y]          = genPrimCCall bid (fsLit "hs_remWord64") [dst] [x,y]-genSimplePrim _   op                   dst     args           = do-  platform <- ncgPlatform <$> getConfig-  pprPanic "genSimplePrim: unhandled primop" (ppr (pprCallishMachOp op, dst, fmap (pdoc platform) args))--{- Note [Evaluate C-call arguments before placing in destination registers]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-When producing code for C calls we must take care when placing arguments-in their final registers. Specifically, we must ensure that temporary register-usage due to evaluation of one argument does not clobber a register in which we-already placed a previous argument (e.g. as the code generation logic for-MO_Shl can clobber %rcx due to x86 instruction limitations).--This is precisely what happened in #18527. Consider this C--:--    (result::I64) = call "ccall" doSomething(_s2hp::I64, 2244, _s2hq::I64, _s2hw::I64 | (1 << _s2hz::I64));--Here we are calling the C function `doSomething` with three arguments, the last-involving a non-trivial expression involving MO_Shl. In this case the NCG could-naively generate the following assembly (where $tmp denotes some temporary-register and $argN denotes the register for argument N, as dictated by the-platform's calling convention):--    mov _s2hp, $arg1   # place first argument-    mov _s2hq, $arg2   # place second argument--    # Compute 1 << _s2hz-    mov _s2hz, %rcx-    shl %cl, $tmp--    # Compute (_s2hw | (1 << _s2hz))-    mov _s2hw, $arg3-    or $tmp, $arg3--    # Perform the call-    call func--This code is outright broken on Windows which assigns $arg1 to %rcx. This means-that the evaluation of the last argument clobbers the first argument.--To avoid this we use a rather awful hack: when producing code for a C call with-at least one non-trivial argument, we first evaluate all of the arguments into-local registers before moving them into their final calling-convention-defined-homes.  This is performed by 'evalArgs'. Here we define "non-trivial" to be an-expression which might contain a MachOp since these are the only cases which-might clobber registers. Furthermore, we use a conservative approximation of-this condition (only looking at the top-level of CmmExprs) to avoid spending-too much effort trying to decide whether we want to take the fast path.--Note that this hack *also* applies to calls to out-of-line PrimTargets (which-are lowered via a C call), which will ultimately end up in-genForeignCall{32,64}.--}---- | See Note [Evaluate C-call arguments before placing in destination registers]-evalArgs :: BlockId -> [CmmActual] -> NatM (InstrBlock, [CmmActual])-evalArgs bid actuals-  | any loadIntoRegMightClobberOtherReg actuals = do-      regs_blks <- mapM evalArg actuals-      return (concatOL $ map fst regs_blks, map snd regs_blks)-  | otherwise = return (nilOL, actuals)-  where--    evalArg :: CmmActual -> NatM (InstrBlock, CmmExpr)-    evalArg actual = do-        platform <- getPlatform-        lreg <- newLocalReg $ cmmExprType platform actual-        (instrs, bid1) <- stmtToInstrs bid $ CmmAssign (CmmLocal lreg) actual-        -- The above assignment shouldn't change the current block-        massert (isNothing bid1)-        return (instrs, CmmReg $ CmmLocal lreg)--    newLocalReg :: CmmType -> NatM LocalReg-    newLocalReg ty = LocalReg <$> getUniqueM <*> pure ty---- | Might the code to put this expression into a register--- clobber any other registers?-loadIntoRegMightClobberOtherReg :: CmmExpr -> Bool-loadIntoRegMightClobberOtherReg (CmmReg _)      = False-loadIntoRegMightClobberOtherReg (CmmRegOff _ _) = False-loadIntoRegMightClobberOtherReg (CmmLit _)      = False-  -- NB: this last 'False' is slightly risky, because the code for loading-  -- a literal into a register is not entirely trivial.-loadIntoRegMightClobberOtherReg _               = True---- Note [DIV/IDIV for bytes]--- ~~~~~~~~~~~~~~~~~~~~~~~~~--- IDIV reminder:---   Size    Dividend   Divisor   Quotient    Remainder---   byte    %ax         r/m8      %al          %ah---   word    %dx:%ax     r/m16     %ax          %dx---   dword   %edx:%eax   r/m32     %eax         %edx---   qword   %rdx:%rax   r/m64     %rax         %rdx------ We do a special case for the byte division because the current--- codegen doesn't deal well with accessing %ah register (also,--- accessing %ah in 64-bit mode is complicated because it cannot be an--- operand of many instructions). So we just widen operands to 16 bits--- and get the results from %al, %dl. This is not optimal, but a few--- register moves are probably not a huge deal when doing division.----- | Generate C call to the given function in ghc-prim-genPrimCCall-  :: BlockId-  -> FastString-  -> [CmmFormal]-  -> [CmmActual]-  -> NatM InstrBlock-genPrimCCall bid lbl_txt dsts args = do-  config <- getConfig-  -- FIXME: we should use mkForeignLabel instead of mkCmmCodeLabel-  let lbl = mkCmmCodeLabel primUnitId lbl_txt-  addr <- cmmMakeDynamicReference config CallReference lbl-  let conv = ForeignConvention CCallConv [] [] CmmMayReturn-  genCCall bid addr conv dsts args---- | Generate C call to the given function in libc-genLibCCall-  :: BlockId-  -> FastString-  -> [CmmFormal]-  -> [CmmActual]-  -> NatM InstrBlock-genLibCCall bid lbl_txt dsts args = do-  config <- getConfig-  -- Assume we can call these functions directly, and that they're not in a dynamic library.-  -- TODO: Why is this ok? Under linux this code will be in libm.so-  --       Is it because they're really implemented as a primitive instruction by the assembler??  -- BL 2009/12/31-  let lbl = mkForeignLabel lbl_txt ForeignLabelInThisPackage IsFunction-  addr <- cmmMakeDynamicReference config CallReference lbl-  let conv = ForeignConvention CCallConv [] [] CmmMayReturn-  genCCall bid addr conv dsts args---- | Generate C call to the given function in the RTS-genRTSCCall-  :: BlockId-  -> FastString-  -> [CmmFormal]-  -> [CmmActual]-  -> NatM InstrBlock-genRTSCCall bid lbl_txt dsts args = do-  config <- getConfig-  -- Assume we can call these functions directly, and that they're not in a dynamic library.-  let lbl = mkForeignLabel lbl_txt ForeignLabelInThisPackage IsFunction-  addr <- cmmMakeDynamicReference config CallReference lbl-  let conv = ForeignConvention CCallConv [] [] CmmMayReturn-  genCCall bid addr conv dsts args---- | Generate a real C call to the given address with the given convention-genCCall-  :: BlockId-  -> CmmExpr-  -> ForeignConvention-  -> [CmmFormal]-  -> [CmmActual]-  -> NatM InstrBlock-genCCall bid addr conv@(ForeignConvention _ argHints _ _) dest_regs args = do-  platform <- getPlatform-  is32Bit <- is32BitPlatform-  let args_hints = zip args (argHints ++ repeat NoHint)-      prom_args = map (maybePromoteCArgToW32 platform) args_hints-  (instrs0, args') <- evalArgs bid prom_args-  instrs1 <- if is32Bit-    then genCCall32 addr conv dest_regs args'-    else genCCall64 addr conv dest_regs args'-  return (instrs0 `appOL` instrs1)--maybePromoteCArgToW32 :: Platform -> (CmmExpr, ForeignHint) -> CmmExpr-maybePromoteCArgToW32 platform (arg, hint)- | wfrom < wto =-    -- As wto=W32, we only need to handle integer conversions,-    -- never Float -> Double.-    case hint of-      SignedHint -> CmmMachOp (MO_SS_Conv wfrom wto) [arg]-      _          -> CmmMachOp (MO_UU_Conv wfrom wto) [arg]- | otherwise   = arg- where-   ty = cmmExprType platform arg-   wfrom = typeWidth ty-   wto = W32--genCCall32 :: CmmExpr           -- ^ address of the function to call-           -> ForeignConvention -- ^ calling convention-           -> [CmmFormal]       -- ^ where to put the result-           -> [CmmActual]       -- ^ arguments (of mixed type)-           -> NatM InstrBlock-genCCall32 addr _conv dest_regs args = do-        config <- getConfig-        let platform = ncgPlatform config--            -- If the size is smaller than the word, we widen things (see maybePromoteCArg)-            arg_size_bytes :: CmmType -> Int-            arg_size_bytes ty = max (widthInBytes (typeWidth ty)) (widthInBytes (wordWidth platform))--            roundTo a x | x `mod` a == 0 = x-                        | otherwise = x + a - (x `mod` a)--            push_arg :: CmmActual {-current argument-}-                            -> NatM InstrBlock  -- code--            push_arg  arg -- we don't need the hints on x86-              | isWord64 arg_ty = do-                RegCode64 code r_hi r_lo <- iselExpr64 arg-                delta <- getDeltaNat-                setDeltaNat (delta - 8)-                return (       code `appOL`-                               toOL [PUSH II32 (OpReg r_hi), DELTA (delta - 4),-                                     PUSH II32 (OpReg r_lo), DELTA (delta - 8),-                                     DELTA (delta-8)]-                    )--              | isFloatType arg_ty || isVecType arg_ty = do-                (reg, code) <- getSomeReg arg-                delta <- getDeltaNat-                setDeltaNat (delta-size)-                return (code `appOL`-                                toOL [SUB II32 (OpImm (ImmInt size)) (OpReg esp),-                                      DELTA (delta-size),-                                      let addr = AddrBaseIndex (EABaseReg esp)-                                                                EAIndexNone-                                                                (ImmInt 0)-                                          format = cmmTypeFormat arg_ty-                                      in--                                       movInstr config format (OpReg reg) (OpAddr addr)--                                     ]-                               )--              | otherwise = do-                -- Arguments can be smaller than 32-bit, but we still use @PUSH-                -- II32@ - the usual calling conventions expect integers to be-                -- 4-byte aligned.-                massert ((typeWidth arg_ty) <= W32)-                (operand, code) <- getOperand arg-                delta <- getDeltaNat-                setDeltaNat (delta-size)-                return (code `snocOL`-                        PUSH II32 operand `snocOL`-                        DELTA (delta-size))--              where-                 arg_ty = cmmExprType platform arg-                 size = arg_size_bytes arg_ty -- Byte size--        let-            -- Align stack to 16n for calls, assuming a starting stack-            -- alignment of 16n - word_size on procedure entry. Which we-            -- maintain. See Note [Stack Alignment on X86] in rts/StgCRun.c.-            sizes               = map (arg_size_bytes . cmmExprType platform) (reverse args)-            raw_arg_size        = sum sizes + platformWordSizeInBytes platform-            arg_pad_size        = (roundTo 16 $ raw_arg_size) - raw_arg_size-            tot_arg_size        = raw_arg_size + arg_pad_size - platformWordSizeInBytes platform---        delta0 <- getDeltaNat-        setDeltaNat (delta0 - arg_pad_size)--        push_codes <- mapM push_arg (reverse args)-        delta <- getDeltaNat-        massert (delta == delta0 - tot_arg_size)--        -- deal with static vs dynamic call targets-        callinsns <--          case addr of-            CmmLit (CmmLabel lbl)-               -> return $ unitOL (CALL (Left fn_imm) [])-               where fn_imm = ImmCLbl lbl-            _-               -> do { (dyn_r, dyn_c) <- getSomeReg addr-                     ; massert (isWord32 (cmmExprType platform addr))-                     ; return $ dyn_c `snocOL` CALL (Right dyn_r) [] }-        let push_code-                | arg_pad_size /= 0-                = toOL [SUB II32 (OpImm (ImmInt arg_pad_size)) (OpReg esp),-                        DELTA (delta0 - arg_pad_size)]-                  `appOL` concatOL push_codes-                | otherwise-                = concatOL push_codes--            call = callinsns `appOL`-                   toOL (-                      (if tot_arg_size == 0 then [] else-                       [ADD II32 (OpImm (ImmInt tot_arg_size)) (OpReg esp)])-                      ++-                      [DELTA delta0]-                   )-        setDeltaNat delta0--        let-            -- assign the results, if necessary-            assign_code []     = nilOL-            assign_code [dest]-              | isVecType ty-              = unitOL (mkRegRegMoveInstr config (cmmTypeFormat ty) xmm0 r_dest)-              | isFloatType ty =-                  -- we assume SSE2-                  let tmp_amode = AddrBaseIndex (EABaseReg esp)-                                                       EAIndexNone-                                                       (ImmInt 0)-                      fmt = floatFormat w-                         in toOL [ SUB II32 (OpImm (ImmInt b)) (OpReg esp),-                                   DELTA (delta0 - b),-                                   X87Store fmt  tmp_amode,-                                   -- X87Store only supported for the CDECL ABI-                                   -- NB: This code will need to be-                                   -- revisited once GHC does more work around-                                   -- SIGFPE f-                                   MOV fmt (OpAddr tmp_amode) (OpReg r_dest),-                                   ADD II32 (OpImm (ImmInt b)) (OpReg esp),-                                   DELTA delta0]-              | isWord64 ty    = toOL [MOV II32 (OpReg eax) (OpReg r_dest),-                                        MOV II32 (OpReg edx) (OpReg r_dest_hi)]-              | otherwise      = unitOL (MOV (intFormat w)-                                             (OpReg eax)-                                             (OpReg r_dest))-              where-                    ty = localRegType dest-                    w  = typeWidth ty-                    b  = widthInBytes w-                    r_dest_hi = getHiVRegFromLo r_dest-                    r_dest    = getLocalRegReg dest-            assign_code many = pprPanic "genForeignCall.assign_code - too many return values:" (ppr many)--        return (push_code `appOL`-                call `appOL`-                assign_code dest_regs)--genCCall64 :: CmmExpr           -- ^ address of function to call-           -> ForeignConvention -- ^ calling convention-           -> [CmmFormal]       -- ^ where to put the result-           -> [CmmActual]       -- ^ arguments (of mixed type)-           -> NatM InstrBlock-genCCall64 addr conv dest_regs args = do-    config <- getConfig-    let platform = ncgPlatform config-        word_size = platformWordSizeInBytes platform-        wordFmt = archWordFormat (target32Bit platform)--    -- Compute the code for loading arguments into registers,-    -- returning the leftover arguments that will need to be passed on the stack.-    ---    -- NB: the code for loading references to data into registers is computed-    -- later (in 'pushArgs'), because we don't yet know where the data will be-    -- placed (due to alignment requirements).-    LoadArgs-      { stackArgs       = proper_stack_args-      , stackDataArgs   = stack_data_args-      , usedRegs        = arg_regs_used-      , assignArgsCode  = assign_args_code-      }-      <- loadArgs config args--    let--    -- Pad all arguments and data passed on stack to align them properly.-        (stk_args_with_padding, args_aligned_16) =-          padStackArgs platform (proper_stack_args, stack_data_args)--    -- Align stack to 16n for calls, assuming a starting stack-    -- alignment of 16n - word_size on procedure entry. Which we-    -- maintain. See Note [Stack Alignment on X86] in rts/StgCRun.c-        need_realign_call = args_aligned_16-    align_call_code <--      if need_realign_call-      then addStackPadding word_size-      else return nilOL--    -- Compute the code that pushes data to the stack, and also-    -- the code that loads references to that data into registers,-    -- when the data is passed by reference in a register.-    (load_data_refs, push_code) <--      pushArgs config proper_stack_args stk_args_with_padding--    -- On Windows, leave stack space for the arguments that we are passing-    -- in registers (the so-called shadow space).-    let shadow_space =-          if platformOS platform == OSMinGW32-          then 8 * length (allArgRegs platform)-            -- NB: the shadow store is always 8 * 4 = 32 bytes large,-            -- i.e. the cumulative size of rcx, rdx, r8, r9 (see 'allArgRegs').-          else 0-    shadow_space_code <- addStackPadding shadow_space--    let total_args_size-          = shadow_space-          + sum (map (stackArgSpace platform) stk_args_with_padding)-        real_size =-          total_args_size + if need_realign_call then word_size else 0--    -- End of argument passing.-    ---    -- Next step: emit the appropriate call instruction.-    delta <- getDeltaNat--    let -- The System V AMD64 ABI requires us to set %al to the number of SSE2-        -- registers that contain arguments, if the called routine-        -- is a varargs function.  We don't know whether it's a-        -- varargs function or not, so we have to assume it is.-        ---        -- It's not safe to omit this assignment, even if the number-        -- of SSE2 regs in use is zero.  If %al is larger than 8-        -- on entry to a varargs function, seg faults ensue.-        is_sse_reg (RegWithFormat r _) =-          -- NB: use 'targetClassOfRealReg' to compute whether this is an SSE-          -- register or not, as we may have decided to e.g. store a 64-bit-          -- integer in an xmm register.-          case targetClassOfReg platform r of-            RcFloatOrVector -> True-            RcInteger       -> False-        nb_sse_regs_used = count is_sse_reg arg_regs_used-        assign_eax_sse_regs-          = unitOL (MOV II32 (OpImm (ImmInt nb_sse_regs_used)) (OpReg eax))-          -- Note: we do this on Windows as well. It's not entirely clear why-          -- it's needed (the Windows X86_64 calling convention does not-          -- dictate it), but we get segfaults without it.-          ---          -- One test case exhibiting the issue is T20030_test1j;-          -- if you change this, make sure to run it in a loop for a while-          -- with at least -j8 to check.--        -- Live registers we are annotating the call instruction with-        arg_regs = [RegWithFormat eax wordFmt] ++ arg_regs_used--    -- deal with static vs dynamic call targets-    (callinsns,_cconv) <- case addr of-      CmmLit (CmmLabel lbl) ->-        return (unitOL (CALL (Left (ImmCLbl lbl)) arg_regs), conv)-      _ -> do-        (dyn_r, dyn_c) <- getSomeReg addr-        return (dyn_c `snocOL` CALL (Right dyn_r) arg_regs, conv)--    let call = callinsns `appOL`-               toOL (-                    -- Deallocate parameters after call for ccall-                  (if real_size==0 then [] else-                   [ADD (intFormat (platformWordWidth platform)) (OpImm (ImmInt real_size)) (OpReg esp)])-                  ++-                  [DELTA (delta + real_size)]-               )-    setDeltaNat (delta + real_size)--    let-        -- assign the results, if necessary-        assign_code []     = nilOL-        assign_code [dest] =-          unitOL $-            mkRegRegMoveInstr config fmt reg r_dest-          where-            reg = if isIntFormat fmt then rax else xmm0-            fmt = cmmTypeFormat rep-            rep = localRegType dest-            r_dest = getRegisterReg platform (CmmLocal dest)-        assign_code _many = panic "genForeignCall.assign_code many"--    return (align_call_code     `appOL`-            push_code           `appOL`-            assign_args_code    `appOL`-            load_data_refs      `appOL`-            shadow_space_code   `appOL`-            assign_eax_sse_regs `appOL`-            call                `appOL`-            assign_code dest_regs)---- -------------------------------------------------------------------------------- Loading arguments into registers for 64-bit C calls.---- | Information needed to know how to pass arguments in a C call,--- and in particular how to load them into registers.-data LoadArgs-  = LoadArgs-  -- | Arguments that should be passed on the stack-  { stackArgs     :: [RawStackArg]-  -- | Additional values to store onto the stack.-  , stackDataArgs :: [CmmExpr]-  -- | Which registers are we using for argument passing?-  , usedRegs      :: [RegWithFormat]-  -- | The code to assign arguments to registers used for argument passing.-  , assignArgsCode :: InstrBlock-  }-instance Semigroup LoadArgs where-  LoadArgs a1 d1 r1 j1 <> LoadArgs a2 d2 r2 j2-    = LoadArgs (a1 ++ a2) (d1 ++ d2) (r1 ++ r2) (j1 S.<> j2)-instance Monoid LoadArgs where-  mempty = LoadArgs [] [] [] nilOL---- | An argument passed on the stack, either directly or by reference.------ The padding information hasn't yet been computed (see 'StackArg').-data RawStackArg-  -- | Pass the argument on the stack directly.-  = RawStackArg { stackArgExpr :: CmmExpr }-  -- | Pass the argument by reference.-  | RawStackArgRef-    { stackRef :: StackRef-       -- ^ is the reference passed in a register, or on the stack?-    , stackRefArgSize :: Int-        -- ^ the size of the data pointed to-    }-  deriving ( Show )---- | An argument passed on the stack, either directly or by reference,--- with additional padding information.-data StackArg-  -- | Pass the argument on the stack directly.-  = StackArg-      { stackArgExpr :: CmmExpr-      , stackArgPadding :: Int-        -- ^ padding required (in bytes)-      }-  -- | Pass the argument by reference.-  | StackArgRef-     { stackRef :: StackRef-        -- ^ where the reference is passed-     , stackRefArgSize :: Int-        -- ^ the size of the data pointed to-     , stackRefArgPadding :: Int-       -- ^ padding of the data pointed to-       -- (the reference itself never requires padding)-     }-  deriving ( Show )---- | Where is a reference to data on the stack passed?-data StackRef-  -- | In a register.-  = InReg Reg-  -- | On the stack.-  | OnStack-  deriving ( Eq, Ord, Show )--newtype Padding = Padding { paddingBytes :: Int }-  deriving ( Show, Eq, Ord )---- | How much space does this 'StackArg' take up on the stack?------ Only counts the "reference" part for references, not the data it points to.-stackArgSpace :: Platform -> StackArg -> Int-stackArgSpace platform = \case-  StackArg arg padding ->-    argSize platform arg + padding-  StackArgRef { stackRef = ref } ->-    case ref of-      InReg   {} -> 0-      OnStack {} -> 8---- | Pad arguments, assuming we start aligned to a 16-byte boundary.------ Returns padded arguments, together with whether we end up aligned--- to a 16-byte boundary.-padStackArgs :: Platform-             -> ([RawStackArg], [CmmExpr])-             -> ([StackArg], Bool)-padStackArgs platform (args0, data_args0) =-  let-    -- Pad the direct args-    (args, align_16_mid) = pad_args True args0--    -- Pad the data section-    (data_args, align_16_end) = pad_args align_16_mid (map RawStackArg data_args0)--    -- Now figure out where the data is placed relative to the direct arguments,-    -- in order to resolve references.-    resolve_args :: [(RawStackArg, Padding)] -> [Padding] -> [StackArg]-    resolve_args [] _ = []-    resolve_args ((stk_arg, Padding pad):rest) pads =-      let (this_arg, pads') =-            case stk_arg of-              RawStackArg arg -> (StackArg arg pad, pads)-              RawStackArgRef ref size ->-                let (Padding arg_pad : rest_pads) = pads-                    arg =-                      StackArgRef-                        { stackRef = ref-                        , stackRefArgSize = size-                        , stackRefArgPadding = arg_pad }-                in (arg, rest_pads)-      in this_arg : resolve_args rest pads'--  in-    ( resolve_args args (fmap snd data_args) ++-        [ case data_arg of-            RawStackArg arg -> StackArg arg pad-            RawStackArgRef {} -> panic "padStackArgs: reference in data section"-        | (data_arg, Padding pad) <- data_args-        ]-    , align_16_end )--  where-    pad_args :: Bool -> [RawStackArg] -> ([(RawStackArg, Padding)], Bool)-    pad_args aligned_16 [] = ([], aligned_16)-    pad_args aligned_16 (arg:args)-      | needed_alignment > 16-      -- We don't know if the stack is aligned to 8 (mod 32) or 24 (mod 32).-      -- This makes aligning the stack to a 32 or 64 byte boundary more-      -- complicated, in particular with DELTA.-      = sorry $ unlines-        [ "X86_86 C call: unsupported argument."-        , "  Alignment requirement: " ++ show needed_alignment ++ " bytes."-        , if platformOS platform == OSMinGW32-          then "  The X86_64 NCG does not (yet) support Windows C calls with 256/512 bit vectors."-          else "  The X86_64 NCG cannot (yet) pass 256/512 bit vectors on the stack for C calls."-        , "  Please use the LLVM backend (-fllvm)." ]-      | otherwise-      = let ( rest, final_align_16 ) = pad_args next_aligned_16 args-        in  ( (arg, Padding padding) : rest, final_align_16 )--      where-        needed_alignment = case arg of-          RawStackArg arg   -> argSize platform arg-          RawStackArgRef {} -> platformWordSizeInBytes platform-        padding-          | needed_alignment < 16 || aligned_16-          = 0-          | otherwise-          = 8-        next_aligned_16 = not ( aligned_16 && needed_alignment < 16 )---- | Load arguments into available registers.-loadArgs :: NCGConfig -> [CmmExpr] -> NatM LoadArgs-loadArgs config args-  | platformOS platform == OSMinGW32-  = evalStateT (loadArgsWin config args) (allArgRegs platform)-  | otherwise-  = evalStateT (loadArgsSysV config args) (allIntArgRegs platform-                                          ,allFPArgRegs  platform)-  where-    platform = ncgPlatform config---- | Load arguments into available registers (System V AMD64 ABI).-loadArgsSysV :: NCGConfig-             -> [CmmExpr]-             -> StateT ([Reg], [Reg]) NatM LoadArgs-loadArgsSysV _ [] = return mempty-loadArgsSysV config (arg:rest) = do-  (iregs, fregs) <- get-  -- No available registers: pass everything on the stack (shortcut).-  if null iregs && null fregs-  then return $-          LoadArgs-            { stackArgs       = map RawStackArg (arg:rest)-            , stackDataArgs   = []-            , assignArgsCode  = nilOL-            , usedRegs        = []-            }-  else do-    mbReg <--      if-        | isIntFormat arg_fmt-        , ireg:iregs' <- iregs-        -> do put (iregs', fregs)-              return $ Just ireg-        | isFloatFormat arg_fmt || isVecFormat arg_fmt-        , freg:fregs' <- fregs-        -> do put (iregs, fregs')-              return $ Just freg-        | otherwise-        -> return Nothing-    this_arg <--      case mbReg of-        Just reg -> do-          assign_code <- lift $ loadArgIntoReg arg reg-          return $-            LoadArgs-                { stackArgs       = [] -- passed in register-                , stackDataArgs   = []-                , assignArgsCode  = assign_code-                , usedRegs        = [RegWithFormat reg arg_fmt]-                }-        Nothing -> do-          return $-            -- No available register for this argument: pass it on the stack.-            LoadArgs-                { stackArgs       = [RawStackArg arg]-                , stackDataArgs   = []-                , assignArgsCode  = nilOL-                , usedRegs        = []-                }-    others <- loadArgsSysV config rest-    return $ this_arg S.<> others--  where-    platform = ncgPlatform config-    arg_fmt = cmmTypeFormat (cmmExprType platform arg)---- | Compute all things that will need to be pushed to the stack.------ On Windows, an argument passed by reference will require two pieces of data:------  - the reference (returned in the first position)---  - the actual data (returned in the second position)-computeWinPushArgs :: Platform -> [CmmExpr] -> ([RawStackArg], [CmmExpr])-computeWinPushArgs platform = go-  where-    go :: [CmmExpr] -> ([RawStackArg], [CmmExpr])-    go [] = ([], [])-    go (arg:args) =-      let-        arg_size = argSize platform arg-        (this_arg, add_this_arg)-          | arg_size > 8-          = ( RawStackArgRef OnStack arg_size, (arg :) )-          | otherwise-          = ( RawStackArg arg, id )-        (stk_args, stk_data) = go args-      in-        (this_arg:stk_args, add_this_arg stk_data)---- | Load arguments into available registers (Windows C X64 calling convention).-loadArgsWin :: NCGConfig -> [CmmExpr] -> StateT [(Reg,Reg)] NatM LoadArgs-loadArgsWin _ [] = return mempty-loadArgsWin config (arg:rest) = do-  regs <- get-  case regs of-    reg:regs' -> do-      put regs'-      this_arg <- lift $ load_arg_win reg-      rest <- loadArgsWin config rest-      return $ this_arg S.<> rest-    [] -> do-      -- No more registers available: pass all (remaining) arguments on the stack.-      let (stk_args, data_args) = computeWinPushArgs platform (arg:rest)-      return $-        LoadArgs-          { stackArgs       = stk_args-          , stackDataArgs   = data_args-          , assignArgsCode  = nilOL-          , usedRegs        = []-          }-  where-    platform = ncgPlatform config-    arg_fmt = cmmTypeFormat $ cmmExprType platform arg-    load_arg_win (ireg, freg)-      | isVecFormat arg_fmt-       -- Vectors are passed by reference.-       -- See Note [The Windows X64 C calling convention].-      = do return $-             LoadArgs-                -- Pass the reference in a register,-                -- and the argument data on the stack.-                { stackArgs       = [RawStackArgRef (InReg ireg) (argSize platform arg)]-                , stackDataArgs   = [arg] -- we don't yet know where the data will reside,-                , assignArgsCode  = nilOL -- so we defer computing the reference and storing it-                                          -- in the register until later-                , usedRegs        = [RegWithFormat ireg II64]-                }-      | otherwise-      = do let arg_reg-                  | isFloatFormat arg_fmt-                  = freg-                  | otherwise-                  = ireg-           assign_code <- loadArgIntoReg arg arg_reg-           -- Recall that, for varargs, we must pass floating-point-           -- arguments in both fp and integer registers.-           let (assign_code', regs')-                | isFloatFormat arg_fmt =-                    ( assign_code `snocOL` MOVD FF64 II64 (OpReg freg) (OpReg ireg),-                      [ RegWithFormat freg FF64-                      , RegWithFormat ireg II64 ])-                | otherwise = (assign_code, [RegWithFormat ireg II64])-           return $-             LoadArgs-               { stackArgs       = [] -- passed in register-               , stackDataArgs   = []-               , assignArgsCode = assign_code'-               , usedRegs = regs'-               }---- | Load an argument into a register.------ Assumes that the expression does not contain any MachOps,--- as per Note [Evaluate C-call arguments before placing in destination registers].-loadArgIntoReg :: CmmExpr -> Reg -> NatM InstrBlock-loadArgIntoReg arg reg = do-  when (debugIsOn && loadIntoRegMightClobberOtherReg arg) $ do-    platform <- getPlatform-    massertPpr False $-      vcat [ text "loadArgIntoReg: arg might contain MachOp"-           , text "arg:" <+> pdoc platform arg ]-  arg_code <- getAnyReg arg-  return $ arg_code reg---- -------------------------------------------------------------------------------- Pushing arguments onto the stack for 64-bit C calls.---- | The size of an argument (in bytes).------ Never smaller than the platform word width.-argSize :: Platform -> CmmExpr -> Int-argSize platform arg =-  max (platformWordSizeInBytes platform) $-    widthInBytes (typeWidth $ cmmExprType platform arg)---- | Add the given amount of padding on the stack.-addStackPadding :: Int -- ^ padding (in bytes)-                -> NatM InstrBlock-addStackPadding pad_bytes-  | pad_bytes == 0-  = return nilOL-  | otherwise-  = do delta <- getDeltaNat-       setDeltaNat (delta - pad_bytes)-       return $-         toOL [ SUB II64 (OpImm (ImmInt pad_bytes)) (OpReg rsp)-              , DELTA (delta - pad_bytes)-              ]---- | Push one argument directly to the stack (by value).------ Assumes the current stack pointer fulfills any necessary alignment requirements.-pushArgByValue :: NCGConfig -> CmmExpr -> NatM InstrBlock-pushArgByValue config arg-   -- For 64-bit integer arguments, use PUSH II64.-   ---   -- Note: we *must not* do this for smaller arguments.-   -- For example, if we tried to push an argument such as @CmmLoad addr W32 aln@,-   -- we could end up reading unmapped memory and segfaulting.-   | isIntFormat fmt-   , formatInBytes fmt == 8-   = do-     (arg_op, arg_code) <- getOperand arg-     delta <- getDeltaNat-     setDeltaNat (delta-arg_size)-     return $-       arg_code `appOL` toOL-       [ PUSH II64 arg_op-       , DELTA (delta-arg_size) ]--   | otherwise-   = do-     (arg_reg, arg_code) <- getSomeReg arg-     delta <- getDeltaNat-     setDeltaNat (delta-arg_size)-     return $ arg_code `appOL` toOL-        [ SUB (intFormat (wordWidth platform)) (OpImm (ImmInt arg_size)) (OpReg rsp)-        , DELTA (delta-arg_size)-        , movInstr config fmt (OpReg arg_reg) (OpAddr (spRel platform 0)) ]--    where-      platform = ncgPlatform config-      arg_size = argSize platform arg-      arg_rep = cmmExprType platform arg-      fmt = cmmTypeFormat arg_rep---- | Load an argument into a register or push it to the stack.-loadOrPushArg :: NCGConfig -> (StackArg, Maybe Int) -> NatM (InstrBlock, InstrBlock)-loadOrPushArg config (stk_arg, mb_off) =-  case stk_arg of-    StackArg arg pad -> do-      push_code <- pushArgByValue config arg-      pad_code  <- addStackPadding pad-      return (nilOL, push_code `appOL` pad_code)-    StackArgRef { stackRef = ref } ->-      case ref of-        -- Pass the reference in a register-        InReg ireg ->-          return (unitOL $ LEA II64 (OpAddr (spRel platform off)) (OpReg ireg), nilOL)-        -- Pass the reference on the stack-        OnStack {} -> do-          tmp <- getNewRegNat II64-          delta <- getDeltaNat-          setDeltaNat (delta-arg_ref_size)-          let push_code = toOL-                [ SUB (intFormat (wordWidth platform)) (OpImm (ImmInt arg_ref_size)) (OpReg rsp)-                , DELTA (delta-arg_ref_size)-                , LEA II64 (OpAddr (spRel platform off)) (OpReg tmp)-                , MOV II64 (OpReg tmp) (OpAddr (spRel platform 0)) ]-          return (nilOL, push_code)-      where off = expectJust "push_arg_win offset" mb_off-    where-      arg_ref_size = 8 -- passing a reference to the argument-      platform = ncgPlatform config---- | Push arguments to the stack, right to left.------ On Windows, some arguments may need to be passed by reference,--- which requires separately passing the data and the reference.--- See Note [The Windows X64 C calling convention].-pushArgs :: NCGConfig-         -> [RawStackArg]-            -- ^ arguments proper (i.e. don't include the data for arguments passed by reference)-         -> [StackArg]-            -- ^ arguments we are passing on the stack-         -> NatM (InstrBlock, InstrBlock)-pushArgs config proper_args all_stk_args-  = do { let-            vec_offs :: [Maybe Int]-            vec_offs-              | platformOS platform == OSMinGW32-              = go stack_arg_size all_stk_args-              | otherwise-              = repeat Nothing--    ----------------------    -- Windows-only code--            -- Size of the arguments we are passing on the stack, counting only-            -- the reference part for arguments passed by reference.-            stack_arg_size = 8 * count not_in_reg proper_args-            not_in_reg (RawStackArg {}) = True-            not_in_reg (RawStackArgRef { stackRef = ref }) =-              case ref of-                InReg {} -> False-                OnStack {} -> True--            -- Check an offset is valid (8-byte aligned), for assertions.-            ok off = off `rem` 8 == 0--            -- Tricky code: compute the stack offset to the vector data-            -- for this argument.-            ---            -- If you're confused, Note [The Windows X64 C calling convention]-            -- contains a helpful diagram.-            go :: Int -> [StackArg] -> [Maybe Int]-            go _ [] = []-            go off (stk_arg:args) =-              assertPpr (ok off) (text "unaligned offset:" <+> ppr off) $-              case stk_arg of-                StackArg {} ->-                  -- Only account for the stack pointer movement.-                  let off' = off - stackArgSpace platform stk_arg-                  in Nothing : go off' args-                StackArgRef-                  { stackRefArgSize    = data_size-                  , stackRefArgPadding = data_pad } ->-                  assertPpr (ok data_size) (text "unaligned data size:" <+> ppr data_size) $-                  assertPpr (ok data_pad) (text "unaligned data padding:" <+> ppr data_pad) $-                  let off' = off-                        -- Next piece of data is after the data for this reference-                           + data_size + data_pad-                        -- ... and account for the stack pointer movement.-                           - stackArgSpace platform stk_arg-                  in Just (data_pad + off) : go off' args--    -- end of Windows-only code-    ------------------------------         -- Push the stack arguments (right to left),-         -- including both the reference and the data for arguments passed by reference.-       ; (load_regs, push_args) <- foldMapM (loadOrPushArg config) (reverse $ zip all_stk_args vec_offs)-       ; return (load_regs, push_args) }-  where-    platform = ncgPlatform config--{- Note [The Windows X64 C calling convention]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-Here are a few facts about the Windows X64 C calling convention that-are important:--  - any argument larger than 8 bytes must be passed by reference,-    and arguments smaller than 8 bytes are padded to 8 bytes.--  - the first four arguments are passed in registers:-      - floating-point scalar arguments are passed in %xmm0, %xmm1, %xmm2, %xmm3-      - other arguments are passed in %rcx, %rdx, %r8, %r9-        (this includes vector arguments, passed by reference)--    For variadic functions, it is additionally expected that floating point-    scalar arguments are copied to the corresponding integer register, e.g.-    the data in xmm2 should also be copied to r8.--    There is no requirement about setting %al like there is for the-    System V AMD64 ABI.--  - subsequent arguments are passed on the stack.--There are also alignment requirements:--  - the data for vectors must be aligned to the size of the vector,-    e.g. a 32 byte vector must be aligned on a 32 byte boundary,--  - the call instruction must be aligned to 16 bytes.-  (This differs from the System V AMD64 ABI, which mandates that the call-  instruction must be aligned to 32 bytes if there are any 32 byte vectors-  passed on the stack.)--This motivates our handling of vector values. Suppose we have a function call-with many arguments, several of them being vectors. We proceed as follows:-- - Add some padding, if necessary, to ensure the stack, when executing the call-    instruction, is 16-byte aligned. Whether this padding is necessary depends-    on what happens next. (Recall also that we start off at 8 (mod 16) alignment,-    as per Note [Stack Alignment on X86] in rts/StgCRun.c)-  - Push all the vectors to the stack first, adding padding after each one-    if necessary.-  - Then push the arguments:-      - for non-vectors, proceed as usual,-      - for vectors, push the address of the vector data we pushed above.-  - Then assign the registers:-      - for non-vectors, proceed as usual,-      - for vectors, store the address in a general-purpose register, as opposed-        to storing the data in an xmm register.--For a concrete example, suppose we have a call of the form:--  f x1 x2 x3 x4 x5 x6 x7--in which:--  - x2, x3, x5 and x7 are 16 byte vectors-  - the other arguments are all 8 byte wide--Now, x1, x2, x3, x4 will get passed in registers, except that we pass-x2 and x3 by reference, because they are vectors. We proceed as follows:--  - push the vectors to the stack: x7, x5, x3, x2 (in that order)-  - push the stack arguments in order: addr(x7), x6, addr(x5)-  - load the remaining arguments into registers: x4, addr(x3), addr(x2), x1--The tricky part is to get the right offsets for the addresses of the vector-data. The following visualisation will hopefully clear things up:--                                  ┌──┐-                                  │▓▓│ ─── padding to align the call instruction-                      ╭─╴         ╞══╡     (ensures Sp, below, is 16-byte aligned)-                      │           │  │-                      │  x7  ───╴ │  │-                      │           ├──┤-                      │           │  │-                      │  x5  ───╴ │  │-                      │           ├──┤-     vector data  ────┤           │  │-(individually padded) │  x3  ───╴ │  │-                      │           ├──┤-                      │           │  │-                      │  x2  ───╴ │  │-                      │           ├┄┄┤-                      │           │▓▓│ ─── padding to align x2 to 16 bytes-               ╭─╴    ╰─╴         ╞══╡-               │    addr(x7) ───╴ │  │    ╭─ from here: x7 is +64-               │                  ├──┤ ╾──╯    = 64 (position of x5)-     stack  ───┤         x6  ───╴ │  │         + 16 (size of x5) + 0 (padding of x7)-   arguments   │                  ├──┤         - 2 * 8 (x7 is 2 arguments higher than x5)-               │    addr(x5) ───╴ │  │-               ╰─╴            ╭─╴ ╞══╡ ╾─── from here:-                              │   │  │       - x2 is +32 = 24 (stack_arg_size) + 8 (padding of x2)-                   shadow  ───┤   │  │       - x3 is +48 = 32 (position of x2) + 16 (size of x2) + 0 (padding of x3)-                    space     │   │  │       - x5 is +64 = 48 (position of x3) + 16 (size of x3) + 0 (padding of x5)-                              │   │  │-                              ╰─╴ └──┘ ╾─── Sp--This is all tested in the simd013 test.--}---- -------------------------------------------------------------------------------- Generating a table-branch--{--Note [Sub-word subtlety during jump-table indexing]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-Offset the index by the start index of the jump table.-It's important that we do this *before* the widening below. To see-why, consider a switch with a sub-word, signed discriminant such as:--    switch [-5...+2] x::I16 {-        case -5: ...-        ...-        case +2: ...-    }--Consider what happens if we offset *after* widening in the case that-x=-4:--                                         // x == -4 == 0xfffc::I16-    indexWidened = UU_Conv(x);           // == 0xfffc::I64-    indexExpr    = indexWidened - (-5);  // == 0x10000::I64--This index is clearly nonsense given that the jump table only has-eight entries.--By contrast, if we widen *after* we offset then we get the correct-index (1),--                                         // x == -4 == 0xfffc::I16-    indexOffset  = x - (-5);             // == 1::I16-    indexExpr    = UU_Conv(indexOffset); // == 1::I64--See #21186.--}--genSwitch :: CmmExpr -> SwitchTargets -> NatM InstrBlock--genSwitch expr targets = do-  config <- getConfig-  let platform = ncgPlatform config-      expr_w = cmmExprWidth platform expr-      indexExpr0 = cmmOffset platform expr offset-      -- We widen to a native-width register because we cannot use arbitrary sizes-      -- in x86 addressing modes.-      -- See Note [Sub-word subtlety during jump-table indexing].-      indexExpr = CmmMachOp-        (MO_UU_Conv expr_w (platformWordWidth platform))-        [indexExpr0]-  if ncgPIC config-  then do-        (reg,e_code) <- getNonClobberedReg indexExpr-           -- getNonClobberedReg because it needs to survive across t_code-        lbl <- getNewLabelNat-        let is32bit = target32Bit platform-            os = platformOS platform-            -- Might want to use .rodata.<function we're in> instead, but as-            -- long as it's something unique it'll work out since the-            -- references to the jump table are in the appropriate section.-            rosection = case os of-              -- on Mac OS X/x86_64, put the jump table in the text section to-              -- work around a limitation of the linker.-              -- ld64 is unable to handle the relocations for-              --     .quad L1 - L0-              -- if L0 is not preceded by a non-anonymous label in its section.-              OSDarwin | not is32bit -> Section Text lbl-              _ -> Section ReadOnlyData lbl-        dynRef <- cmmMakeDynamicReference config DataReference lbl-        (tableReg,t_code) <- getSomeReg $ dynRef-        let op = OpAddr (AddrBaseIndex (EABaseReg tableReg)-                                       (EAIndex reg (platformWordSizeInBytes platform)) (ImmInt 0))--        return $ e_code `appOL` t_code `appOL` toOL [-                                ADD (intFormat (platformWordWidth platform)) op (OpReg tableReg),-                                JMP_TBL (OpReg tableReg) ids rosection lbl-                       ]-  else do-        (reg,e_code) <- getSomeReg indexExpr-        lbl <- getNewLabelNat-        let is32bit = target32Bit platform-        if is32bit-          then let op = OpAddr (AddrBaseIndex EABaseNone (EAIndex reg (platformWordSizeInBytes platform)) (ImmCLbl lbl))-                   jmp_code = JMP_TBL op ids (Section ReadOnlyData lbl) lbl-               in return $ e_code `appOL` unitOL jmp_code-          else do-            -- See Note [%rip-relative addressing on x86-64].-            tableReg <- getNewRegNat (intFormat (platformWordWidth platform))-            targetReg <- getNewRegNat (intFormat (platformWordWidth platform))-            let op = OpAddr (AddrBaseIndex (EABaseReg tableReg) (EAIndex reg (platformWordSizeInBytes platform)) (ImmInt 0))-                fmt = archWordFormat is32bit-                code = e_code `appOL` toOL-                    [ LEA fmt (OpAddr (AddrBaseIndex EABaseRip EAIndexNone (ImmCLbl lbl))) (OpReg tableReg)-                    , MOV fmt op (OpReg targetReg)-                    , JMP_TBL (OpReg targetReg) ids (Section ReadOnlyData lbl) lbl-                    ]-            return code-  where-    (offset, blockIds) = switchTargetsToTable targets-    ids = map (fmap DestBlockId) blockIds--generateJumpTableForInstr :: NCGConfig -> Instr -> Maybe (NatCmmDecl (Alignment, RawCmmStatics) Instr)-generateJumpTableForInstr config (JMP_TBL _ ids section lbl)-    = let getBlockId (DestBlockId id) = id-          getBlockId _ = panic "Non-Label target in Jump Table"-          blockIds = map (fmap getBlockId) ids-      in Just (createJumpTable config blockIds section lbl)-generateJumpTableForInstr _ _ = Nothing--createJumpTable :: NCGConfig -> [Maybe BlockId] -> Section -> CLabel-                -> GenCmmDecl (Alignment, RawCmmStatics) h g-createJumpTable config ids section lbl-    = let jumpTable-            | ncgPIC config =-                  let ww = ncgWordWidth config-                      jumpTableEntryRel Nothing-                          = CmmStaticLit (CmmInt 0 ww)-                      jumpTableEntryRel (Just blockid)-                          = CmmStaticLit (CmmLabelDiffOff blockLabel lbl 0 ww)-                          where blockLabel = blockLbl blockid-                  in map jumpTableEntryRel ids-            | otherwise = map (jumpTableEntry config) ids-      in CmmData section (mkAlignment 1, CmmStaticsRaw lbl jumpTable)--extractUnwindPoints :: [Instr] -> [UnwindPoint]-extractUnwindPoints instrs =-    [ UnwindPoint lbl unwinds | UNWIND lbl unwinds <- instrs]---- -------------------------------------------------------------------------------- 'condIntReg' and 'condFltReg': condition codes into registers---- Turn those condition codes into integers now (when they appear on--- the right hand side of an assignment).------ (If applicable) Do not fill the delay slots here; you will confuse the--- register allocator.--condIntReg :: Cond -> CmmExpr -> CmmExpr -> NatM Register--condIntReg cond x y = do-  CondCode _ cond cond_code <- condIntCode cond x y-  tmp <- getNewRegNat II8-  let-        code dst = cond_code `appOL` toOL [-                    SETCC cond (OpReg tmp),-                    MOVZxL II8 (OpReg tmp) (OpReg dst)-                  ]-  return (Any II32 code)----- Note [SSE Parity Checks]--- ~~~~~~~~~~~~~~~~~~~~~~~~--- We have to worry about unordered operands (eg. comparisons--- against NaN).  If the operands are unordered, the comparison--- sets the parity flag, carry flag and zero flag.--- All comparisons are supposed to return false for unordered--- operands except for !=, which returns true.------ Optimisation: we don't have to test the parity flag if we--- know the test has already excluded the unordered case: eg >--- and >= test for a zero carry flag, which can only occur for--- ordered operands.------ By reversing comparisons we can avoid testing the parity--- for < and <= as well. If any of the arguments is an NaN we--- return false either way. If both arguments are valid then--- x <= y  <->  y >= x  holds. So it's safe to swap these.------ We invert the condition inside getRegister'and  getCondCode--- which should cover all invertable cases.--- All other functions translating FP comparisons to assembly--- use these to two generate the comparison code.------ As an example consider a simple check:------ func :: Float -> Float -> Int--- func x y = if x < y then 1 else 0------ Which in Cmm gives the floating point comparison.------  if (%MO_F_Lt_W32(F1, F2)) goto c2gg; else goto c2gf;------ We used to compile this to an assembly code block like this:--- _c2gh:---  ucomiss %xmm2,%xmm1---  jp _c2gf---  jb _c2gg---  jmp _c2gf------ Where we have to introduce an explicit--- check for unordered results (using jmp parity):------ We can avoid this by exchanging the arguments and inverting the direction--- of the comparison. This results in the sequence of:------  ucomiss %xmm1,%xmm2---  ja _c2g2---  jmp _c2g1------ Removing the jump reduces the pressure on the branch prediction system--- and plays better with the uOP cache.--condFltReg :: Bool -> Cond -> CmmExpr -> CmmExpr -> NatM Register-condFltReg is32Bit cond x y = condFltReg_sse2- where---  condFltReg_sse2 = do-    CondCode _ cond cond_code <- condFltCode cond x y-    tmp1 <- getNewRegNat (archWordFormat is32Bit)-    tmp2 <- getNewRegNat (archWordFormat is32Bit)-    let -- See Note [SSE Parity Checks]-        code dst =-           cond_code `appOL`-             (case cond of-                NE  -> or_unordered dst-                GU  -> plain_test   dst-                GEU -> plain_test   dst-                -- Use ASSERT so we don't break releases if these creep in.-                LTT -> assertPpr False (text "Should have been turned into >") $-                       and_ordered  dst-                LE  -> assertPpr False (text "Should have been turned into >=") $-                       and_ordered  dst-                _   -> and_ordered  dst)--        plain_test dst = toOL [-                    SETCC cond (OpReg tmp1),-                    MOVZxL II8 (OpReg tmp1) (OpReg dst)-                 ]-        or_unordered dst = toOL [-                    SETCC cond (OpReg tmp1),-                    SETCC PARITY (OpReg tmp2),-                    OR II8 (OpReg tmp1) (OpReg tmp2),-                    MOVZxL II8 (OpReg tmp2) (OpReg dst)-                  ]-        and_ordered dst = toOL [-                    SETCC cond (OpReg tmp1),-                    SETCC NOTPARITY (OpReg tmp2),-                    AND II8 (OpReg tmp1) (OpReg tmp2),-                    MOVZxL II8 (OpReg tmp2) (OpReg dst)-                  ]-    return (Any II32 code)----- -------------------------------------------------------------------------------- 'trivial*Code': deal with trivial instructions---- Trivial (dyadic: 'trivialCode', floating-point: 'trivialFCode',--- unary: 'trivialUCode', unary fl-pt:'trivialUFCode') instructions.--- Only look for constants on the right hand side, because that's--- where the generic optimizer will have put them.---- Similarly, for unary instructions, we don't have to worry about--- matching an StInt as the argument, because genericOpt will already--- have handled the constant-folding.---{--The Rules of the Game are:--* You cannot assume anything about the destination register dst;-  it may be anything, including a fixed reg.--* You may compute an operand into a fixed reg, but you may not-  subsequently change the contents of that fixed reg.  If you-  want to do so, first copy the value either to a temporary-  or into dst.  You are free to modify dst even if it happens-  to be a fixed reg -- that's not your problem.--* You cannot assume that a fixed reg will stay live over an-  arbitrary computation.  The same applies to the dst reg.--* Temporary regs obtained from getNewRegNat are distinct from-  each other and from all other regs, and stay live over-  arbitrary computations.------------------------SDM's version of The Rules:--* If getRegister returns Any, that means it can generate correct-  code which places the result in any register, period.  Even if that-  register happens to be read during the computation.--  Corollary #1: this means that if you are generating code for an-  operation with two arbitrary operands, you cannot assign the result-  of the first operand into the destination register before computing-  the second operand.  The second operand might require the old value-  of the destination register.--  Corollary #2: A function might be able to generate more efficient-  code if it knows the destination register is a new temporary (and-  therefore not read by any of the sub-computations).--* If getRegister returns Any, then the code it generates may modify only:-        (a) fresh temporaries-        (b) the destination register-        (c) known registers (eg. %ecx is used by shifts)-  In particular, it may *not* modify global registers, unless the global-  register happens to be the destination register.--}--trivialCode :: Width -> (Operand -> Operand -> Instr)-            -> Maybe (Operand -> Operand -> Instr)-            -> CmmExpr -> CmmExpr -> NatM Register-trivialCode width instr m a b-    = do platform <- getPlatform-         trivialCode' platform width instr m a b--trivialCode' :: Platform -> Width -> (Operand -> Operand -> Instr)-             -> Maybe (Operand -> Operand -> Instr)-             -> CmmExpr -> CmmExpr -> NatM Register-trivialCode' platform width _ (Just revinstr) (CmmLit lit_a) b-  | is32BitLit platform lit_a = do-  b_code <- getAnyReg b-  let-       code dst-         = b_code dst `snocOL`-           revinstr (OpImm (litToImm lit_a)) (OpReg dst)-  return (Any (intFormat width) code)--trivialCode' _ width instr _ a b-  = genTrivialCode (intFormat width) instr a b---- This is re-used for floating pt instructions too.-genTrivialCode :: Format -> (Operand -> Operand -> Instr)-               -> CmmExpr -> CmmExpr -> NatM Register-genTrivialCode rep instr a b = do-  (b_op, b_code) <- getNonClobberedOperand b-  a_code <- getAnyReg a-  tmp <- getNewRegNat rep-  let-     -- We want the value of 'b' to stay alive across the computation of 'a'.-     -- But, we want to calculate 'a' straight into the destination register,-     -- because the instruction only has two operands (dst := dst `op` src).-     -- The troublesome case is when the result of 'b' is in the same register-     -- as the destination 'reg'.  In this case, we have to save 'b' in a-     -- new temporary across the computation of 'a'.-     code dst-        | dst `regClashesWithOp` b_op =-                b_code `appOL`-                unitOL (MOV rep b_op (OpReg tmp)) `appOL`-                a_code dst `snocOL`-                instr (OpReg tmp) (OpReg dst)-        | otherwise =-                b_code `appOL`-                a_code dst `snocOL`-                instr b_op (OpReg dst)-  return (Any rep code)--regClashesWithOp :: Reg -> Operand -> Bool-reg `regClashesWithOp` OpReg reg2   = reg == reg2-reg `regClashesWithOp` OpAddr amode = any (==reg) (addrModeRegs amode)-_   `regClashesWithOp` _            = False---- | Generate code for a fused multiply-add operation, of the form @± x * y ± z@,--- with 3 operands (FMA3 instruction set).-genFMA3Code :: Length-            -> Width-            -> FMASign-            -> CmmExpr -> CmmExpr -> CmmExpr -> NatM Register-genFMA3Code l w signs x y z = do-  config <- getConfig-  -- For the FMA instruction, we want to compute x * y + z-  ---  -- There are three possible instructions we could emit:-  ---  --   - fmadd213 z y x, result in x, z can be a memory address-  --   - fmadd132 x z y, result in y, x can be a memory address-  --   - fmadd231 y x z, result in z, y can be a memory address-  ---  -- This suggests two possible optimisations:-  ---  --   - OPTIMISATION 1-  --     If one argument is an address, use the instruction that allows-  --     a memory address in that position.-  ---  --   - OPTIMISATION 2-  --     If one argument is in a fixed register, use the instruction that puts-  --     the result in that same register.-  ---  -- Currently we follow neither of these optimisations,-  -- opting to always use fmadd213 for simplicity.-  ---  -- We would like to compute the result directly into the requested register.-  -- To do so we must first compute `x` into the destination register. This is-  -- only possible if the other arguments don't use the destination register.-  -- We check for this and if there is a conflict we move the result only after-  -- the computation. See #24496 how this went wrong in the past.-  let rep-        | l == 1-        = floatFormat w-        | otherwise-        = vecFormat (cmmVec l $ cmmFloat w)-  (y_reg, y_code) <- getNonClobberedReg y-  (z_op, z_code) <- getNonClobberedOperand z-  x_code <- getAnyReg x-  x_tmp <- getNewRegNat rep-  let-     fma213 = FMA3 rep signs FMA213--     code, code_direct, code_mov :: Reg -> InstrBlock-     -- Ideal: Compute the result directly into dst-     code_direct dst = x_code dst `snocOL`-                       fma213 z_op y_reg dst-     -- Fallback: Compute the result into a tmp reg and then move it.-     code_mov dst    = x_code x_tmp `snocOL`-                       fma213 z_op y_reg x_tmp `snocOL`-                       mkRegRegMoveInstr config rep x_tmp dst--     code dst =-        y_code `appOL`-        z_code `appOL`-        ( if arg_regs_conflict then code_mov dst else code_direct dst )--      where--        arg_regs_conflict =-          y_reg == dst ||-          case z_op of-            OpReg z_reg -> z_reg == dst-            OpAddr amode -> dst `elem` addrModeRegs amode-            OpImm {} -> False--  -- NB: Computing the result into a desired register using Any can be tricky.-  -- So for now, we keep it simple. (See #24496).-  return (Any rep code)---------------trivialUCode :: Format -> (Operand -> Instr)-             -> CmmExpr -> NatM Register-trivialUCode rep instr x = do-  x_code <- getAnyReg x-  let-     code dst =-        x_code dst `snocOL`-        instr (OpReg dst)-  return (Any rep code)----------------trivialFCode_sse2 :: Width -> (Format -> Operand -> Operand -> Instr)-                  -> CmmExpr -> CmmExpr -> NatM Register-trivialFCode_sse2 ty instr x y-    = genTrivialCode format (instr format) x y-    where format = floatFormat ty------------------------------------------------------------------------------------coerceInt2FP :: Width -> Width -> CmmExpr -> NatM Register-coerceInt2FP from to x =  coerce_sse2- where--   coerce_sse2 = do-     (x_op, x_code) <- getOperand x  -- ToDo: could be a safe operand-     let-           opc  = case to of W32 -> CVTSI2SS; W64 -> CVTSI2SD-                             n -> panic $ "coerceInt2FP.sse: unhandled width ("-                                         ++ show n ++ ")"-           code dst = x_code `snocOL` opc (intFormat from) x_op dst-     return (Any (floatFormat to) code)-        -- works even if the destination rep is <II32-----------------------------------------------------------------------------------coerceFP2Int :: Width -> Width -> CmmExpr -> NatM Register-coerceFP2Int from to x =  coerceFP2Int_sse2- where-   coerceFP2Int_sse2 = do-     (x_op, x_code) <- getOperand x  -- ToDo: could be a safe operand-     let-           opc  = case from of W32 -> CVTTSS2SIQ; W64 -> CVTTSD2SIQ;-                               n -> panic $ "coerceFP2Init.sse: unhandled width ("-                                           ++ show n ++ ")"-           code dst = x_code `snocOL` opc (intFormat to) x_op dst-     return (Any (intFormat to) code)-         -- works even if the destination rep is <II32------------------------------------------------------------------------------------coerceFP2FP :: Width -> CmmExpr -> NatM Register-coerceFP2FP to x = do-  (x_reg, x_code) <- getSomeReg x-  let-        opc  = case to of W32 -> CVTSD2SS; W64 -> CVTSS2SD;-                                     n -> panic $ "coerceFP2FP: unhandled width ("-                                                 ++ show n ++ ")"-        code dst = x_code `snocOL` opc x_reg dst-  return (Any ( floatFormat to) code)------------------------------------------------------------------------------------sse2NegCode :: Width -> CmmExpr -> NatM Register-sse2NegCode w x = do-  let fmt = floatFormat w-  x_code <- getAnyReg x-  -- This is how gcc does it, so it can't be that bad:-  let-    const = case fmt of-      FF32 -> CmmInt 0x80000000 W32-      FF64 -> CmmInt 0x8000000000000000 W64-      x@II8  -> wrongFmt x-      x@II16 -> wrongFmt x-      x@II32 -> wrongFmt x-      x@II64 -> wrongFmt x-      x@(VecFormat {}) -> wrongFmt x--      where-        wrongFmt x = panic $ "sse2NegCode: " ++ show x-  Amode amode amode_code <- memConstant (mkAlignment $ widthInBytes w) const-  tmp <- getNewRegNat fmt-  let-    code dst = x_code dst `appOL` amode_code `appOL` toOL [-        MOV fmt (OpAddr amode) (OpReg tmp),-        XOR fmt (OpReg tmp) (OpReg dst)-        ]-  ---  return (Any fmt code)--needLlvm :: MachOp -> NatM a-needLlvm mop =-  sorry $ unlines [ "Unsupported vector instruction for the native code generator:"-                  , show mop-                  , "Please use -fllvm." ]--incorrectOperands :: NatM a-incorrectOperands = sorry "Incorrect number of operands"--invalidConversion :: Width -> Width -> NatM a-invalidConversion from to =-  sorry $ "Invalid conversion operation from " ++ show from ++ " to " ++ show to---- | This works on the invariant that all jumps in the given blocks are required.---   Starting from there we try to make a few more jumps redundant by reordering---   them.---   We depend on the information in the CFG to do so so without a given CFG---   we do nothing.-invertCondBranches :: Maybe CFG  -- ^ CFG if present-                   -> LabelMap a -- ^ Blocks with info tables-                   -> [NatBasicBlock Instr] -- ^ List of basic blocks-                   -> [NatBasicBlock Instr]-invertCondBranches Nothing _       bs = bs-invertCondBranches (Just cfg) keep bs =-    invert bs-  where-    invert :: [NatBasicBlock Instr] -> [NatBasicBlock Instr]-    invert (BasicBlock lbl1 ins:b2@(BasicBlock lbl2 _):bs)-      | --pprTrace "Block" (ppr lbl1) True,-        Just (jmp1,jmp2) <- last2 ins-      , JXX cond1 target1 <- jmp1-      , target1 == lbl2-      --, pprTrace "CutChance" (ppr b1) True-      , JXX ALWAYS target2 <- jmp2-      -- We have enough information to check if we can perform the inversion-      -- TODO: We could also check for the last asm instruction which sets-      -- status flags instead. Which I suspect is worse in terms of compiler-      -- performance, but might be applicable to more cases-      , Just edgeInfo1 <- getEdgeInfo lbl1 target1 cfg-      , Just edgeInfo2 <- getEdgeInfo lbl1 target2 cfg-      -- Both jumps come from the same cmm statement-      , transitionSource edgeInfo1 == transitionSource edgeInfo2-      , CmmSource {trans_cmmNode = cmmCondBranch} <- transitionSource edgeInfo1--      --Int comparisons are invertable-      , CmmCondBranch (CmmMachOp op _args) _ _ _ <- cmmCondBranch-      , Just _ <- maybeIntComparison op-      , Just invCond <- maybeInvertCond cond1--      --Swap the last two jumps, invert the conditional jumps condition.-      = let jumps =-              case () of-                -- We are free the eliminate the jmp. So we do so.-                _ | not (mapMember target1 keep)-                    -> [JXX invCond target2]-                -- If the conditional target is unlikely we put the other-                -- target at the front.-                  | edgeWeight edgeInfo2 > edgeWeight edgeInfo1-                    -> [JXX invCond target2, JXX ALWAYS target1]-                -- Keep things as-is otherwise-                  | otherwise-                    -> [jmp1, jmp2]-        in --pprTrace "Cutable" (ppr [jmp1,jmp2] <+> text "=>" <+> ppr jumps) $-           (BasicBlock lbl1-            (dropTail 2 ins ++ jumps))-            : invert (b2:bs)-    invert (b:bs) = b : invert bs-    invert [] = []--genAtomicRMW-  :: BlockId-  -> Width-  -> AtomicMachOp-  -> LocalReg-  -> CmmExpr-  -> CmmExpr-  -> NatM (InstrBlock, Maybe BlockId)-genAtomicRMW bid width amop dst addr n = do-    Amode amode addr_code <--        if amop `elem` [AMO_Add, AMO_Sub]-        then getAmode addr-        else getSimpleAmode addr  -- See genForeignCall for MO_Cmpxchg-    arg <- getNewRegNat format-    arg_code <- getAnyReg n-    platform <- ncgPlatform <$> getConfig--    let dst_r    = getRegisterReg platform  (CmmLocal dst)-    (code, lbl) <- op_code dst_r arg amode-    return (addr_code `appOL` arg_code arg `appOL` code, Just lbl)-  where-    -- Code for the operation-    op_code :: Reg       -- Destination reg-            -> Reg       -- Register containing argument-            -> AddrMode  -- Address of location to mutate-            -> NatM (OrdList Instr,BlockId) -- TODO: Return Maybe BlockId-    op_code dst_r arg amode = do-        case amop of-          -- In the common case where dst_r is a virtual register the-          -- final move should go away, because it's the last use of arg-          -- and the first use of dst_r.-          AMO_Add  -> return $ (toOL [ LOCK (XADD format (OpReg arg) (OpAddr amode))-                                     , MOV format (OpReg arg) (OpReg dst_r)-                                     ], bid)-          AMO_Sub  -> return $ (toOL [ NEGI format (OpReg arg)-                                     , LOCK (XADD format (OpReg arg) (OpAddr amode))-                                     , MOV format (OpReg arg) (OpReg dst_r)-                                     ], bid)-          -- In these cases we need a new block id, and have to return it so-          -- that later instruction selection can reference it.-          AMO_And  -> cmpxchg_code (\ src dst -> unitOL $ AND format src dst)-          AMO_Nand -> cmpxchg_code (\ src dst -> toOL [ AND format src dst-                                                      , NOT format dst-                                                      ])-          AMO_Or   -> cmpxchg_code (\ src dst -> unitOL $ OR format src dst)-          AMO_Xor  -> cmpxchg_code (\ src dst -> unitOL $ XOR format src dst)-      where-        -- Simulate operation that lacks a dedicated instruction using-        -- cmpxchg.-        cmpxchg_code :: (Operand -> Operand -> OrdList Instr)-                     -> NatM (OrdList Instr, BlockId)-        cmpxchg_code instrs = do-            lbl1 <- getBlockIdNat-            lbl2 <- getBlockIdNat-            tmp <- getNewRegNat format--            --Record inserted blocks-            --  We turn A -> B into A -> A' -> A'' -> B-            --  with a self loop on A'.-            addImmediateSuccessorNat bid lbl1-            addImmediateSuccessorNat lbl1 lbl2-            updateCfgNat (addWeightEdge lbl1 lbl1 0)--            return $ (toOL-                [ MOV format (OpAddr amode) (OpReg eax)-                , JXX ALWAYS lbl1-                , NEWBLOCK lbl1-                  -- Keep old value so we can return it:-                , MOV format (OpReg eax) (OpReg dst_r)-                , MOV format (OpReg eax) (OpReg tmp)-                ]-                `appOL` instrs (OpReg arg) (OpReg tmp) `appOL` toOL-                [ LOCK (CMPXCHG format (OpReg tmp) (OpAddr amode))-                , JXX NE lbl1-                -- See Note [Introducing cfg edges inside basic blocks]-                -- why this basic block is required.-                , JXX ALWAYS lbl2-                , NEWBLOCK lbl2-                ],-                lbl2)-    format = intFormat width---- | Count trailing zeroes-genCtz :: BlockId -> Width -> LocalReg -> CmmExpr -> NatM (InstrBlock, Maybe BlockId)-genCtz bid width dst src = do-  is32Bit <- is32BitPlatform-  if is32Bit && width == W64-    then genCtz64_32 bid dst src-    else (,Nothing) <$> genCtzGeneric width dst src---- | Count trailing zeroes------ 64-bit width on 32-bit architecture-genCtz64_32-  :: BlockId-  -> LocalReg-  -> CmmExpr-  -> NatM (InstrBlock, Maybe BlockId)-genCtz64_32 bid dst src = do-  RegCode64 vcode rhi rlo <- iselExpr64 src-  let dst_r = getLocalRegReg dst-  lbl1 <- getBlockIdNat-  lbl2 <- getBlockIdNat-  tmp_r <- getNewRegNat II64--  -- New CFG Edges:-  --  bid -> lbl2-  --  bid -> lbl1 -> lbl2-  --  We also changes edges originating at bid to start at lbl2 instead.-  weights <- getCfgWeights-  updateCfgNat (addWeightEdge bid lbl1 110 .-                addWeightEdge lbl1 lbl2 110 .-                addImmediateSuccessor weights bid lbl2)--  -- The following instruction sequence corresponds to the pseudo-code-  ---  --  if (src) {-  --    dst = src.lo32 ? BSF(src.lo32) : (BSF(src.hi32) + 32);-  --  } else {-  --    dst = 64;-  --  }-  let instrs = vcode `appOL` toOL-           ([ MOV      II32 (OpReg rhi)         (OpReg tmp_r)-            , OR       II32 (OpReg rlo)         (OpReg tmp_r)-            , MOV      II32 (OpImm (ImmInt 64)) (OpReg dst_r)-            , JXX EQQ    lbl2-            , JXX ALWAYS lbl1--            , NEWBLOCK   lbl1-            , BSF     II32 (OpReg rhi)         dst_r-            , ADD     II32 (OpImm (ImmInt 32)) (OpReg dst_r)-            , BSF     II32 (OpReg rlo)         tmp_r-            , CMOV NE II32 (OpReg tmp_r)       dst_r-            , JXX ALWAYS lbl2--            , NEWBLOCK   lbl2-            ])-  return (instrs, Just lbl2)---- | Count trailing zeroes------ Generic case (width <= word size)-genCtzGeneric :: Width -> LocalReg -> CmmExpr -> NatM InstrBlock-genCtzGeneric width dst src = do-  code_src <- getAnyReg src-  config <- getConfig-  let bw = widthInBits width-  let dst_r = getLocalRegReg dst-  if ncgBmiVersion config >= Just BMI2-  then do-      src_r <- getNewRegNat (intFormat width)-      let instrs = appOL (code_src src_r) $ case width of-              W8 -> toOL-                  [ OR    II32 (OpImm (ImmInteger 0xFFFFFF00)) (OpReg src_r)-                  , TZCNT II32 (OpReg src_r) dst_r-                  ]-              W16 -> toOL-                  [ TZCNT  II16 (OpReg src_r) dst_r-                  , MOVZxL II16 (OpReg dst_r) (OpReg dst_r)-                  ]-              _ -> unitOL $ TZCNT (intFormat width) (OpReg src_r) dst_r-      return instrs-  else do-      -- The following insn sequence makes sure 'ctz 0' has a defined value.-      -- starting with Haswell, one could use the TZCNT insn instead.-      let format = if width == W8 then II16 else intFormat width-      src_r <- getNewRegNat format-      tmp_r <- getNewRegNat format-      let instrs = code_src src_r `appOL` toOL-               ([ MOVZxL  II8    (OpReg src_r)       (OpReg src_r) | width == W8 ] ++-                [ BSF     format (OpReg src_r)       tmp_r-                , MOV     II32   (OpImm (ImmInt bw)) (OpReg dst_r)-                , CMOV NE format (OpReg tmp_r)       dst_r-                ]) -- NB: We don't need to zero-extend the result for the-                   -- W8/W16 cases because the 'MOV' insn already-                   -- took care of implicitly clearing the upper bits-      return instrs------ | Copy memory------ Unroll memcpy calls if the number of bytes to copy isn't too large (cf--- ncgInlineThresholdMemcpy).  Otherwise, call C's memcpy.-genMemCpy-  :: BlockId-  -> Int-  -> CmmExpr-  -> CmmExpr-  -> CmmExpr-  -> NatM InstrBlock-genMemCpy bid align dst src arg_n = do--  let libc_memcpy = genLibCCall bid (fsLit "memcpy") [] [dst,src,arg_n]--  case arg_n of-    CmmLit (CmmInt n _) -> do-      -- try to inline it-      mcode <- genMemCpyInlineMaybe align dst src n-      -- if it didn't inline, call the C function-      case mcode of-        Nothing -> libc_memcpy-        Just c  -> pure c--    -- not a literal size argument: call the C function-    _ -> libc_memcpy----genMemCpyInlineMaybe-  :: Int-  -> CmmExpr-  -> CmmExpr-  -> Integer-  -> NatM (Maybe InstrBlock)-genMemCpyInlineMaybe align dst src n = do-  config <- getConfig-  let-    platform     = ncgPlatform config-    maxAlignment = wordAlignment platform-                   -- only machine word wide MOVs are supported-    effectiveAlignment = min (alignmentOf align) maxAlignment-    format = intFormat . widthFromBytes $ alignmentBytes effectiveAlignment---  -- The size of each move, in bytes.-  let sizeBytes :: Integer-      sizeBytes = fromIntegral (formatInBytes format)--  -- The number of instructions we will generate (approx). We need 2-  -- instructions per move.-  let insns = 2 * ((n + sizeBytes - 1) `div` sizeBytes)--      go :: Reg -> Reg -> Reg -> Integer -> OrdList Instr-      go dst src tmp i-          | i >= sizeBytes =-              unitOL (MOV format (OpAddr src_addr) (OpReg tmp)) `appOL`-              unitOL (MOV format (OpReg tmp) (OpAddr dst_addr)) `appOL`-              go dst src tmp (i - sizeBytes)-          -- Deal with remaining bytes.-          | i >= 4 =  -- Will never happen on 32-bit-              unitOL (MOV II32 (OpAddr src_addr) (OpReg tmp)) `appOL`-              unitOL (MOV II32 (OpReg tmp) (OpAddr dst_addr)) `appOL`-              go dst src tmp (i - 4)-          | i >= 2 =-              unitOL (MOVZxL II16 (OpAddr src_addr) (OpReg tmp)) `appOL`-              unitOL (MOV    II16  (OpReg tmp) (OpAddr dst_addr)) `appOL`-              go dst src tmp (i - 2)-          | i >= 1 =-              unitOL (MOVZxL II8 (OpAddr src_addr) (OpReg tmp)) `appOL`-              unitOL (MOV    II8 (OpReg tmp) (OpAddr dst_addr)) `appOL`-              go dst src tmp (i - 1)-          | otherwise = nilOL-        where-          src_addr = AddrBaseIndex (EABaseReg src) EAIndexNone-                       (ImmInteger (n - i))--          dst_addr = AddrBaseIndex (EABaseReg dst) EAIndexNone-                       (ImmInteger (n - i))--  if insns > fromIntegral (ncgInlineThresholdMemcpy config)-    then pure Nothing-    else do-      code_dst <- getAnyReg dst-      dst_r <- getNewRegNat format-      code_src <- getAnyReg src-      src_r <- getNewRegNat format-      tmp_r <- getNewRegNat format-      pure $ Just $ code_dst dst_r `appOL` code_src src_r `appOL`-                      go dst_r src_r tmp_r (fromInteger n)---- | Set memory to the given byte------ Unroll memset calls if the number of bytes to copy isn't too large (cf--- ncgInlineThresholdMemset).  Otherwise, call C's memset.-genMemSet-  :: BlockId-  -> Int-  -> CmmExpr-  -> CmmExpr-  -> CmmExpr-  -> NatM InstrBlock-genMemSet bid align dst arg_c arg_n = do--  let libc_memset = genLibCCall bid (fsLit "memset") [] [dst,arg_c,arg_n]--  case (arg_c,arg_n) of-    (CmmLit (CmmInt c _), CmmLit (CmmInt n _)) -> do-      -- try to inline it-      mcode <- genMemSetInlineMaybe align dst c n-      -- if it didn't inline, call the C function-      case mcode of-        Nothing -> libc_memset-        Just c  -> pure c--    -- not literal size arguments: call the C function-    _ -> libc_memset--genMemSetInlineMaybe-  :: Int-  -> CmmExpr-  -> Integer-  -> Integer-  -> NatM (Maybe InstrBlock)-genMemSetInlineMaybe align dst c n = do-  config <- getConfig-  let-    platform = ncgPlatform config-    maxAlignment = wordAlignment platform -- only machine word wide MOVs are supported-    effectiveAlignment = min (alignmentOf align) maxAlignment-    format = intFormat . widthFromBytes $ alignmentBytes effectiveAlignment-    c2 = c `shiftL` 8 .|. c-    c4 = c2 `shiftL` 16 .|. c2-    c8 = c4 `shiftL` 32 .|. c4--    -- The number of instructions we will generate (approx). We need 1-    -- instructions per move.-    insns = (n + sizeBytes - 1) `div` sizeBytes--    -- The size of each move, in bytes.-    sizeBytes :: Integer-    sizeBytes = fromIntegral (formatInBytes format)--    -- Depending on size returns the widest MOV instruction and its-    -- width.-    gen4 :: AddrMode -> Integer -> (InstrBlock, Integer)-    gen4 addr size-        | size >= 4 =-            (unitOL (MOV II32 (OpImm (ImmInteger c4)) (OpAddr addr)), 4)-        | size >= 2 =-            (unitOL (MOV II16 (OpImm (ImmInteger c2)) (OpAddr addr)), 2)-        | size >= 1 =-            (unitOL (MOV II8 (OpImm (ImmInteger c)) (OpAddr addr)), 1)-        | otherwise = (nilOL, 0)--    -- Generates a 64-bit wide MOV instruction from REG to MEM.-    gen8 :: AddrMode -> Reg -> InstrBlock-    gen8 addr reg8byte =-      unitOL (MOV format (OpReg reg8byte) (OpAddr addr))--    -- Unrolls memset when the widest MOV is <= 4 bytes.-    go4 :: Reg -> Integer -> InstrBlock-    go4 dst left =-      if left <= 0 then nilOL-      else curMov `appOL` go4 dst (left - curWidth)-      where-        possibleWidth = minimum [left, sizeBytes]-        dst_addr = AddrBaseIndex (EABaseReg dst) EAIndexNone (ImmInteger (n - left))-        (curMov, curWidth) = gen4 dst_addr possibleWidth--    -- Unrolls memset when the widest MOV is 8 bytes (thus another Reg-    -- argument). Falls back to go4 when all 8 byte moves are-    -- exhausted.-    go8 :: Reg -> Reg -> Integer -> InstrBlock-    go8 dst reg8byte left =-      if possibleWidth >= 8 then-        let curMov = gen8 dst_addr reg8byte-        in  curMov `appOL` go8 dst reg8byte (left - 8)-      else go4 dst left-      where-        possibleWidth = minimum [left, sizeBytes]+-----------------------------------------------------------------------------+--+-- Generating machine code (instruction selection)+--+-- (c) The University of Glasgow 1996-2004+--+-----------------------------------------------------------------------------++-- This is a big module, but, if you pay attention to+-- (a) the sectioning, and (b) the type signatures, the+-- structure should not be too overwhelming.++module GHC.CmmToAsm.X86.CodeGen (+        cmmTopCodeGen,+        generateJumpTableForInstr,+        extractUnwindPoints,+        invertCondBranches,+        InstrBlock+)++where++-- NCG stuff:+import GHC.Prelude++import GHC.CmmToAsm.X86.Instr+import GHC.CmmToAsm.X86.Cond+import GHC.CmmToAsm.X86.Regs+import GHC.CmmToAsm.X86.Ppr+import GHC.CmmToAsm.X86.RegInfo++import GHC.Platform.Regs+import GHC.CmmToAsm.CPrim+import GHC.CmmToAsm.Types+import GHC.Cmm.DebugBlock+   ( DebugBlock(..), UnwindPoint(..), UnwindTable+   , UnwindExpr(UwReg), toUnwindExpr+   )+import GHC.CmmToAsm.PIC+import GHC.CmmToAsm.Monad+   ( NatM, getNewRegNat, getNewLabelNat, setDeltaNat+   , getDeltaNat, getBlockIdNat, getPicBaseNat+   , Reg64(..), RegCode64(..), getNewReg64, localReg64+   , getPicBaseMaybeNat, getDebugBlock, getFileId+   , addImmediateSuccessorNat, updateCfgNat, getConfig, getPlatform+   , getCfgWeights+   )+import GHC.CmmToAsm.CFG+import GHC.CmmToAsm.Format+import GHC.CmmToAsm.Config+import GHC.Platform.Reg+import GHC.Platform++-- Our intermediate code:+import GHC.Types.Basic+import GHC.Cmm.BlockId+import GHC.Unit.Types ( ghcInternalUnitId )+import GHC.Cmm.Utils+import GHC.Cmm.Switch+import GHC.Cmm+import GHC.Cmm.Dataflow.Block+import GHC.Cmm.Dataflow.Graph+import GHC.Cmm.Dataflow.Label+import GHC.Cmm.CLabel+import GHC.Types.Tickish ( GenTickish(..) )+import GHC.Types.SrcLoc  ( srcSpanFile, srcSpanStartLine, srcSpanStartCol )++-- The rest:+import GHC.Data.Maybe ( expectJust )+import GHC.Types.ForeignCall ( CCallConv(..) )+import GHC.Data.OrdList+import GHC.Utils.Outputable+import GHC.Utils.Constants (debugIsOn)+import GHC.Utils.Monad ( foldMapM )+import GHC.Utils.Panic+import GHC.Data.FastString+import GHC.Utils.Misc+import GHC.Types.Unique.DSM ( getUniqueM )++import qualified Data.Semigroup as S++import Control.Monad+import Control.Monad.Trans.State.Strict+  ( StateT, evalStateT, get, put )+import Control.Monad.Trans.Class (lift)+import Data.Foldable (fold)+import Data.Int+import Data.List (partition, (\\))+import Data.Maybe+import Data.Word++import qualified Data.Map as Map++is32BitPlatform :: NatM Bool+is32BitPlatform = do+    platform <- getPlatform+    return $ target32Bit platform++ssse3Enabled :: NatM Bool+ssse3Enabled = do+  config <- getConfig+  return (ncgSseVersion config >= Just SSSE3)++sse4_1Enabled :: NatM Bool+sse4_1Enabled = do+  config <- getConfig+  return (ncgSseVersion config >= Just SSE4)++sse4_2Enabled :: NatM Bool+sse4_2Enabled = do+  config <- getConfig+  return (ncgSseVersion config >= Just SSE42)++avxEnabled :: NatM Bool+avxEnabled = do+  config <- getConfig+  return (ncgAvxEnabled config)++avx2Enabled :: NatM Bool+avx2Enabled = do+  config <- getConfig+  return (ncgAvx2Enabled config)++cmmTopCodeGen+        :: RawCmmDecl+        -> NatM [NatCmmDecl (Alignment, RawCmmStatics) Instr]++cmmTopCodeGen (CmmProc info lab live graph) = do+  let blocks = toBlockListEntryFirst graph+  (nat_blocks,statics) <- mapAndUnzipM basicBlockCodeGen blocks+  picBaseMb <- getPicBaseMaybeNat+  platform <- getPlatform+  let proc = CmmProc info lab live (ListGraph $ concat nat_blocks)+      tops = proc : concat statics+      os   = platformOS platform++  case picBaseMb of+      Just picBase -> initializePicBase_x86 os picBase tops+      Nothing -> return tops++cmmTopCodeGen (CmmData sec dat) =+  return [CmmData sec (mkAlignment 1, dat)]  -- no translation, we just use CmmStatic++{- Note [Verifying basic blocks]+   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+   We want to guarantee a few things about the results+   of instruction selection.++   Namely that each basic blocks consists of:+    * A (potentially empty) sequence of straight line instructions+  followed by+    * A (potentially empty) sequence of jump like instructions.++    We can verify this by going through the instructions and+    making sure that any non-jumpish instruction can't appear+    after a jumpish instruction.++    There are gotchas however:+    * CALLs are strictly speaking control flow but here we care+      not about them. Hence we treat them as regular instructions.++      It's safe for them to appear inside a basic block+      as (ignoring side effects inside the call) they will result in+      straight line code.++    * NEWBLOCK marks the start of a new basic block so can+      be followed by any instructions.+-}++-- Verifying basic blocks is cheap, but not cheap enough to enable it unconditionally.+verifyBasicBlock :: Platform -> [Instr] -> ()+verifyBasicBlock platform instrs+  | debugIsOn     = go False instrs+  | otherwise     = ()+  where+    go _     [] = ()+    go atEnd (i:instr)+        = case i of+            -- Start a new basic block+            NEWBLOCK {} -> go False instr+            -- Calls are not viable block terminators+            CALL {}     | atEnd -> faultyBlockWith i+                        | not atEnd -> go atEnd instr+            -- All instructions ok, check if we reached the end and continue.+            _ | not atEnd -> go (isJumpishInstr i) instr+              -- Only jumps allowed at the end of basic blocks.+              | otherwise -> if isJumpishInstr i+                                then go True instr+                                else faultyBlockWith i+    faultyBlockWith i+        = pprPanic "Non control flow instructions after end of basic block."+                   (pprInstr platform i <+> text "in:" $$ vcat (map (pprInstr platform) instrs))++basicBlockCodeGen+        :: CmmBlock+        -> NatM ( [NatBasicBlock Instr]+                , [NatCmmDecl (Alignment, RawCmmStatics) Instr])++basicBlockCodeGen block = do+  let (_, nodes, tail)  = blockSplit block+      id = entryLabel block+      stmts = blockToList nodes+  -- Generate location directive+  dbg <- getDebugBlock (entryLabel block)+  loc_instrs <- case dblSourceTick =<< dbg of+    Just (SourceNote span (LexicalFastString name))+      -> do fileId <- getFileId (srcSpanFile span)+            let line = srcSpanStartLine span; col = srcSpanStartCol span+            return $ unitOL $ LOCATION fileId line col (unpackFS name)+    _ -> return nilOL+  (mid_instrs,mid_bid) <- stmtsToInstrs id stmts+  (!tail_instrs,_) <- stmtToInstrs mid_bid tail+  let instrs = loc_instrs `appOL` mid_instrs `appOL` tail_instrs+  platform <- getPlatform+  return $! verifyBasicBlock platform (fromOL instrs)+  instrs' <- fold <$> traverse addSpUnwindings instrs+  -- code generation may introduce new basic block boundaries, which+  -- are indicated by the NEWBLOCK instruction.  We must split up the+  -- instruction stream into basic blocks again.  Also, we extract+  -- LDATAs here too.+  let+        (top,other_blocks,statics) = foldrOL mkBlocks ([],[],[]) instrs'++        mkBlocks (NEWBLOCK id) (instrs,blocks,statics)+          = ([], BasicBlock id instrs : blocks, statics)+        mkBlocks (LDATA sec dat) (instrs,blocks,statics)+          = (instrs, blocks, CmmData sec dat:statics)+        mkBlocks instr (instrs,blocks,statics)+          = (instr:instrs, blocks, statics)+  return (BasicBlock id top : other_blocks, statics)++-- | Convert 'DELTA' instructions into 'UNWIND' instructions to capture changes+-- in the @sp@ register. See Note [What is this unwinding business?] in "GHC.Cmm.DebugBlock"+-- for details.+addSpUnwindings :: Instr -> NatM (OrdList Instr)+addSpUnwindings instr@(DELTA d) = do+    config <- getConfig+    let platform = ncgPlatform config+    if ncgDwarfUnwindings config+        then do lbl <- mkAsmTempLabel <$> getUniqueM+                let unwind = Map.singleton MachSp (Just $ UwReg (GlobalRegUse MachSp (bWord platform)) $ negate d)+                return $ toOL [ instr, UNWIND lbl unwind ]+        else return (unitOL instr)+addSpUnwindings instr = return $ unitOL instr++{- Note [Keeping track of the current block]+   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+When generating instructions for Cmm we sometimes require+the current block for things like retry loops.++We also sometimes change the current block, if a MachOP+results in branching control flow.++Issues arise if we have two statements in the same block,+which both depend on the current block id *and* change the+basic block after them. This happens for atomic primops+in the X86 backend where we want to update the CFG data structure+when introducing new basic blocks.++For example in #17334 we got this Cmm code:++        c3Bf: // global+            (_s3t1::I64) = call MO_AtomicRMW W64 AMO_And(_s3sQ::P64 + 88, 18);+            (_s3t4::I64) = call MO_AtomicRMW W64 AMO_Or(_s3sQ::P64 + 88, 0);+            _s3sT::I64 = _s3sV::I64;+            goto c3B1;++This resulted in two new basic blocks being inserted:++        c3Bf:+                movl $18,%vI_n3Bo+                movq 88(%vI_s3sQ),%rax+                jmp _n3Bp+        n3Bp:+                ...+                cmpxchgq %vI_n3Bq,88(%vI_s3sQ)+                jne _n3Bp+                ...+                jmp _n3Bs+        n3Bs:+                ...+                cmpxchgq %vI_n3Bt,88(%vI_s3sQ)+                jne _n3Bs+                ...+                jmp _c3B1+        ...++Based on the Cmm we called stmtToInstrs we translated both atomic operations under+the assumption they would be placed into their Cmm basic block `c3Bf`.+However for the retry loop we introduce new labels, so this is not the case+for the second statement.+This resulted in a desync between the explicit control flow graph+we construct as a separate data type and the actual control flow graph in the code.++Instead we now return the new basic block if a statement causes a change+in the current block and use the block for all following statements.++For this reason genForeignCall is also split into two parts.  One for calls which+*won't* change the basic blocks in which successive instructions will be+placed (since they only evaluate CmmExpr, which can only contain MachOps, which+cannot introduce basic blocks in their lowerings).  A different one for calls+which *are* known to change the basic block.++-}++-- See Note [Keeping track of the current block] for why+-- we pass the BlockId.+stmtsToInstrs :: BlockId -- ^ Basic block these statement will start to be placed in.+              -> [CmmNode O O] -- ^ Cmm Statement+              -> NatM (InstrBlock, BlockId) -- ^ Resulting instruction+stmtsToInstrs bid stmts =+    go bid stmts nilOL+  where+    go bid  []        instrs = return (instrs,bid)+    go bid (s:stmts)  instrs = do+      (instrs',bid') <- stmtToInstrs bid s+      -- If the statement introduced a new block, we use that one+      let !newBid = fromMaybe bid bid'+      go newBid stmts (instrs `appOL` instrs')++-- | `bid` refers to the current block and is used to update the CFG+--   if new blocks are inserted in the control flow.+-- See Note [Keeping track of the current block] for more details.+stmtToInstrs :: BlockId -- ^ Basic block this statement will start to be placed in.+             -> CmmNode e x+             -> NatM (InstrBlock, Maybe BlockId)+             -- ^ Instructions, and bid of new block if successive+             -- statements are placed in a different basic block.+stmtToInstrs bid stmt = do+  is32Bit <- is32BitPlatform+  platform <- getPlatform+  case stmt of+    CmmUnsafeForeignCall target result_regs args+       -> genForeignCall target result_regs args bid++    _ -> (,Nothing) <$> case stmt of+      CmmComment s   -> return (unitOL (COMMENT s))+      CmmTick {}     -> return nilOL++      CmmUnwind regs -> do+        let to_unwind_entry :: (GlobalReg, Maybe CmmExpr) -> UnwindTable+            to_unwind_entry (reg, expr) = Map.singleton reg (fmap (toUnwindExpr platform) expr)+        case foldMap to_unwind_entry regs of+          tbl | Map.null tbl -> return nilOL+              | otherwise    -> do+                  lbl <- mkAsmTempLabel <$> getUniqueM+                  return $ unitOL $ UNWIND lbl tbl++      CmmAssign reg src+        | isFloatType ty         -> assignReg_FltCode reg src+        | is32Bit && isWord64 ty -> assignReg_I64Code reg src+        | isVecType ty           -> assignReg_VecCode reg src+        | otherwise              -> assignReg_IntCode reg src+          where ty = cmmRegType reg++      CmmStore addr src _alignment+        | isFloatType ty         -> assignMem_FltCode format addr src+        | is32Bit && isWord64 ty -> assignMem_I64Code        addr src+        | isVecType ty           -> assignMem_VecCode format addr src+        | otherwise              -> assignMem_IntCode format addr src+          where ty = cmmExprType platform src+                format = cmmTypeFormat ty++      CmmBranch id          -> return $ genBranch id++      --We try to arrange blocks such that the likely branch is the fallthrough+      --in GHC.Cmm.ContFlowOpt. So we can assume the condition is likely false here.+      CmmCondBranch arg true false _ -> genCondBranch bid true false arg+      CmmSwitch arg ids -> genSwitch arg ids+      CmmCall { cml_target = arg+              , cml_args_regs = gregs } -> genJump arg (jumpRegs platform gregs)+      _ ->+        panic "stmtToInstrs: statement should have been cps'd away"+++jumpRegs :: Platform -> [GlobalRegUse] -> [RegWithFormat]+jumpRegs platform gregs =+  [ RegWithFormat (RegReal r) (cmmTypeFormat ty)+  | GlobalRegUse gr ty <- gregs+  , Just r <- [globalRegMaybe platform gr] ]++--------------------------------------------------------------------------------+-- | 'InstrBlock's are the insn sequences generated by the insn selectors.+--      They are really trees of insns to facilitate fast appending, where a+--      left-to-right traversal yields the insns in the correct order.+--+type InstrBlock+        = OrdList Instr+++-- | Condition codes passed up the tree.+--+data CondCode+        = CondCode Bool Cond InstrBlock+++-- | Register's passed up the tree.  If the stix code forces the register+--      to live in a pre-decided machine register, it comes out as @Fixed@;+--      otherwise, it comes out as @Any@, and the parent can decide which+--      register to put it in.+--+data Register+        = Fixed Format Reg InstrBlock+        | Any   Format (Reg -> InstrBlock)+++swizzleRegisterRep :: Register -> Format -> Register+swizzleRegisterRep (Fixed _ reg code) format = Fixed format reg code+swizzleRegisterRep (Any _ codefn)     format = Any   format codefn++getLocalRegReg :: LocalReg -> Reg+getLocalRegReg (LocalReg u ty)+  = -- by assuming SSE2, Int, Word, Float, Double and vectors all can be register allocated+    RegVirtual (mkVirtualReg u (cmmTypeFormat ty))++-- | Grab the Reg for a CmmReg+getRegisterReg :: Platform  -> CmmReg -> Reg++getRegisterReg _   (CmmLocal lreg) = getLocalRegReg lreg++getRegisterReg platform  (CmmGlobal mid)+  = case globalRegMaybe platform $ globalRegUse_reg mid of+        Just reg -> RegReal $ reg+        Nothing  -> pprPanic "getRegisterReg-memory" (ppr $ CmmGlobal mid)+        -- By this stage, the only MagicIds remaining should be the+        -- ones which map to a real machine register on this+        -- platform.  Hence ...++-- | Memory addressing modes passed up the tree.+data Amode+        = Amode AddrMode InstrBlock++{-+Now, given a tree (the argument to a CmmLoad) that references memory,+produce a suitable addressing mode.++A Rule of the Game (tm) for Amodes: use of the addr bit must+immediately follow use of the code part, since the code part puts+values in registers which the addr then refers to.  So you can't put+anything in between, lest it overwrite some of those registers.  If+you need to do some other computation between the code part and use of+the addr bit, first store the effective address from the amode in a+temporary, then do the other computation, and then use the temporary:++    code+    LEA amode, tmp+    ... other computation ...+    ... (tmp) ...+-}++{-+Note [%rip-relative addressing on x86-64]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+On x86-64 GHC produces code for use in the "small" or, when `-fPIC` is set,+"small PIC" code models defined by the x86-64 System V ABI (section 3.5.1 of+specification version 0.99).++In general the small code model would allow us to assume that code is located+between 0 and 2^31 - 1. However, this is not true on Windows which, due to+high-entropy ASLR, may place the executable image anywhere in 64-bit address+space. This is problematic since immediate operands in x86-64 are generally+32-bit sign-extended values (with the exception of the 64-bit MOVABS encoding).+Consequently, to avoid overflowing we use %rip-relative addressing universally.+Since %rip-relative addressing comes essentially for free and makes linking far+easier, we use it even on non-Windows platforms.++See also: the documentation for GCC's `-mcmodel=small` flag.+-}+++-- | Check whether an integer will fit in 32 bits.+--      A CmmInt is intended to be truncated to the appropriate+--      number of bits, so here we truncate it to Int64.  This is+--      important because e.g. -1 as a CmmInt might be either+--      -1 or 18446744073709551615.+--+is32BitInteger :: Integer -> Bool+is32BitInteger i = i64 <= 0x7fffffff && i64 >= -0x80000000+  where i64 = fromIntegral i :: Int64+++-- | Convert a BlockId to some CmmStatic data+jumpTableEntry :: NCGConfig -> Maybe BlockId -> CmmStatic+jumpTableEntry config Nothing = CmmStaticLit (CmmInt 0 (ncgWordWidth config))+jumpTableEntry _ (Just blockid) = CmmStaticLit (CmmLabel blockLabel)+    where blockLabel = blockLbl blockid+++-- -----------------------------------------------------------------------------+-- General things for putting together code sequences++-- Expand CmmRegOff.  ToDo: should we do it this way around, or convert+-- CmmExprs into CmmRegOff?+mangleIndexTree :: CmmReg -> Int -> CmmExpr+mangleIndexTree reg off+  = CmmMachOp (MO_Add width) [CmmReg reg, CmmLit (CmmInt (fromIntegral off) width)]+  where width = typeWidth (cmmRegType reg)++-- | The dual to getAnyReg: compute an expression into a register, but+--      we don't mind which one it is.+getSomeReg :: CmmExpr -> NatM (Reg, InstrBlock)+getSomeReg expr = do+  r <- getRegister expr+  case r of+    Any rep code -> do+        tmp <- getNewRegNat rep+        return (tmp, code tmp)+    Fixed _ reg code ->+        return (reg, code)++assignMem_I64Code :: CmmExpr -> CmmExpr -> NatM InstrBlock+assignMem_I64Code addrTree valueTree = do+  Amode addr addr_code <- getAmode addrTree+  RegCode64 vcode rhi rlo <- iselExpr64 valueTree+  let+        -- Little-endian store+        mov_lo = MOV II32 (OpReg rlo) (OpAddr addr)+        mov_hi = MOV II32 (OpReg rhi) (OpAddr (fromJust (addrOffset addr 4)))+  return (vcode `appOL` addr_code `snocOL` mov_lo `snocOL` mov_hi)+++assignReg_I64Code :: CmmReg  -> CmmExpr -> NatM InstrBlock+assignReg_I64Code (CmmLocal dst) valueTree = do+   RegCode64 vcode r_src_hi r_src_lo <- iselExpr64 valueTree+   let+         Reg64 r_dst_hi r_dst_lo = localReg64 dst+         mov_lo = MOV II32 (OpReg r_src_lo) (OpReg r_dst_lo)+         mov_hi = MOV II32 (OpReg r_src_hi) (OpReg r_dst_hi)+   return (+        vcode `snocOL` mov_lo `snocOL` mov_hi+     )++assignReg_I64Code _ _+   = panic "assignReg_I64Code(i386): invalid lvalue"++iselExpr64 :: HasDebugCallStack => CmmExpr -> NatM (RegCode64 InstrBlock)+iselExpr64 (CmmLit (CmmInt i _)) = do+  Reg64 rhi rlo <- getNewReg64+  let+        r = fromIntegral (fromIntegral i :: Word32)+        q = fromIntegral (fromIntegral (i `shiftR` 32) :: Word32)+        code = toOL [+                MOV II32 (OpImm (ImmInteger r)) (OpReg rlo),+                MOV II32 (OpImm (ImmInteger q)) (OpReg rhi)+                ]+  return (RegCode64 code rhi rlo)++iselExpr64 (CmmLoad addrTree ty _) | isWord64 ty = do+   Amode addr addr_code <- getAmode addrTree+   Reg64 rhi rlo <- getNewReg64+   let+        mov_lo = MOV II32 (OpAddr addr) (OpReg rlo)+        mov_hi = MOV II32 (OpAddr (fromJust (addrOffset addr 4))) (OpReg rhi)+   return (+            RegCode64 (addr_code `snocOL` mov_lo `snocOL` mov_hi) rhi rlo+     )++iselExpr64 (CmmReg (CmmLocal local_reg)) = do+  let Reg64 hi lo = localReg64 local_reg+  return (RegCode64 nilOL hi lo)++iselExpr64 (CmmMachOp (MO_Add _) [e1, CmmLit (CmmInt i _)]) = do+   RegCode64 code1 r1hi r1lo <- iselExpr64 e1+   Reg64 rhi rlo <- getNewReg64+   let+        r = fromIntegral (fromIntegral i :: Word32)+        q = fromIntegral (fromIntegral (i `shiftR` 32) :: Word32)+        code =  code1 `appOL`+                toOL [ MOV II32 (OpReg r1lo) (OpReg rlo),+                       ADD II32 (OpImm (ImmInteger r)) (OpReg rlo),+                       MOV II32 (OpReg r1hi) (OpReg rhi),+                       ADC II32 (OpImm (ImmInteger q)) (OpReg rhi) ]+   return (RegCode64 code rhi rlo)++iselExpr64 (CmmMachOp (MO_Add _) [e1,e2]) = do+   RegCode64 code1 r1hi r1lo <- iselExpr64 e1+   RegCode64 code2 r2hi r2lo <- iselExpr64 e2+   Reg64 rhi rlo <- getNewReg64+   let+        code =  code1 `appOL`+                code2 `appOL`+                toOL [ MOV II32 (OpReg r1lo) (OpReg rlo),+                       ADD II32 (OpReg r2lo) (OpReg rlo),+                       MOV II32 (OpReg r1hi) (OpReg rhi),+                       ADC II32 (OpReg r2hi) (OpReg rhi) ]+   return (RegCode64 code rhi rlo)++iselExpr64 (CmmMachOp (MO_Sub _) [e1,e2]) = do+   RegCode64 code1 r1hi r1lo <- iselExpr64 e1+   RegCode64 code2 r2hi r2lo <- iselExpr64 e2+   Reg64 rhi rlo <- getNewReg64+   let+        code =  code1 `appOL`+                code2 `appOL`+                toOL [ MOV II32 (OpReg r1lo) (OpReg rlo),+                       SUB II32 (OpReg r2lo) (OpReg rlo),+                       MOV II32 (OpReg r1hi) (OpReg rhi),+                       SBB II32 (OpReg r2hi) (OpReg rhi) ]+   return (RegCode64 code rhi rlo)++iselExpr64 (CmmMachOp (MO_UU_Conv W32 W64) [expr]) = do+     code <- getAnyReg expr+     Reg64 r_dst_hi r_dst_lo <- getNewReg64+     return $ RegCode64 (code r_dst_lo `snocOL`+                          XOR II32 (OpReg r_dst_hi) (OpReg r_dst_hi))+                          r_dst_hi+                          r_dst_lo++iselExpr64 (CmmMachOp (MO_UU_Conv W16 W64) [expr]) = do+     (rsrc, code) <- getByteReg expr+     Reg64 r_dst_hi r_dst_lo <- getNewReg64+     return $ RegCode64 (code `appOL` toOL [+                          MOVZxL II16 (OpReg rsrc) (OpReg r_dst_lo),+                          XOR    II32 (OpReg r_dst_hi) (OpReg r_dst_hi)+                          ])+                          r_dst_hi+                          r_dst_lo++iselExpr64 (CmmMachOp (MO_UU_Conv W8 W64) [expr]) = do+     (rsrc, code) <- getByteReg expr+     Reg64 r_dst_hi r_dst_lo <- getNewReg64+     return $ RegCode64 (code `appOL` toOL [+                          MOVZxL II8 (OpReg rsrc) (OpReg r_dst_lo),+                          XOR    II32 (OpReg r_dst_hi) (OpReg r_dst_hi)+                          ])+                          r_dst_hi+                          r_dst_lo++iselExpr64 (CmmMachOp (MO_SS_Conv W32 W64) [expr]) = do+     code <- getAnyReg expr+     Reg64 r_dst_hi r_dst_lo <- getNewReg64+     return $ RegCode64 (code r_dst_lo `snocOL`+                          MOV II32 (OpReg r_dst_lo) (OpReg eax) `snocOL`+                          CLTD II32 `snocOL`+                          MOV II32 (OpReg eax) (OpReg r_dst_lo) `snocOL`+                          MOV II32 (OpReg edx) (OpReg r_dst_hi))+                          r_dst_hi+                          r_dst_lo++iselExpr64 (CmmMachOp (MO_SS_Conv W16 W64) [expr]) = do+     (r, code) <- getByteReg expr+     Reg64 r_dst_hi r_dst_lo <- getNewReg64+     return $ RegCode64 (code `appOL` toOL [+                          MOVSxL II16 (OpReg r) (OpReg eax),+                          CLTD II32,+                          MOV II32 (OpReg eax) (OpReg r_dst_lo),+                          MOV II32 (OpReg edx) (OpReg r_dst_hi)])+                          r_dst_hi+                          r_dst_lo++iselExpr64 (CmmMachOp (MO_SS_Conv W8 W64) [expr]) = do+     (r, code) <- getByteReg expr+     Reg64 r_dst_hi r_dst_lo <- getNewReg64+     return $ RegCode64 (code `appOL` toOL [+                          MOVSxL II8 (OpReg r) (OpReg eax),+                          CLTD II32,+                          MOV II32 (OpReg eax) (OpReg r_dst_lo),+                          MOV II32 (OpReg edx) (OpReg r_dst_hi)])+                          r_dst_hi+                          r_dst_lo++iselExpr64 (CmmMachOp (MO_S_Neg _) [expr]) = do+   RegCode64 code rhi rlo <- iselExpr64 expr+   Reg64 rohi rolo <- getNewReg64+   let+        ocode = code `appOL`+                toOL [ MOV II32 (OpReg rlo) (OpReg rolo),+                       XOR II32 (OpReg rohi) (OpReg rohi),+                       NEGI II32 (OpReg rolo),+                       SBB II32 (OpReg rhi) (OpReg rohi) ]+   return (RegCode64 ocode rohi rolo)++-- To multiply two 64-bit numbers we use the following decomposition (in C notation):+--+--     ((r1hi << 32) + r1lo) * ((r2hi << 32) + r2lo)+--      = ((r2lo * r1hi) << 32)+--      + ((r1lo * r2hi) << 32)+--      + r1lo * r2lo+--+-- Note that @(r1hi * r2hi) << 64@ can be dropped because it overflows completely.++iselExpr64 (CmmMachOp (MO_Mul _) [e1,e2]) = do+   RegCode64 code1 r1hi r1lo <- iselExpr64 e1+   RegCode64 code2 r2hi r2lo <- iselExpr64 e2+   Reg64 rhi rlo <- getNewReg64+   tmp <- getNewRegNat II32+   let+        code =  code1 `appOL`+                code2 `appOL`+                toOL [ MOV  II32 (OpReg r1lo) (OpReg eax),+                       MOV  II32 (OpReg r2lo) (OpReg tmp),+                       MOV  II32 (OpReg r1hi) (OpReg rhi),+                       IMUL II32 (OpReg tmp) (OpReg rhi),+                       MOV  II32 (OpReg r2hi) (OpReg rlo),+                       IMUL II32 (OpReg eax) (OpReg rlo),+                       ADD  II32 (OpReg rlo) (OpReg rhi),+                       MUL2 II32 (OpReg tmp),+                       ADD  II32 (OpReg edx) (OpReg rhi),+                       MOV  II32 (OpReg eax) (OpReg rlo)+                     ]+   return (RegCode64 code rhi rlo)++iselExpr64 (CmmMachOp (MO_S_MulMayOflo W64) _) = do+   -- Performance sensitive users won't use 32 bit so let's keep it simple:+   -- We always return a (usually false) positive.+   Reg64 rhi rlo <- getNewReg64+   let code = toOL   [+                       MOV II32 (OpImm (ImmInt 1)) (OpReg rhi),+                       MOV II32 (OpImm (ImmInt 1)) (OpReg rlo)+                     ]+   return (RegCode64 code rhi rlo)+++-- To shift a 64-bit number to the left we use the SHLD and SHL instructions.+-- We use SHLD to shift the bits in @rhi@ to the left while copying+-- high bits from @rlo@ to fill the new space in the low bits of @rhi@.+-- That leaves @rlo@ unchanged, so we use SHL to shift the bits of @rlo@ left.+-- However, both these instructions only use the lowest 5 bits from %cl to do+-- their shifting. So if the sixth bit (0x32) is set then we additionally move+-- the contents of @rlo@ to @rhi@ and clear @rlo@.++iselExpr64 (CmmMachOp (MO_Shl _) [e1,e2]) = do+   RegCode64 code1 r1hi r1lo <- iselExpr64 e1+   code2 <- getAnyReg e2+   Reg64 rhi rlo <- getNewReg64+   lbl1 <- newBlockId+   lbl2 <- newBlockId+   let+        code =  code1 `appOL`+                code2 ecx `appOL`+                toOL [ MOV II32 (OpReg r1lo) (OpReg rlo),+                       MOV II32 (OpReg r1hi) (OpReg rhi),+                       SHLD II32 (OpReg ecx) (OpReg rlo) (OpReg rhi),+                       SHL II32 (OpReg ecx) (OpReg rlo),+                       TEST II32 (OpImm (ImmInt 32)) (OpReg ecx),+                       JXX EQQ lbl2,+                       JXX ALWAYS lbl1,+                       NEWBLOCK lbl1,+                       MOV II32 (OpReg rlo) (OpReg rhi),+                       XOR II32 (OpReg rlo) (OpReg rlo),+                       JXX ALWAYS lbl2,+                       NEWBLOCK lbl2+                     ]+   return (RegCode64 code rhi rlo)++-- Similar to above, however now we're shifting to the right+-- and we're doing a signed shift which means that @rhi@ needs+-- to be set to either 0 if @rhi@ is positive or 0xffffffff otherwise,+-- and if the sixth bit of %cl is set (so the shift amount is more than 32).+-- To accomplish that we shift @rhi@ by 31.++iselExpr64 (CmmMachOp (MO_S_Shr _) [e1,e2]) = do+   RegCode64 code1 r1hi r1lo <- iselExpr64 e1+   (r2, code2) <- getSomeReg e2+   Reg64 rhi rlo <- getNewReg64+   lbl1 <- newBlockId+   lbl2 <- newBlockId+   let+        code =  code1 `appOL`+                code2 `appOL`+                toOL [ MOV II32 (OpReg r1lo) (OpReg rlo),+                       MOV II32 (OpReg r1hi) (OpReg rhi),+                       MOV II32 (OpReg r2) (OpReg ecx),+                       SHRD II32 (OpReg ecx) (OpReg rhi) (OpReg rlo),+                       SAR II32 (OpReg ecx) (OpReg rhi),+                       TEST II32 (OpImm (ImmInt 32)) (OpReg ecx),+                       JXX EQQ lbl2,+                       JXX ALWAYS lbl1,+                       NEWBLOCK lbl1,+                       MOV II32 (OpReg rhi) (OpReg rlo),+                       SAR II32 (OpImm (ImmInt 31)) (OpReg rhi),+                       JXX ALWAYS lbl2,+                       NEWBLOCK lbl2+                     ]+   return (RegCode64 code rhi rlo)++-- Similar to the above.++iselExpr64 (CmmMachOp (MO_U_Shr _) [e1,e2]) = do+   RegCode64 code1 r1hi r1lo <- iselExpr64 e1+   (r2, code2) <- getSomeReg e2+   Reg64 rhi rlo <- getNewReg64+   lbl1 <- newBlockId+   lbl2 <- newBlockId+   let+        code =  code1 `appOL`+                code2 `appOL`+                toOL [ MOV II32 (OpReg r1lo) (OpReg rlo),+                       MOV II32 (OpReg r1hi) (OpReg rhi),+                       MOV II32 (OpReg r2) (OpReg ecx),+                       SHRD II32 (OpReg ecx) (OpReg rhi) (OpReg rlo),+                       SHR II32 (OpReg ecx) (OpReg rhi),+                       TEST II32 (OpImm (ImmInt 32)) (OpReg ecx),+                       JXX EQQ lbl2,+                       JXX ALWAYS lbl1,+                       NEWBLOCK lbl1,+                       MOV II32 (OpReg rhi) (OpReg rlo),+                       XOR II32 (OpReg rhi) (OpReg rhi),+                       JXX ALWAYS lbl2,+                       NEWBLOCK lbl2+                     ]+   return (RegCode64 code rhi rlo)++iselExpr64 (CmmMachOp (MO_And _) [e1,e2]) = iselExpr64ParallelBin AND e1 e2+iselExpr64 (CmmMachOp (MO_Or  _) [e1,e2]) = iselExpr64ParallelBin OR  e1 e2+iselExpr64 (CmmMachOp (MO_Xor _) [e1,e2]) = iselExpr64ParallelBin XOR e1 e2++iselExpr64 (CmmMachOp (MO_Not _) [e1]) = do+   RegCode64 code1 r1hi r1lo <- iselExpr64 e1+   Reg64 rhi rlo <- getNewReg64+   let+        code =  code1 `appOL`+                toOL [ MOV II32 (OpReg r1lo) (OpReg rlo),+                       MOV II32 (OpReg r1hi) (OpReg rhi),+                       NOT II32 (OpReg rlo),+                       NOT II32 (OpReg rhi)+                     ]+   return (RegCode64 code rhi rlo)++iselExpr64 (CmmRegOff r i) = iselExpr64 (mangleIndexTree r i)++iselExpr64 expr+   = do+      platform <- getPlatform+      pprPanic "iselExpr64(i386)" (pdoc platform expr $+$ text (show expr))++iselExpr64ParallelBin :: (Format -> Operand -> Operand -> Instr)+                      -> CmmExpr -> CmmExpr -> NatM (RegCode64 (OrdList Instr))+iselExpr64ParallelBin op e1 e2 = do+   RegCode64 code1 r1hi r1lo <- iselExpr64 e1+   RegCode64 code2 r2hi r2lo <- iselExpr64 e2+   Reg64 rhi rlo <- getNewReg64+   let+        code =  code1 `appOL`+                code2 `appOL`+                toOL [ MOV II32 (OpReg r1lo) (OpReg rlo),+                       MOV II32 (OpReg r1hi) (OpReg rhi),+                       op  II32 (OpReg r2lo) (OpReg rlo),+                       op  II32 (OpReg r2hi) (OpReg rhi)+                     ]+   return (RegCode64 code rhi rlo)++--------------------------------------------------------------------------------++getRegister :: HasDebugCallStack => CmmExpr -> NatM Register+getRegister e = do platform <- getPlatform+                   is32Bit <- is32BitPlatform+                   getRegister' platform is32Bit e++getRegister' :: HasDebugCallStack => Platform -> Bool -> CmmExpr -> NatM Register++getRegister' platform is32Bit (CmmReg reg)+  = case reg of+        CmmGlobal (GlobalRegUse PicBaseReg _)+         | is32Bit ->+            -- on x86_64, we have %rip for PicBaseReg, but it's not+            -- a full-featured register, it can only be used for+            -- rip-relative addressing.+            do reg' <- getPicBaseNat (archWordFormat is32Bit)+               return (Fixed (archWordFormat is32Bit) reg' nilOL)+        _ ->+          let ty = cmmRegType reg+              reg_fmt = cmmTypeFormat ty+          in return $ Fixed reg_fmt (getRegisterReg platform reg) nilOL++getRegister' platform is32Bit (CmmRegOff r n)+  = getRegister' platform is32Bit $ mangleIndexTree r n++getRegister' platform is32Bit (CmmMachOp (MO_RelaxedRead w) [e])+  = getRegister' platform is32Bit (CmmLoad e (cmmBits w) NaturallyAligned)++getRegister' platform is32Bit (CmmMachOp (MO_AlignmentCheck align _) [e])+  = addAlignmentCheck align <$> getRegister' platform is32Bit e++-- for 32-bit architectures, support some 64 -> 32 bit conversions:+-- TO_W_(x), TO_W_(x >> 32)++getRegister' _ is32Bit (CmmMachOp (MO_UU_Conv W64 W32)+                     [CmmMachOp (MO_U_Shr W64) [x,CmmLit (CmmInt 32 _)]])+ | is32Bit = do+  RegCode64 code rhi _rlo <- iselExpr64 x+  return $ Fixed II32 rhi code++getRegister' _ is32Bit (CmmMachOp (MO_SS_Conv W64 W32)+                     [CmmMachOp (MO_U_Shr W64) [x,CmmLit (CmmInt 32 _)]])+ | is32Bit = do+  RegCode64 code rhi _rlo <- iselExpr64 x+  return $ Fixed II32 rhi code++getRegister' _ is32Bit (CmmMachOp (MO_UU_Conv W64 W32) [x])+ | is32Bit = do+  RegCode64 code _rhi rlo <- iselExpr64 x+  return $ Fixed II32 rlo code++getRegister' _ is32Bit (CmmMachOp (MO_SS_Conv W64 W32) [x])+ | is32Bit = do+  RegCode64 code _rhi rlo <- iselExpr64 x+  return $ Fixed II32 rlo code++getRegister' _ is32Bit (CmmMachOp (MO_UU_Conv W64 W8) [x])+ | is32Bit = do+  RegCode64 code _rhi rlo <- iselExpr64 x+  ro <- getNewRegNat II8+  return $ Fixed II8 ro (code `appOL` toOL [ MOVZxL II8 (OpReg rlo) (OpReg ro) ])++getRegister' _ is32Bit (CmmMachOp (MO_UU_Conv W64 W16) [x])+ | is32Bit = do+  RegCode64 code _rhi rlo <- iselExpr64 x+  ro <- getNewRegNat II16+  return $ Fixed II16 ro (code `appOL` toOL [ MOVZxL II16 (OpReg rlo) (OpReg ro) ])++-- catch simple cases of zero- or sign-extended load+getRegister' _ _ (CmmMachOp (MO_UU_Conv W8 W32) [CmmLoad addr _ _]) = do+  code <- intLoadCode (MOVZxL II8) addr+  return (Any II32 code)++getRegister' _ _ (CmmMachOp (MO_SS_Conv W8 W32) [CmmLoad addr _ _]) = do+  code <- intLoadCode (MOVSxL II8) addr+  return (Any II32 code)++getRegister' _ _ (CmmMachOp (MO_UU_Conv W16 W32) [CmmLoad addr _ _]) = do+  code <- intLoadCode (MOVZxL II16) addr+  return (Any II32 code)++getRegister' _ _ (CmmMachOp (MO_SS_Conv W16 W32) [CmmLoad addr _ _]) = do+  code <- intLoadCode (MOVSxL II16) addr+  return (Any II32 code)++-- catch simple cases of zero- or sign-extended load+getRegister' _ is32Bit (CmmMachOp (MO_UU_Conv W8 W64) [CmmLoad addr _ _])+ | not is32Bit = do+  code <- intLoadCode (MOVZxL II8) addr+  return (Any II64 code)++getRegister' _ is32Bit (CmmMachOp (MO_SS_Conv W8 W64) [CmmLoad addr _ _])+ | not is32Bit = do+  code <- intLoadCode (MOVSxL II8) addr+  return (Any II64 code)++getRegister' _ is32Bit (CmmMachOp (MO_UU_Conv W16 W64) [CmmLoad addr _ _])+ | not is32Bit = do+  code <- intLoadCode (MOVZxL II16) addr+  return (Any II64 code)++getRegister' _ is32Bit (CmmMachOp (MO_SS_Conv W16 W64) [CmmLoad addr _ _])+ | not is32Bit = do+  code <- intLoadCode (MOVSxL II16) addr+  return (Any II64 code)++getRegister' _ is32Bit (CmmMachOp (MO_UU_Conv W32 W64) [CmmLoad addr _ _])+ | not is32Bit = do+  code <- intLoadCode (MOV II32) addr -- 32-bit loads zero-extend+  return (Any II64 code)++getRegister' _ is32Bit (CmmMachOp (MO_SS_Conv W32 W64) [CmmLoad addr _ _])+ | not is32Bit = do+  code <- intLoadCode (MOVSxL II32) addr+  return (Any II64 code)++getRegister' _ is32Bit (CmmMachOp (MO_Add W64) [CmmReg (CmmGlobal (GlobalRegUse PicBaseReg _)),+                                     CmmLit displacement])+ | not is32Bit =+      return $ Any II64 (\dst -> unitOL $+        LEA II64 (OpAddr (ripRel (litToImm displacement))) (OpReg dst))++getRegister' _ _ (CmmMachOp mop []) =+  pprPanic "getRegister(x86): nullary MachOp" (text $ show mop)++getRegister' platform is32Bit (CmmMachOp mop [x]) = do -- unary MachOps+    avx    <- avxEnabled+    avx2   <- avx2Enabled+    case mop of+      MO_F_Neg w  -> sse2NegCode w x+++      MO_S_Neg w -> triv_ucode NEGI (intFormat w)+      MO_Not w   -> triv_ucode NOT  (intFormat w)++      -- Nop conversions+      MO_UU_Conv W32 W8  -> toI8Reg  W32 x+      MO_SS_Conv W32 W8  -> toI8Reg  W32 x+      MO_XX_Conv W32 W8  -> toI8Reg  W32 x+      MO_UU_Conv W16 W8  -> toI8Reg  W16 x+      MO_SS_Conv W16 W8  -> toI8Reg  W16 x+      MO_XX_Conv W16 W8  -> toI8Reg  W16 x+      MO_UU_Conv W32 W16 -> toI16Reg W32 x+      MO_SS_Conv W32 W16 -> toI16Reg W32 x+      MO_XX_Conv W32 W16 -> toI16Reg W32 x++      MO_UU_Conv W64 W32 | not is32Bit -> conversionNop II64 x+      MO_SS_Conv W64 W32 | not is32Bit -> conversionNop II64 x+      MO_XX_Conv W64 W32 | not is32Bit -> conversionNop II64 x+      MO_UU_Conv W64 W16 | not is32Bit -> toI16Reg W64 x+      MO_SS_Conv W64 W16 | not is32Bit -> toI16Reg W64 x+      MO_XX_Conv W64 W16 | not is32Bit -> toI16Reg W64 x+      MO_UU_Conv W64 W8  | not is32Bit -> toI8Reg  W64 x+      MO_SS_Conv W64 W8  | not is32Bit -> toI8Reg  W64 x+      MO_XX_Conv W64 W8  | not is32Bit -> toI8Reg  W64 x++      MO_UU_Conv rep1 rep2 | rep1 == rep2 -> conversionNop (intFormat rep1) x+      MO_SS_Conv rep1 rep2 | rep1 == rep2 -> conversionNop (intFormat rep1) x+      MO_XX_Conv rep1 rep2 | rep1 == rep2 -> conversionNop (intFormat rep1) x++      MO_FW_Bitcast W32 -> bitcast FF32 II32 x+      MO_WF_Bitcast W32 -> bitcast II32 FF32 x+      MO_FW_Bitcast W64 -> bitcast FF64 II64 x+      MO_WF_Bitcast W64 -> bitcast II64 FF64 x+      MO_WF_Bitcast {}  -> incorrectOperands+      MO_FW_Bitcast {}  -> incorrectOperands++      -- widenings+      MO_UU_Conv W8  W32 -> integerExtend W8  W32 MOVZxL x+      MO_UU_Conv W16 W32 -> integerExtend W16 W32 MOVZxL x+      MO_UU_Conv W8  W16 -> integerExtend W8  W16 MOVZxL x++      MO_SS_Conv W8  W32 -> integerExtend W8  W32 MOVSxL x+      MO_SS_Conv W16 W32 -> integerExtend W16 W32 MOVSxL x+      MO_SS_Conv W8  W16 -> integerExtend W8  W16 MOVSxL x++      -- We don't care about the upper bits for MO_XX_Conv, so MOV is enough. However, on 32-bit we+      -- have 8-bit registers only for a few registers (as opposed to x86-64 where every register+      -- has 8-bit version). So for 32-bit code, we'll just zero-extend.+      MO_XX_Conv W8  W32+          | is32Bit   -> integerExtend W8 W32 MOVZxL x+          | otherwise -> integerExtend W8 W32 MOV x+      MO_XX_Conv W8  W16+          | is32Bit   -> integerExtend W8 W16 MOVZxL x+          | otherwise -> integerExtend W8 W16 MOV x+      MO_XX_Conv W16 W32 -> integerExtend W16 W32 MOV x++      MO_UU_Conv W8  W64 | not is32Bit -> integerExtend W8  W64 MOVZxL x+      MO_UU_Conv W16 W64 | not is32Bit -> integerExtend W16 W64 MOVZxL x+      MO_UU_Conv W32 W64 | not is32Bit -> integerExtend W32 W64 MOVZxL x+      MO_SS_Conv W8  W64 | not is32Bit -> integerExtend W8  W64 MOVSxL x+      MO_SS_Conv W16 W64 | not is32Bit -> integerExtend W16 W64 MOVSxL x+      MO_SS_Conv W32 W64 | not is32Bit -> integerExtend W32 W64 MOVSxL x+      -- For 32-to-64 bit zero extension, amd64 uses an ordinary movl.+      -- However, we don't want the register allocator to throw it+      -- away as an unnecessary reg-to-reg move, so we keep it in+      -- the form of a movzl and print it as a movl later.+      -- This doesn't apply to MO_XX_Conv since in this case we don't care about+      -- the upper bits. So we can just use MOV.+      MO_XX_Conv W8  W64 | not is32Bit -> integerExtend W8  W64 MOV x+      MO_XX_Conv W16 W64 | not is32Bit -> integerExtend W16 W64 MOV x+      MO_XX_Conv W32 W64 | not is32Bit -> integerExtend W32 W64 MOV x++      MO_FF_Conv W32 W64 -> coerceFP2FP W64 x+      MO_FF_Conv W64 W32 -> coerceFP2FP W32 x++      MO_FF_Conv from to -> invalidConversion from to+      MO_UU_Conv from to -> invalidConversion from to+      MO_SS_Conv from to -> invalidConversion from to+      MO_XX_Conv from to -> invalidConversion from to++      MO_FS_Truncate from to -> coerceFP2Int from to x+      MO_SF_Round    from to -> coerceInt2FP from to x++      MO_VF_Neg l w  | avx       -> vector_float_negate_avx l w x+                     | otherwise -> vector_float_negate_sse l w x+      -- SIMD NCG TODO: Support 256/512-bit integer vectors+      MO_VS_Neg l w -> getRegister' platform is32Bit (CmmMachOp (MO_V_Sub l w) [zero_vec, x])+        where zero_vec = CmmLit $ CmmVec $ replicate l $ CmmInt 0 w++      MO_VF_Broadcast l w+        | avx+        -> vector_float_broadcast_avx l w x+        | otherwise+        -> vector_float_broadcast_sse l w x+      MO_V_Broadcast l w+        | avx2, l * widthInBits w `elem` [128, 256] -- AVX-512 is not supported for now+        -> vector_int_broadcast_avx2 l w x+      MO_V_Broadcast 16 W8 -> vector_int8x16_broadcast x+      MO_V_Broadcast 8 W16 -> vector_int16x8_broadcast x+      MO_V_Broadcast 4 W32 -> vector_int32x4_broadcast x+      MO_V_Broadcast 2 W64 -> vector_int64x2_broadcast x+      MO_V_Broadcast {}+        -> pprPanic "Unsupported integer vector broadcast operation for: " (pdoc platform x)++      -- Binary MachOps+      MO_Add {}    -> incorrectOperands+      MO_Sub {}    -> incorrectOperands+      MO_Eq {}     -> incorrectOperands+      MO_Ne {}     -> incorrectOperands+      MO_Mul {}    -> incorrectOperands+      MO_S_MulMayOflo {} -> incorrectOperands+      MO_S_Quot {} -> incorrectOperands+      MO_S_Rem {}  -> incorrectOperands+      MO_U_Quot {} -> incorrectOperands+      MO_U_Rem {}  -> incorrectOperands+      MO_S_Ge {}   -> incorrectOperands+      MO_S_Le {}   -> incorrectOperands+      MO_S_Gt {}   -> incorrectOperands+      MO_S_Lt {}   -> incorrectOperands+      MO_U_Ge {}   -> incorrectOperands+      MO_U_Le {}   -> incorrectOperands+      MO_U_Gt {}   -> incorrectOperands+      MO_U_Lt {}   -> incorrectOperands+      MO_F_Add {}  -> incorrectOperands+      MO_F_Sub {}  -> incorrectOperands+      MO_F_Mul {}  -> incorrectOperands+      MO_F_Quot {} -> incorrectOperands+      MO_F_Eq {}   -> incorrectOperands+      MO_F_Ne {}   -> incorrectOperands+      MO_F_Ge {}   -> incorrectOperands+      MO_F_Le {}   -> incorrectOperands+      MO_F_Gt {}   -> incorrectOperands+      MO_F_Lt {}   -> incorrectOperands+      MO_F_Min {}  -> incorrectOperands+      MO_F_Max {}  -> incorrectOperands+      MO_And {}    -> incorrectOperands+      MO_Or {}     -> incorrectOperands+      MO_Xor {}    -> incorrectOperands+      MO_Shl {}    -> incorrectOperands+      MO_U_Shr {}  -> incorrectOperands+      MO_S_Shr {}  -> incorrectOperands++      MO_V_Extract {}     -> incorrectOperands+      MO_V_Add {}         -> incorrectOperands+      MO_V_Sub {}         -> incorrectOperands+      MO_V_Mul {}         -> incorrectOperands+      MO_V_Shuffle {}     -> incorrectOperands+      MO_VF_Shuffle {}    -> incorrectOperands+      MO_VU_Min {}  -> incorrectOperands+      MO_VU_Max {}  -> incorrectOperands+      MO_VS_Min {}  -> incorrectOperands+      MO_VS_Max {}  -> incorrectOperands+      MO_VF_Min {}  -> incorrectOperands+      MO_VF_Max {}  -> incorrectOperands++      MO_VF_Extract {}    -> incorrectOperands+      MO_VF_Add {}        -> incorrectOperands+      MO_VF_Sub {}        -> incorrectOperands+      MO_VF_Mul {}        -> incorrectOperands+      MO_VF_Quot {}       -> incorrectOperands++      -- Ternary MachOps+      MO_FMA {}           -> incorrectOperands+      MO_VF_Insert {}     -> incorrectOperands+      MO_V_Insert {}      -> incorrectOperands++      --_other -> pprPanic "getRegister" (pprMachOp mop)+   where+        triv_ucode :: (Format -> Operand -> Instr) -> Format -> NatM Register+        triv_ucode instr format = trivialUCode format (instr format) x++        -- signed or unsigned extension.+        integerExtend :: Width -> Width+                      -> (Format -> Operand -> Operand -> Instr)+                      -> CmmExpr -> NatM Register+        integerExtend from to instr expr = do+            (reg,e_code) <- if from == W8 then getByteReg expr+                                          else getSomeReg expr+            let+                code dst =+                  e_code `snocOL`+                  instr (intFormat from) (OpReg reg) (OpReg dst)+            return (Any (intFormat to) code)++        bitcast :: Format -> Format -> CmmExpr -> NatM Register+        bitcast fmt rfmt expr =+          do (src, e_code) <- getSomeReg expr+             let code = \dst -> e_code `snocOL` (MOVD fmt rfmt (OpReg src) (OpReg dst))+             return (Any rfmt code)++        toI8Reg :: Width -> CmmExpr -> NatM Register+        toI8Reg new_rep expr+            = do codefn <- getAnyReg expr+                 return (Any (intFormat new_rep) codefn)+                -- HACK: use getAnyReg to get a byte-addressable register.+                -- If the source was a Fixed register, this will add the+                -- mov instruction to put it into the desired destination.+                -- We're assuming that the destination won't be a fixed+                -- non-byte-addressable register; it won't be, because all+                -- fixed registers are word-sized.++        toI16Reg = toI8Reg -- for now++        conversionNop :: Format -> CmmExpr -> NatM Register+        conversionNop new_format expr+            = do e_code <- getRegister' platform is32Bit expr+                 return (swizzleRegisterRep e_code new_format)++        vector_float_negate_avx :: Length -> Width -> CmmExpr -> NatM Register+        vector_float_negate_avx l w expr = do+          let fmt :: Format+              mask :: CmmLit+              (fmt, mask) = case w of+                       W32 -> (VecFormat l FmtFloat , CmmInt (bit 31) w) -- TODO: these should be negative 0 floating point literals,+                       W64 -> (VecFormat l FmtDouble, CmmInt (bit 63) w) -- but we don't currently have those in Cmm.+                       _ -> panic "AVX floating-point negation: elements must be FF32 or FF64"+          (maskReg, maskCode) <- getSomeReg (CmmLit $ CmmVec $ replicate l mask)+          (reg, exp) <- getSomeReg expr+          let code dst = maskCode `appOL`+                         exp `snocOL`+                         (VMOVU fmt (OpReg reg) (OpReg dst)) `snocOL`+                         (VXOR fmt (OpReg maskReg) dst dst)+          return (Any fmt code)++        vector_float_negate_sse :: Length -> Width -> CmmExpr -> NatM Register+        vector_float_negate_sse l w expr = do+          let fmt :: Format+              mask :: CmmLit+              (fmt, mask) = case w of+                       W32 -> (VecFormat l FmtFloat , CmmInt (bit 31) w) -- Same comment as for vector_float_negate_avx,+                       W64 -> (VecFormat l FmtDouble, CmmInt (bit 63) w) -- these should be -0.0 CmmFloat values.+                       _ -> panic "SSE floating-point negation: elements must be FF32 or FF64"+          (maskReg, maskCode) <- getSomeReg (CmmLit $ CmmVec $ replicate l mask)+          (reg, exp) <- getSomeReg expr+          let code dst = maskCode `appOL`+                         exp `snocOL`+                         (MOVU fmt (OpReg reg) (OpReg dst)) `snocOL`+                         (XOR  fmt (OpReg maskReg) (OpReg dst))+          return (Any fmt code)++        -----------------------++        -- TODO: we could use VBROADCASTSS/SD when AVX2 is available.+        vector_float_broadcast_avx :: Length+                                   -> Width+                                   -> CmmExpr+                                   -> NatM Register+        vector_float_broadcast_avx len w expr = do+          (dst, exp) <- getSomeReg expr+          let fmt = VecFormat len (floatScalarFormat w)+              code = VSHUF fmt (ImmInt 0) (OpReg dst) dst dst+          return $ Fixed fmt dst (exp `snocOL` code)++        vector_float_broadcast_sse :: Length+                                   -> Width+                                   -> CmmExpr+                                   -> NatM Register+        vector_float_broadcast_sse len w expr = do+          (dst, exp) <- getSomeReg expr+          let fmt = VecFormat len (floatScalarFormat w)+              code = SHUF fmt (ImmInt 0) (OpReg dst) dst+          return $ Fixed fmt dst (exp `snocOL` code)++        vector_int_broadcast_avx2 :: Length+                                  -> Width+                                  -> CmmExpr+                                  -> NatM Register+        vector_int_broadcast_avx2 len w expr = do+          (reg, exp) <- getNonClobberedReg expr+          let (movFormat, fmt) = case w of+                W8  -> (II32, VecFormat len FmtInt8)+                W16 -> (II32, VecFormat len FmtInt16)+                W32 -> (II32, VecFormat len FmtInt32)+                W64 -> (II64, VecFormat len FmtInt64)+                _   -> pprPanic "Broadcast not supported for: " (pdoc platform expr)+              code dst = exp `snocOL`+                         -- VPBROADCAST from GPR requires AVX-512,+                         -- so we use an additional MOVD.+                         (MOVD movFormat fmt (OpReg reg) (OpReg dst)) `snocOL`+                         (VPBROADCAST fmt fmt (OpReg dst) dst)+          return $ Any fmt code++        vector_int8x16_broadcast :: CmmExpr+                                 -> NatM Register+        vector_int8x16_broadcast expr = do+          (reg, exp) <- getNonClobberedReg expr+          let fmt = VecFormat 16 FmtInt8+          return $ Any fmt (\dst -> exp `snocOL`+                                    (MOVD II32 fmt (OpReg reg) (OpReg dst)) `snocOL`+                                    (PUNPCKLBW fmt (OpReg dst) dst) `snocOL`+                                    (PUNPCKLWD (VecFormat 8 FmtInt16) (OpReg dst) dst) `snocOL`+                                    (PSHUFD fmt (ImmInt 0x00) (OpReg dst) dst)+                                    )++        vector_int16x8_broadcast :: CmmExpr+                                 -> NatM Register+        vector_int16x8_broadcast expr = do+          (reg, exp) <- getNonClobberedReg expr+          let fmt = VecFormat 8 FmtInt16+          return $ Any fmt (\dst -> exp `snocOL`+                                    (MOVD II32 fmt (OpReg reg) (OpReg dst)) `snocOL`+                                    (PUNPCKLWD fmt (OpReg dst) dst) `snocOL`+                                    (PSHUFD fmt (ImmInt 0x00) (OpReg dst) dst)+                                    )++        vector_int32x4_broadcast :: CmmExpr+                                 -> NatM Register+        vector_int32x4_broadcast expr = do+          (reg, exp) <- getNonClobberedReg expr+          let fmt = VecFormat 4 FmtInt32+          return $ Any fmt (\dst -> exp `snocOL`+                                    (MOVD II32 fmt (OpReg reg) (OpReg dst)) `snocOL`+                                    (PSHUFD fmt (ImmInt 0x00) (OpReg dst) dst)+                                    )++        vector_int64x2_broadcast :: CmmExpr+                                 -> NatM Register+        vector_int64x2_broadcast expr = do+          (reg, exp) <- getNonClobberedReg expr+          let fmt = VecFormat 2 FmtInt64+          return $ Any fmt (\dst -> exp `snocOL`+                                    (MOVD II64 fmt (OpReg reg) (OpReg dst)) `snocOL`+                                    (PUNPCKLQDQ fmt (OpReg dst) dst)+                                    )++getRegister' platform is32Bit (CmmMachOp mop [x, y]) = do -- dyadic MachOps+  sse4_1 <- sse4_1Enabled+  sse4_2 <- sse4_2Enabled+  avx <- avxEnabled+  case mop of+      MO_F_Eq _ -> condFltReg is32Bit EQQ x y+      MO_F_Ne _ -> condFltReg is32Bit NE  x y+      MO_F_Gt _ -> condFltReg is32Bit GTT x y+      MO_F_Ge _ -> condFltReg is32Bit GE  x y+      -- Invert comparison condition and swap operands+      -- See Note [SSE Parity Checks]+      MO_F_Lt _ -> condFltReg is32Bit GTT  y x+      MO_F_Le _ -> condFltReg is32Bit GE   y x++      MO_Eq _   -> condIntReg EQQ x y+      MO_Ne _   -> condIntReg NE  x y++      MO_S_Gt _ -> condIntReg GTT x y+      MO_S_Ge _ -> condIntReg GE  x y+      MO_S_Lt _ -> condIntReg LTT x y+      MO_S_Le _ -> condIntReg LE  x y++      MO_U_Gt _ -> condIntReg GU  x y+      MO_U_Ge _ -> condIntReg GEU x y+      MO_U_Lt _ -> condIntReg LU  x y+      MO_U_Le _ -> condIntReg LEU x y++      MO_F_Add  w -> trivialFCode_sse2 w (\fmt op2 -> ADD fmt op2 . OpReg) x y+      MO_F_Sub  w -> trivialFCode_sse2 w (\fmt op2 -> SUB fmt op2 . OpReg) x y+      MO_F_Quot w -> trivialFCode_sse2 w FDIV x y+      MO_F_Mul  w -> trivialFCode_sse2 w (\fmt op2 -> MUL fmt op2 . OpReg) x y+      MO_F_Min  w -> trivialFCode_sse2 w (MINMAX Min FloatMinMax) x y+      MO_F_Max  w -> trivialFCode_sse2 w (MINMAX Max FloatMinMax) x y++      MO_Add rep -> add_code rep x y+      MO_Sub rep -> sub_code rep x y++      MO_S_Quot rep -> div_code rep True  True  x y+      MO_S_Rem  rep -> div_code rep True  False x y+      MO_U_Quot rep -> div_code rep False True  x y+      MO_U_Rem  rep -> div_code rep False False x y++      MO_S_MulMayOflo rep -> imulMayOflo rep x y++      MO_Mul W8  -> imulW8 x y+      MO_Mul rep -> triv_op rep IMUL+      MO_And rep -> triv_op rep AND+      MO_Or  rep -> triv_op rep OR+      MO_Xor rep -> triv_op rep XOR++        {- Shift ops on x86s have constraints on their source, it+           either has to be Imm, CL or 1+            => trivialCode is not restrictive enough (sigh.)+        -}+      MO_Shl rep   -> shift_code rep SHL x y {-False-}+      MO_U_Shr rep -> shift_code rep SHR x y {-False-}+      MO_S_Shr rep -> shift_code rep SAR x y {-False-}++      MO_VF_Shuffle 4 W32 is | avx -> vector_shuffle_float_avx 4 x y is+                             | otherwise -> vector_shuffle_floatx4_sse sse4_1 x y is+      MO_VF_Shuffle 2 W64 is | avx -> vector_shuffle_double_avx 2 x y is+                             | otherwise -> vector_shuffle_doublex2_sse x y is+      MO_VF_Shuffle {} -> sorry "Please use -fllvm for wide shuffle instructions"++      MO_VF_Extract l W32   | avx       -> vector_float_extract l W32 x y+                            | otherwise -> vector_float_extract_sse l W32 x y+      MO_VF_Extract l W64               -> vector_float_extract l W64 x y+      MO_VF_Extract {} -> incorrectOperands++      MO_V_Extract 16 W8 | sse4_1 -> vector_int_extract_pextr 16 W8 x y+                         | otherwise -> vector_int8x16_extract_sse2 x y+      MO_V_Extract 8 W16 -> vector_int_extract_pextr 8 W16 x y -- PEXTRW (SSE2)+      MO_V_Extract 4 W32 | sse4_1 -> vector_int_extract_pextr 4 W32 x y+                         | otherwise -> vector_int32x4_extract_sse2 x y+      MO_V_Extract 2 W64 | sse4_1 -> vector_int_extract_pextr 2 W64 x y+                         | otherwise -> vector_int64x2_extract_sse2 x y+      -- SIMD NCG TODO: 256/512-bit vector+      MO_V_Extract {} -> needLlvm mop++      MO_VF_Add l w         | avx       -> vector_float_op_avx VADD l w x y+                            | otherwise -> vector_float_op_sse (\fmt op2 -> ADD fmt op2 . OpReg) l w x y++      MO_VF_Sub l w         | avx       -> vector_float_op_avx VSUB l w x y+                            | otherwise -> vector_float_op_sse (\fmt op2 -> SUB fmt op2 . OpReg) l w x y++      MO_VF_Mul l w         | avx       -> vector_float_op_avx VMUL l w x y+                            | otherwise -> vector_float_op_sse (\fmt op2 -> MUL fmt op2 . OpReg) l w x y++      MO_VF_Quot l w        | avx       -> vector_float_op_avx VDIV l w x y+                            | otherwise -> vector_float_op_sse FDIV l w x y++      MO_VF_Min l w         | avx       -> vector_float_op_avx (VMINMAX Min FloatMinMax) l w x y+                            | otherwise -> vector_float_op_sse (MINMAX Min FloatMinMax) l w x y++      MO_VF_Max l w         | avx       -> vector_float_op_avx (VMINMAX Max FloatMinMax) l w x y+                            | otherwise -> vector_float_op_sse (MINMAX Max FloatMinMax) l w x y++      -- SIMD NCG TODO: 256/512-bit integer vector operations+      MO_V_Shuffle 16 W8 is | not is32Bit -> vector_shuffle_int8x16 sse4_1 x y is+      MO_V_Shuffle 8 W16 is -> vector_shuffle_int16x8 sse4_1 x y is+      MO_V_Shuffle 4 W32 is -> vector_shuffle_int32x4 sse4_1 x y is+      MO_V_Shuffle 2 W64 is -> vector_shuffle_int64x2 sse4_1 x y is+      MO_V_Shuffle {} -> needLlvm mop+      MO_V_Add l w | l * widthInBits w == 128 -> vector_int_op_sse PADD l w x y+                   | otherwise -> needLlvm mop+      MO_V_Sub l w | l * widthInBits w == 128 -> vector_int_op_sse PSUB l w x y+                   | otherwise -> needLlvm mop+      MO_V_Mul 16 W8 -> vector_int8x16_mul_sse2 x y+      MO_V_Mul l@8 w@W16 -> vector_int_op_sse PMULL l w x y -- PMULLW (SSE2)+      MO_V_Mul l@4 w@W32 | sse4_1 -> vector_int_op_sse PMULL l w x y -- PMULLD (SSE4.1)+                         | otherwise -> vector_int32x4_mul_sse2 x y+      MO_V_Mul 2 W64 -> vector_int64x2_mul_sse2 x y+      MO_V_Mul {} -> needLlvm mop++      MO_VU_Min l@16 w@W8+                    -> vector_int_op_sse (MINMAX Min (IntVecMinMax False)) l w x y -- PMINUB (SSE2)+      MO_VU_Min l@8 w@W16+        | sse4_1    -> vector_int_op_sse (MINMAX Min (IntVecMinMax False)) l w x y -- PMINUW (SSE4.1)+        | otherwise -> vector_word_minmax_sse Min l w x y+      MO_VU_Min l@4 w@W32+        | sse4_1    -> vector_int_op_sse (MINMAX Min (IntVecMinMax False)) l w x y -- PMINUD (SSE4.1)+        | otherwise -> vector_word_minmax_sse Min l w x y+      MO_VU_Min l@2 w@W64+        | sse4_2    -> vector_word_minmax_sse Min l w x y -- PCMPGTQ requires SSE4.2+        -- The SSE2 version is implemented as a C call (MO_W64X2_Min)+      MO_VU_Min {} -> needLlvm mop+      MO_VU_Max l@16 w@W8+                    -> vector_int_op_sse (MINMAX Max (IntVecMinMax False)) l w x y -- PMAXUB (SSE2)+      MO_VU_Max l@8 w@W16+        | sse4_1    -> vector_int_op_sse (MINMAX Max (IntVecMinMax False)) l w x y -- PMAXUW (SSE4.1)+        | otherwise -> vector_word_minmax_sse Max l w x y+      MO_VU_Max l@4 w@W32+        | sse4_1    -> vector_int_op_sse (MINMAX Max (IntVecMinMax False)) l w x y -- PMAXUD (SSE4.1)+        | otherwise -> vector_word_minmax_sse Max l w x y+      MO_VU_Max l@2 w@W64+        | sse4_2    -> vector_word_minmax_sse Max l w x y -- PCMPGTQ requires SSE4.2+        -- The SSE2 version is implemented as a C call (MO_W64X2_Max)+      MO_VU_Max {} -> needLlvm mop+      MO_VS_Min l@16 w@W8+        | sse4_1    -> vector_int_op_sse (MINMAX Min (IntVecMinMax True)) l w x y -- PMINSB (SSE4.1)+        | otherwise -> vector_int_minmax_sse Min l w x y+      MO_VS_Min l@8 w@W16+                    -> vector_int_op_sse (MINMAX Min (IntVecMinMax True)) l w x y -- PMINSW (SSE2)+      MO_VS_Min l@4 w@W32+        | sse4_1    -> vector_int_op_sse (MINMAX Min (IntVecMinMax True)) l w x y -- PMINSD (SSE4.1)+        | otherwise -> vector_int_minmax_sse Min l w x y+      MO_VS_Min l@2 w@W64+        | sse4_2    -> vector_int_minmax_sse Min l w x y -- PCMPGTQ requires SSE4.2+        -- The SSE2 version is implemented as a C call (MO_I64X2_Min)+      MO_VS_Min {} -> needLlvm mop+      MO_VS_Max l@16 w@W8+        | sse4_1    -> vector_int_op_sse (MINMAX Max (IntVecMinMax True)) l w x y -- PMAXSB (SSE4.1)+        | otherwise -> vector_int_minmax_sse Max l w x y+      MO_VS_Max l@8 w@W16+                    -> vector_int_op_sse (MINMAX Max (IntVecMinMax True)) l w x y -- PMAXSW (SSE2)+      MO_VS_Max l@4 w@W32+        | sse4_1    -> vector_int_op_sse (MINMAX Max (IntVecMinMax True)) l w x y -- PMAXSD (SSE4.1)+        | otherwise -> vector_int_minmax_sse Max l w x y+      MO_VS_Max l@2 w@W64+        | sse4_2    -> vector_int_minmax_sse Max l w x y -- PCMPGTQ requires SSE4.2+        -- The SSE2 version is implemented as a C call (MO_I64X2_Max)+      MO_VS_Max {} -> needLlvm mop++      -- Unary MachOps+      MO_S_Neg {} -> incorrectOperands+      MO_F_Neg {} -> incorrectOperands+      MO_Not {} -> incorrectOperands+      MO_SF_Round {} -> incorrectOperands+      MO_FS_Truncate {} -> incorrectOperands+      MO_SS_Conv {} -> incorrectOperands+      MO_XX_Conv {} -> incorrectOperands+      MO_FF_Conv {} -> incorrectOperands+      MO_UU_Conv {} -> incorrectOperands+      MO_WF_Bitcast {} -> incorrectOperands+      MO_FW_Bitcast  {} -> incorrectOperands+      MO_RelaxedRead {} -> incorrectOperands+      MO_AlignmentCheck {} -> incorrectOperands+      MO_VS_Neg {} -> incorrectOperands+      MO_VF_Neg {} -> incorrectOperands+      MO_V_Broadcast {} -> incorrectOperands+      MO_VF_Broadcast {} -> incorrectOperands++      -- Ternary MachOps+      MO_FMA {} -> incorrectOperands+      MO_V_Insert {} -> incorrectOperands+      MO_VF_Insert {} -> incorrectOperands++  where+    --------------------+    triv_op width instr = trivialCode width op (Just op) x y+                        where op   = instr (intFormat width)++    -- Special case for IMUL for bytes, since the result of IMULB will be in+    -- %ax, the split to %dx/%edx/%rdx and %ax/%eax/%rax happens only for wider+    -- values.+    imulW8 :: CmmExpr -> CmmExpr -> NatM Register+    imulW8 arg_a arg_b = do+        (a_reg, a_code) <- getNonClobberedReg arg_a+        b_code <- getAnyReg arg_b++        let code = a_code `appOL` b_code eax `appOL`+                   toOL [ IMUL2 format (OpReg a_reg) ]+            format = intFormat W8++        return (Fixed format eax code)++    imulMayOflo :: Width -> CmmExpr -> CmmExpr -> NatM Register+    imulMayOflo W8 a b = do+         -- The general case (W16, W32, W64) doesn't work for W8 as its+         -- multiplication doesn't use two registers.+         --+         -- The plan is:+         -- 1. truncate and sign-extend a and b to 8bit width+         -- 2. multiply a' = a * b in 32bit width+         -- 3. copy and sign-extend 8bit from a' to c+         -- 4. compare a' and c: they are equal if there was no overflow+         (a_reg, a_code) <- getNonClobberedReg a+         (b_reg, b_code) <- getNonClobberedReg b+         let+             code = a_code `appOL` b_code `appOL`+                        toOL [+                           MOVSxL II8 (OpReg a_reg) (OpReg a_reg),+                           MOVSxL II8 (OpReg b_reg) (OpReg b_reg),+                           IMUL II32 (OpReg b_reg) (OpReg a_reg),+                           MOVSxL II8 (OpReg a_reg) (OpReg eax),+                           CMP II16 (OpReg a_reg) (OpReg eax),+                           SETCC NE (OpReg eax)+                        ]+         return (Fixed II8 eax code)+    imulMayOflo rep a b = do+         (a_reg, a_code) <- getNonClobberedReg a+         b_code <- getAnyReg b+         let+             shift_amt  = case rep of+                           W16 -> 15+                           W32 -> 31+                           W64 -> 63+                           w -> panic ("shift_amt: " ++ show w)++             format = intFormat rep+             code = a_code `appOL` b_code eax `appOL`+                        toOL [+                           IMUL2 format (OpReg a_reg),   -- result in %edx:%eax+                           SAR format (OpImm (ImmInt shift_amt)) (OpReg eax),+                                -- sign extend lower part+                           SUB format (OpReg edx) (OpReg eax)+                                -- compare against upper+                           -- eax==0 if high part == sign extended low part+                        ]+         return (Fixed format eax code)++    --------------------+    shift_code :: Width+               -> (Format -> Operand -> Operand -> Instr)+               -> CmmExpr+               -> CmmExpr+               -> NatM Register++    {- Case1: shift length as immediate -}+    shift_code width instr x (CmmLit lit)+      -- Handle the case of a shift larger than the width of the shifted value.+      -- This is necessary since x86 applies a mask of 0x1f to the shift+      -- amount, meaning that, e.g., `shr 47, $eax` will actually shift by+      -- `47 & 0x1f == 15`. See #20626.+      | CmmInt n _ <- lit+      , n >= fromIntegral (widthInBits width)+      = getRegister $ CmmLit $ CmmInt 0 width++      | otherwise = do+          x_code <- getAnyReg x+          let+               format = intFormat width+               code dst+                  = x_code dst `snocOL`+                    instr format (OpImm (litToImm lit)) (OpReg dst)+          return (Any format code)++    {- Case2: shift length is complex (non-immediate)+      * y must go in %ecx.+      * we cannot do y first *and* put its result in %ecx, because+        %ecx might be clobbered by x.+      * if we do y second, then x cannot be+        in a clobbered reg.  Also, we cannot clobber x's reg+        with the instruction itself.+      * so we can either:+        - do y first, put its result in a fresh tmp, then copy it to %ecx later+        - do y second and put its result into %ecx.  x gets placed in a fresh+          tmp.  This is likely to be better, because the reg alloc can+          eliminate this reg->reg move here (it won't eliminate the other one,+          because the move is into the fixed %ecx).+      * in the case of C calls the use of ecx here can interfere with arguments.+        We avoid this with the hack described in Note [Evaluate C-call+        arguments before placing in destination registers]+    -}+    shift_code width instr x y{-amount-} = do+        x_code <- getAnyReg x+        let format = intFormat width+        tmp <- getNewRegNat format+        y_code <- getAnyReg y+        let+           code = x_code tmp `appOL`+                  y_code ecx `snocOL`+                  instr format (OpReg ecx) (OpReg tmp)+        return (Fixed format tmp code)++    --------------------+    add_code :: Width -> CmmExpr -> CmmExpr -> NatM Register+    add_code rep x (CmmLit (CmmInt y _))+        | is32BitInteger y+        , rep /= W8 -- LEA doesn't support byte size (#18614)+        = add_int rep x y+    add_code rep x y = trivialCode rep (ADD format) (Just (ADD format)) x y+      where format = intFormat rep+    -- TODO: There are other interesting patterns we want to replace+    --     with a LEA, e.g. `(x + offset) + (y << shift)`.++    --------------------+    sub_code :: Width -> CmmExpr -> CmmExpr -> NatM Register+    sub_code rep x (CmmLit (CmmInt y _))+        | is32BitInteger (-y)+        , rep /= W8 -- LEA doesn't support byte size (#18614)+        = add_int rep x (-y)+    sub_code rep x y = trivialCode rep (SUB (intFormat rep)) Nothing x y++    -- our three-operand add instruction:+    add_int width x y = do+        (x_reg, x_code) <- getSomeReg x+        let+            format = intFormat width+            imm = ImmInt (fromInteger y)+            code dst+               = x_code `snocOL`+                 LEA format+                        (OpAddr (AddrBaseIndex (EABaseReg x_reg) EAIndexNone imm))+                        (OpReg dst)+        --+        return (Any format code)++    ----------------------++    -- See Note [DIV/IDIV for bytes]+    div_code W8 signed quotient x y = do+        let widen | signed    = MO_SS_Conv W8 W16+                  | otherwise = MO_UU_Conv W8 W16+        div_code+            W16+            signed+            quotient+            (CmmMachOp widen [x])+            (CmmMachOp widen [y])++    div_code width signed quotient x y = do+           (y_op, y_code) <- getRegOrMem y -- cannot be clobbered+           x_code <- getAnyReg x+           let+             format = intFormat width+             widen | signed    = CLTD format+                   | otherwise = XOR format (OpReg edx) (OpReg edx)++             instr | signed    = IDIV+                   | otherwise = DIV++             code = y_code `appOL`+                    x_code eax `appOL`+                    toOL [widen, instr format y_op]++             result | quotient  = eax+                    | otherwise = edx++           return (Fixed format result code)++    -----------------------+    -- Vector operations---+    vector_float_op_avx :: (Format -> Operand -> Reg -> Reg -> Instr)+                        -> Length+                        -> Width+                        -> CmmExpr+                        -> CmmExpr+                        -> NatM Register+    vector_float_op_avx instr l w = vector_op_avx_reg (\fmt -> instr fmt . OpReg) format+      where format = case w of+                       W32 -> VecFormat l FmtFloat+                       W64 -> VecFormat l FmtDouble+                       _ -> pprPanic "Floating-point AVX vector operation not supported at this width"+                             (text "width:" <+> ppr w)++    vector_op_avx_reg :: (Format -> Reg -> Reg -> Reg -> Instr)+                      -> Format+                      -> CmmExpr+                      -> CmmExpr+                      -> NatM Register+    vector_op_avx_reg instr format expr1 expr2 = do+      (reg1, exp1) <- getSomeReg expr1+      (reg2, exp2) <- getSomeReg expr2+      let -- opcode src2 src1 dst <==> dst = src1 `opcode` src2+          code dst = exp1 `appOL` exp2 `snocOL`+                     (instr format reg2 reg1 dst)+      return (Any format code)++    vector_float_op_sse :: (Format -> Operand -> Reg -> Instr)+                        -> Length -> Width -> CmmExpr -> CmmExpr -> NatM Register+    vector_float_op_sse instr l w = vector_op_sse instr format+      where format = case w of+                       W32 -> VecFormat l FmtFloat+                       W64 -> VecFormat l FmtDouble+                       _ -> pprPanic "Floating-point SSE vector operation not supported at this width"+                             (text "width:" <+> ppr w)++    vector_int_op_sse :: (Format -> Operand -> Reg -> Instr)+                      -> Length -> Width -> CmmExpr -> CmmExpr -> NatM Register+    vector_int_op_sse instr l w = vector_op_sse instr format+      where format = case w of+                       W8 -> VecFormat l FmtInt8+                       W16 -> VecFormat l FmtInt16+                       W32 -> VecFormat l FmtInt32+                       W64 -> VecFormat l FmtInt64+                       _ -> pprPanic "Integer SSE vector operation not supported at this width"+                              (text "width:" <+> ppr w)++    -- This function is similar to genTrivialCode, but re-using it would require+    -- handling alignment correctly: SSE vector instructions typically require 16-byte+    -- alignment for their memory operand (this restriction is relaxed with VEX-encoded+    -- instructions).+    -- For now, we always load the value into a register and avoid the alignment issue.+    vector_op_sse :: (Format -> Operand -> Reg -> Instr)+                  -> Format+                  -> CmmExpr+                  -> CmmExpr+                  -> NatM Register+    vector_op_sse instr = vector_op_sse_reg (\fmt -> instr fmt . OpReg)++    vector_op_sse_reg :: (Format -> Reg -> Reg -> Instr)+                      -> Format+                      -> CmmExpr+                      -> CmmExpr+                      -> NatM Register+    vector_op_sse_reg instr format expr1 expr2 = do+      config <- getConfig+      exp1_code <- getAnyReg expr1+      (reg2, exp2_code) <- getSomeReg expr2 -- vector registers are never clobbered by an instruction+      tmp <- getNewRegNat format+      let code dst+            -- opcode src2 src1 <==> src1 = src1 `opcode` src2+            | dst == reg2 = exp2_code `snocOL`+                            movInstr config format (OpReg reg2) (OpReg tmp) `appOL` -- MOVU or MOVDQU+                            exp1_code dst `snocOL`+                            instr format tmp dst+            | otherwise = exp2_code `appOL`+                          exp1_code dst `snocOL`+                          instr format reg2 dst+      return (Any format code)+    --------------------+    vector_float_extract :: Length+                         -> Width+                         -> CmmExpr+                         -> CmmExpr+                         -> NatM Register+    vector_float_extract l W32 expr (CmmLit lit) = do+      (r, exp) <- getSomeReg expr+      let format   = VecFormat l FmtFloat+          imm      = litToImm lit+          code dst+            = case lit of+                CmmInt 0 _ -> exp `snocOL` (MOV FF32 (OpReg r) (OpReg dst))+                CmmInt _ _ -> exp `snocOL` (VPSHUFD format imm (OpReg r) dst)+                _          -> pprPanic "Unsupported AVX floating-point vector extract offset" (ppr lit)+      return (Any FF32 code)+    vector_float_extract _ W64 expr (CmmLit lit) = do+      (r, exp) <- getSomeReg expr+      let code dst+            = case lit of+                CmmInt 0 _ -> exp `snocOL`+                              (MOV FF64 (OpReg r) (OpReg dst))+                CmmInt 1 _ -> exp `snocOL`+                              (MOVHLPS FF64 r dst)+                _          -> pprPanic "Unsupported AVX floating-point vector extract offset" (ppr lit)+      return (Any FF64 code)+    vector_float_extract _ w c e =+      pprPanic "Unsupported AVX floating-point vector extract" (pdoc platform c $$ pdoc platform e $$ ppr w)+    -----------------------++    vector_float_extract_sse :: Length+                             -> Width+                             -> CmmExpr+                             -> CmmExpr+                             -> NatM Register+    vector_float_extract_sse l W32 expr (CmmLit lit)+      = do+      (r,exp) <- getSomeReg expr+      let format   = VecFormat l FmtFloat+          imm      = litToImm lit+          code dst+            = case lit of+                CmmInt 0 _ -> exp `snocOL` (MOVU format (OpReg r) (OpReg dst))+                CmmInt _ _ -> exp `snocOL` (PSHUFD format imm (OpReg r) dst)+                _          -> pprPanic "Unsupported SSE floating-point vector extract offset" (ppr lit)+      return (Any FF32 code)+    vector_float_extract_sse _ w c e+      = pprPanic "Unsupported SSE floating-point vector extract" (pdoc platform c $$ pdoc platform e $$ ppr w)+    -----------------------++    -- PEXTRW ("to GPR" variant) is an SSE2 instruction,+    -- whereas PEXTR{B,D,Q} and PEXTRW ("to memory" variant) require SSE4.1.+    vector_int_extract_pextr :: Length+                             -> Width+                             -> CmmExpr+                             -> CmmExpr+                             -> NatM Register+    vector_int_extract_pextr l w expr (CmmLit (CmmInt i _))+      | 0 <= i, i < toInteger l+      = do+      (r, exp) <- getSomeReg expr -- vector registers are never clobbered by an instruction+      let (scalarFormat, vectorFormat) = case w of+            W8 -> (II32, VecFormat l FmtInt8)+            W16 -> (II32, VecFormat l FmtInt16)+            W32 -> (II32, VecFormat l FmtInt32)+            W64 -> (II64, VecFormat l FmtInt64)+            _ -> sorry "Unsupported vector format"+          code dst = exp `snocOL`+                     (PEXTR scalarFormat vectorFormat (ImmInteger i) r (OpReg dst))+      return (Any scalarFormat code)+    vector_int_extract_pextr _ _ _ i+      = pprPanic "Unsupported offset" (pdoc platform i)++    vector_int8x16_extract_sse2 :: CmmExpr+                                -> CmmExpr+                                -> NatM Register+    vector_int8x16_extract_sse2 expr (CmmLit (CmmInt i _))+      | 0 <= i, i < 16+      = do+      (r, exp) <- getSomeReg expr+      let code dst =+            case i `quotRem` 2 of+              (j, 0) -> exp `snocOL`+                        (PEXTR II32 (VecFormat 8 FmtInt16) (ImmInteger j) r (OpReg dst)) -- PEXTRW+              (j, _) -> exp `snocOL`+                        (PEXTR II32 (VecFormat 8 FmtInt16) (ImmInteger j) r (OpReg dst)) `snocOL` -- PEXTRW+                        (SHR II32 (OpImm (ImmInt 8)) (OpReg dst))+      return (Any II8 code)+    vector_int8x16_extract_sse2 _ offset+      = pprPanic "Unsupported offset" (pdoc platform offset)++    vector_int32x4_extract_sse2 :: CmmExpr+                                -> CmmExpr+                                -> NatM Register+    vector_int32x4_extract_sse2 expr (CmmLit (CmmInt i _))+      | 0 <= i, i < 4+      = do+      (r, exp) <- getSomeReg expr+      let fmt = VecFormat 4 FmtInt32+      tmp <- getNewRegNat fmt+      let code dst =+            case i of+              0 -> exp `snocOL`+                   (MOVD fmt II32 (OpReg r) (OpReg dst))+              1 -> exp `snocOL`+                   (PSHUFD fmt (ImmInt 0b01_01_01_01) (OpReg r) tmp) `snocOL` -- tmp <- (r[1],r[1],r[1],r[1])+                   (MOVD fmt II32 (OpReg tmp) (OpReg dst))+              2 -> exp `snocOL`+                   (PSHUFD fmt (ImmInt 0b11_10_11_10) (OpReg r) tmp) `snocOL` -- tmp <- (r[2],r[3],r[2],r[3])+                   (MOVD fmt II32 (OpReg tmp) (OpReg dst))+              _ -> exp `snocOL`+                   (PSHUFD fmt (ImmInt 0b11_11_11_11) (OpReg r) tmp) `snocOL` -- tmp <- (r[3],r[3],r[3],r[3])+                   (MOVD fmt II32 (OpReg tmp) (OpReg dst))+      return (Any II32 code)+    vector_int32x4_extract_sse2 _ offset+      = pprPanic "Unsupported offset" (pdoc platform offset)++    vector_int64x2_extract_sse2 :: CmmExpr+                                -> CmmExpr+                                -> NatM Register+    vector_int64x2_extract_sse2 expr (CmmLit lit)+      = do+      (r, exp) <- getSomeReg expr+      let fmt = VecFormat 2 FmtInt64+      tmp <- getNewRegNat fmt+      let code dst =+            case lit of+              CmmInt 0 _ -> exp `snocOL`+                            (MOVD fmt II64 (OpReg r) (OpReg dst))+              CmmInt 1 _ -> exp `snocOL`+                            (MOVHLPS FF64 r tmp) `snocOL`+                            (MOVD fmt II64 (OpReg tmp) (OpReg dst))+              _          -> panic "Error in offset while unpacking"+      return (Any II64 code)+    vector_int64x2_extract_sse2 _ offset+      = pprPanic "Unsupported offset" (pdoc platform offset)++    vector_int8x16_mul_sse2 :: CmmExpr -> CmmExpr -> NatM Register+    vector_int8x16_mul_sse2 expr1 expr2 = do+      -- use two SSE2 PMULLW (low 16 bits of int16 multiplication) operations+      (reg1, exp1) <- getSomeReg expr1+      (reg2, exp2) <- getSomeReg expr2+      let format = VecFormat 16 FmtInt8+          format16 = VecFormat 8 FmtInt16 -- for PMULLW+      tmp1lo <- getNewRegNat format+      tmp1hi <- getNewRegNat format+      tmp2hi <- getNewRegNat format+      tmp2lo <- getNewRegNat format+      (maskReg, maskCode) <- getSomeReg (CmmLit $ CmmVec $ replicate 8 (CmmInt 0xff W16)) -- (0xff,0,0xff,0,...,0xff,0) :: Int8X16+      let code = exp1 `appOL` exp2 `appOL` maskCode `snocOL`+                 (MOVDQU format (OpReg reg1) (OpReg tmp1lo)) `snocOL` -- tmp1lo <- reg1+                 (MOVDQU format (OpReg reg2) (OpReg tmp2lo)) `snocOL` -- tmp2lo <- reg2+                 (PUNPCKLBW format (OpReg reg1) tmp1lo) `snocOL`      -- tmp1lo <- (tmp1lo[0],reg1[0],tmp1lo[1],reg1[1],...,tmp1lo[7],reg1[7]); The first operand does not really matter+                 (PUNPCKLBW format (OpReg reg2) tmp2lo) `snocOL`      -- tmp2lo <- (tmp2lo[0],reg2[0],tmp2lo[1],reg2[1],...,tmp2lo[7],reg2[7]); The first operand does not really matter+                 (MOVDQU format (OpReg reg1) (OpReg tmp1hi)) `snocOL` -- tmp1hi <- reg1+                 (MOVDQU format (OpReg reg2) (OpReg tmp2hi)) `snocOL` -- tmp2hi <- reg2+                 (PUNPCKHBW format (OpReg reg1) tmp1hi) `snocOL`      -- tmp1hi <- (tmp1hi[8],reg1[8],tmp1hi[9],reg1[9],...,tmp1hi[15],reg1[15]); The first operand does not really matter+                 (PMULL format16 (OpReg tmp2lo) tmp1lo) `snocOL`      -- PMULLW; tmp1lo <- (tmp1lo[0]*tmp2lo[0],*,tmp1lo[2]*tmp2lo[2],*,...,tmp1lo[14]*tmp2lo[14],*)+                 (PUNPCKHBW format (OpReg reg2) tmp2hi) `snocOL`      -- tmp2hi <- (tmp2hi[8],reg2[8],tmp2hi[9],reg2[9],...,tmp2hi[15],reg2[15]); The first operand does not really matter+                 (PMULL format16 (OpReg tmp2hi) tmp1hi) `snocOL`      -- PMULLW; tmp1hi <- (tmp1hi[0]*tmp2hi[0],*,tmp1hi[2]*tmp2hi[2],*,...,tmp1hi[14]*tmp2hi[14],*)+                 (PAND format (OpReg maskReg) tmp1lo) `snocOL`        -- tmp1lo <- (tmp1lo[0],0,tmp1lo[2],0,...,tmp1lo[14],0)+                 (PAND format (OpReg maskReg) tmp1hi) `snocOL`        -- tmp1hi <- (tmp1hi[0],0,tmp1hi[2],0,...,tmp1hi[14],0)+                 (PACKUSWB format (OpReg tmp1hi) tmp1lo)              -- tmp1lo <- (tmp1lo[0],tmp1lo[2],...,tmp1lo[14],tmp1hi[0],tmp1hi[2],...tmp1hi[14])+      return (Fixed format tmp1lo code)++    vector_int32x4_mul_sse2 :: CmmExpr -> CmmExpr -> NatM Register+    vector_int32x4_mul_sse2 expr1 expr2 = do+      -- use two SSE2 PMULUDQ (int32 x int32 -> int64 multiplication) operations+      (reg1, exp1) <- getSomeReg expr1+      (reg2, exp2) <- getSomeReg expr2+      let format = VecFormat 4 FmtInt32+      tmpEven <- getNewRegNat format+      tmpOdd1 <- getNewRegNat format+      tmpOdd2 <- getNewRegNat format+      let code dst = exp1 `appOL` exp2 `snocOL`+                     (MOVDQU format (OpReg reg1) (OpReg tmpEven)) `snocOL`                   -- tmpEven <- reg1+                     (PSHUFD format (ImmInt 0b11_11_01_01) (OpReg reg1) tmpOdd1) `snocOL`    -- tmpOdd1 <- (reg1[1],reg1[1],reg1[3],reg1[3])+                     (PMULUDQ format (OpReg reg2) tmpEven) `snocOL`                          -- tmpEven <- (tmpEven[0]*reg2[0],*,tmpEven[2]*reg2[2],*)+                     (PSHUFD format (ImmInt 0b11_11_01_01) (OpReg reg2) tmpOdd2) `snocOL`    -- tmpOdd2 <- (reg2[1],reg2[1],reg2[3],reg2[3])+                     (PMULUDQ format (OpReg tmpOdd2) tmpOdd1) `snocOL`                       -- tmpOdd1 <- (tmpOdd1[0]*tmpOdd2[0],*,tmpOdd1[2]*tmpOdd2[2],*)+                     (PSHUFD format (ImmInt 0b00_00_10_00) (OpReg tmpEven) dst) `snocOL`     -- dst <- (tmpEven[0],tmpEven[2],tmpEven[0],tmpEven[0])+                     (PSHUFD format (ImmInt 0b00_00_10_00) (OpReg tmpOdd1) tmpOdd1) `snocOL` -- tmpOdd1 <- (tmpOdd1[0],tmpOdd1[2],tmpOdd1[0],tmpOdd1[0])+                     (PUNPCKLDQ format (OpReg tmpOdd1) dst)                                  -- dst <- (dst[0],tmpOdd1[0],dst[1],tmpOdd1[1])+      return (Any format code)++    -- TODO: We could use `VPMULLQ` if AVX-512 or AVX10.1 is available.+    vector_int64x2_mul_sse2 :: CmmExpr -> CmmExpr -> NatM Register+    vector_int64x2_mul_sse2 expr1 expr2 = do+      -- implement 64 bit multiplication using 32-bit PMULUDQ multiplication instructions+      -- (lo1 + shiftL hi1 32) * (lo2 + shiftL hi2 32) = lo1 * lo2 + shiftL (lo1 * hi2) 32 + shiftL (lo2 * hi1) 32+      exp1 <- getAnyReg expr1+      exp2 <- getAnyReg expr2+      let format = VecFormat 2 FmtInt64+      reg1 <- getNewRegNat format+      reg2 <- getNewRegNat format+      tmp1Hi <- getNewRegNat format+      tmp2Hi <- getNewRegNat format+      let code dst = exp1 reg1 `appOL` exp2 reg2 `snocOL`+                     (MOVDQU format (OpReg reg1) (OpReg dst)) `snocOL`    -- dst <- reg1+                     (MOVDQU format (OpReg reg1) (OpReg tmp1Hi)) `snocOL` -- tmp1Hi <- reg1+                     (MOVDQU format (OpReg reg2) (OpReg tmp2Hi)) `snocOL` -- tmp2Hi <- reg2+                     (PSRL format (OpImm (ImmInt 32)) tmp1Hi) `snocOL`    -- PSRLQ (logical shift); tmp1Hi <- (tmp1Hi[0] >> 32, tmp1Hi[1] >> 32)+                     (PMULUDQ format (OpReg reg2) dst) `snocOL`           -- dst <- ((dst as Word32X4)[0] * (reg2 as Word32X4)[0] as Word64, (dst as Word32X4)[2] * (reg2 as Word32X4)[2] as Word64)+                     (PSRL format (OpImm (ImmInt 32)) tmp2Hi) `snocOL`    -- PSRLQ (logical shift); tmp2Hi <- (tmp2Hi[0] >> 32, tmp2Hi[1] >> 32)+                     (PMULUDQ format (OpReg reg2) tmp1Hi) `snocOL`        -- tmp1Hi <- ((tmp1Hi as Word32X4)[0] * (reg2 as Word32X4)[0] as Word64, (tmp1Hi as Word32X4)[2] * (reg2 as Word32X4)[2] as Word64)+                     (PMULUDQ format (OpReg reg1) tmp2Hi) `snocOL`        -- tmp2Hi <- ((tmp2Hi as Word32X4)[0] * (reg1 as Word32X4)[0] as Word64, (tmp2Hi as Word32X4)[2] * (reg1 as Word32X4)[2] as Word64)+                     (PADD format (OpReg tmp2Hi) tmp1Hi) `snocOL`         -- PADDQ; tmp1Hi <- (tmp1Hi[0] + tmp2Hi[0], tmp1Hi[1] + tmp2Hi[1])+                     (PSLL format (OpImm (ImmInt 32)) tmp1Hi) `snocOL`    -- PSLLQ; tmp1Hi <- (tmp1Hi[0] << 32, tmp1Hi[1] << 32)+                     (PADD format (OpReg tmp1Hi) dst)                     -- PADDQ; dst <- (dst[0] + tmp1Hi[0], dst[1] + tmp1Hi[1])+      return (Any format code)++    vector_int_minmax_sse :: MinOrMax -> Length -> Width -> CmmExpr -> CmmExpr -> NatM Register+    vector_int_minmax_sse minmax l w expr1 expr2 = do+      -- SSE2 fallback: compute a mask of 0s/1s using PCMPGT, then max a b = (mask & a) | (not mask & b)+      exp1 <- getAnyReg expr1+      exp2 <- getAnyReg expr2+      let format = case w of+            W8 -> VecFormat l FmtInt8+            W16 -> VecFormat l FmtInt16+            W32 -> VecFormat l FmtInt32+            W64 -> VecFormat l FmtInt64+            _  -> panic "Unsupported width"+      reg1 <- getNewRegNat format+      reg2 <- getNewRegNat format+      tmp <- getNewRegNat format+      let codeMin dst = exp1 reg1 `appOL` exp2 reg2 `snocOL`+                        (MOVDQU format (OpReg reg1) (OpReg dst)) `snocOL` -- dst <- reg1+                        (MOVDQU format (OpReg reg2) (OpReg tmp)) `snocOL` -- tmp <- reg2+                        (PCMPGT format (OpReg reg2) dst) `snocOL`         -- dst <- if dst > reg2 then True(-1) else False(0)+                        (PAND format (OpReg dst) tmp) `snocOL`            -- tmp <- tmp & dst; if dst then tmp else 0+                        (PANDN format (OpReg reg1) dst) `snocOL`          -- dst <- ~dst & reg1; if dst then 0 else reg1+                        (POR format (OpReg tmp) dst)                      -- dst <- tmp | dst+          codeMax dst = exp1 reg1 `appOL` exp2 reg2 `snocOL`+                        (MOVDQU format (OpReg reg1) (OpReg dst)) `snocOL` -- dst <- reg1+                        (MOVDQU format (OpReg reg1) (OpReg tmp)) `snocOL` -- tmp <- reg1+                        (PCMPGT format (OpReg reg2) dst) `snocOL`         -- dst <- if dst > reg2 then True(-1) else False(0)+                        (PAND format (OpReg dst) tmp) `snocOL`            -- tmp <- tmp & dst; if dst then tmp else 0+                        (PANDN format (OpReg reg2) dst) `snocOL`          -- dst <- ~dst & reg2; if dst then 0 else reg2+                        (POR format (OpReg tmp) dst)                      -- dst <- tmp | dst+      return $ case minmax of+        Min -> Any format codeMin+        Max -> Any format codeMax++    vector_word_minmax_sse :: MinOrMax -> Length -> Width -> CmmExpr -> CmmExpr -> NatM Register+    vector_word_minmax_sse minmax l w expr1 expr2 = do+      -- SSE2 fallback: compute a mask of 0s/1s using PCMPGT, then max a b = (mask & a) | (not mask & b)+      -- We can use PCMPGT to compare unsigned integers by flipping the most significant bit.+      exp1 <- getAnyReg expr1+      exp2 <- getAnyReg expr2+      let (format, sign) = case w of+            W8 -> (VecFormat l FmtInt8, 0x80)+            W16 -> (VecFormat l FmtInt16, 0x8000)+            W32 -> (VecFormat l FmtInt32, 2^(31 :: Int))+            W64 -> (VecFormat l FmtInt64, 2^(63 :: Int))+            _  -> panic "Unsupported width"+      reg1 <- getNewRegNat format+      reg2 <- getNewRegNat format+      tmp1 <- getNewRegNat format+      tmp2 <- getNewRegNat format+      (signReg, signCode) <- getSomeReg (CmmLit $ CmmVec $ replicate l (CmmInt sign w))+      let codeMin dst = exp1 reg1 `appOL` exp2 reg2 `appOL` signCode `snocOL`+                        (MOVDQU format (OpReg reg1) (OpReg dst)) `snocOL`  -- dst <- reg1+                        (MOVDQU format (OpReg reg2) (OpReg tmp1)) `snocOL` -- tmp1 <- reg2+                        (MOVDQU format (OpReg reg2) (OpReg tmp2)) `snocOL` -- tmp2 <- reg2+                        (PXOR format (OpReg signReg) dst) `snocOL`         -- dst <- dst ^ 2^(w-1)+                        (PXOR format (OpReg signReg) tmp1) `snocOL`        -- tmp1 < dst ^ 2^(w-1)+                        (PCMPGT format (OpReg tmp1) dst) `snocOL`          -- dst <- if dst > tmp1 then True(-1) else False(0)+                        (PAND format (OpReg dst) tmp2) `snocOL`            -- tmp2 <- tmp2 & dst; if dst then tmp2 else 0+                        (PANDN format (OpReg reg1) dst) `snocOL`           -- dst <- ~dst & reg1; if dst then 0 else reg1+                        (POR format (OpReg tmp2) dst)                      -- dst <- tmp2 | dst+          codeMax dst = exp1 reg1 `appOL` exp2 reg2 `appOL` signCode `snocOL`+                        (MOVDQU format (OpReg reg1) (OpReg dst)) `snocOL`  -- dst <- reg1+                        (MOVDQU format (OpReg reg2) (OpReg tmp1)) `snocOL` -- tmp1 <- reg2+                        (MOVDQU format (OpReg reg1) (OpReg tmp2)) `snocOL` -- tmp2 <- reg1+                        (PXOR format (OpReg signReg) dst) `snocOL`         -- dst <- dst ^ 2^(w-1)+                        (PXOR format (OpReg signReg) tmp1) `snocOL`        -- tmp1 <- tmp1 ^ 2^(w-1)+                        (PCMPGT format (OpReg tmp1) dst) `snocOL`          -- dst <- if dst > tmp1 then True(-1) else False(0)+                        (PAND format (OpReg dst) tmp2) `snocOL`            -- tmp2 <- tmp2 & dst; if dst then tmp2 else 0+                        (PANDN format (OpReg reg2) dst) `snocOL`           -- dst <- ~dst & reg2; if dst then 0 else reg2+                        (POR format (OpReg tmp2) dst)                      -- dst <- tmp2 | dst+      return $ case minmax of+        Min -> Any format codeMin+        Max -> Any format codeMax++    vector_shuffle_floatx4_sse :: Bool -> CmmExpr -> CmmExpr -> [Int] -> NatM Register+    vector_shuffle_floatx4_sse sse4_1 v1 v2 is+      | length is == 4, all (\i -> 0 <= i && i < 8) is = do+        let fmt = VecFormat 4 FmtFloat++            -- A helper function to shuffle a vector `r` in-place using (dst,src) pairs+            -- (r[d0],r[d1],...) <- (r[s0],r[s1],...)+            inplaceShuffle pairs r = do+              let mask = foldl' (\acc (dst,src) -> acc .|. (src `shiftL` (2 * dst))) 0 pairs+              case mask of+                0b11_10_01_00 -> nilOL -- trivial+                0b01_00_01_00 -> unitOL (MOVLHPS fmt r r)+                0b11_10_11_10 -> unitOL (MOVHLPS fmt r r)+                0b01_01_00_00 -> unitOL (UNPCKL fmt (OpReg r) r)+                0b11_11_10_10 -> unitOL (UNPCKH fmt (OpReg r) r)+                _ -> unitOL (SHUF fmt (ImmInt mask) (OpReg r) r)++            -- All elements are from one source vector+            oneSource p0 p1 p2 p3 v = do+              exp <- getAnyReg v+              let code dst = exp dst `appOL`+                             inplaceShuffle [p0,p1,p2,p3] dst+              return $ Any fmt code++            -- Two elements from one vector, other two from the other vector+            twoAndTwo (0,0) (1,1) (2,0) (3,1) v1 v2 = vector_op_sse_reg MOVLHPS fmt v1 v2+            twoAndTwo (2,0) (3,1) (0,0) (1,1) v1 v2 = vector_op_sse_reg MOVLHPS fmt v2 v1+            twoAndTwo (2,2) (3,3) (0,2) (1,3) v1 v2 = vector_op_sse_reg MOVHLPS fmt v1 v2+            twoAndTwo (0,2) (1,3) (2,2) (3,3) v1 v2 = vector_op_sse_reg MOVHLPS fmt v2 v1+            twoAndTwo (0,0) (2,1) (1,0) (3,1) v1 v2 = vector_op_sse UNPCKL fmt v1 v2+            twoAndTwo (1,0) (3,1) (0,0) (2,1) v1 v2 = vector_op_sse UNPCKL fmt v2 v1+            twoAndTwo (0,2) (2,3) (1,2) (3,3) v1 v2 = vector_op_sse UNPCKH fmt v1 v2+            twoAndTwo (1,2) (3,3) (0,2) (2,3) v1 v2 = vector_op_sse UNPCKH fmt v2 v1+            twoAndTwo p0 p1 q0 q1 v1 v2 =+              if sse4_1 && all (\(dst,src) -> dst == src) [p0,p1,q0,q1] then+                let imm = (1 `shiftL` fst q0) .|. (1 `shiftL` fst q1)+                in vector_op_sse (`BLEND` (ImmInt imm)) fmt v1 v2+              else do+                let imm = snd p0 .|. (snd p1 `shiftL` 2) .|. (snd q0 `shiftL` 4) .|. (snd q1 `shiftL` 6)+                reg <- vector_op_sse (`SHUF` (ImmInt imm)) fmt v1 v2+                exp <- anyReg reg+                let code dst = exp dst `appOL`+                               inplaceShuffle [(fst p0,0),(fst p1,1),(fst q0,2),(fst q1,3)] dst+                return $ Any fmt code++            -- Three elements from one vector, the last one from the other vector+            threeAndOne p0 p1 p2 q0 v1 v2+              | sse4_1 = do -- Use INSERTPS+                exp1 <- getAnyReg v1+                (r2, exp2) <- getSomeReg v2+                let imm2 = (snd q0 `shiftL` 6) .|. (fst q0 `shiftL` 4)+                dst <- getNewRegNat fmt+                let code = exp1 dst `appOL` exp2 `appOL`+                           inplaceShuffle [p0,p1,p2,(fst q0,fst q0)] dst `snocOL`+                           (INSERTPS fmt (ImmInt imm2) (OpReg r2) dst)+                return $ Fixed fmt dst code++              | (_, 0) <- q0, 0 `notElem` [snd p0,snd p1,snd p2] = do -- Use MOVSS+                exp1 <- getAnyReg v1+                (r2, exp2) <- getSomeReg v2+                dst <- getNewRegNat fmt+                let code = exp1 dst `appOL` exp2 `snocOL`+                           (MOV fmt (OpReg r2) (OpReg dst)) `appOL`+                           inplaceShuffle [p0,p1,p2,(fst q0,0)] dst+                return $ Fixed fmt dst code++              | otherwise = do -- Use two or three SHUFPSs+                (r1, exp1) <- getSomeReg v1+                exp2 <- getAnyReg v2+                let makeMask i0 i1 i2 i3 = i0 .|. (i1 `shiftL` 2) .|. (i2 `shiftL` 4) .|. (i3 `shiftL` 6)+                let imm1 = makeMask (snd q0) (snd q0) (snd p0) (snd p0)+                    (imm2, pairs) =+                      if fst q0 == 1 then+                        (makeMask 2 1 (snd p1) (snd p2), [(fst p0,0),(fst q0,1),(fst p1,2),(fst p2,3)])+                        -- dst <- (dst[2],dst[1],r1[snd p1],r1[snd p2]) = (v1[snd p0],v2[snd q0],v1[snd p1],v1[snd p2])+                        -- (dst[fst p0],dst[fst q0],dst[fst p1],dst[fst p2]) <- dst+                      else+                        (makeMask 0 2 (snd p1) (snd p2), [(fst q0,0),(fst p0,1),(fst p1,2),(fst p2,3)])+                        -- dst <- (dst[0],dst[2],r1[snd p1],r1[snd p2]) = (v2[snd q0],v1[snd p0],v1[snd p1],v1[snd p2])+                        -- (dst[fst p0],dst[fst q0],dst[fst p1],dst[fst p2]) <- dst+                dst <- getNewRegNat fmt+                let code = exp1 `appOL` exp2 dst `snocOL`+                           (SHUF fmt (ImmInt imm1) (OpReg r1) dst) `snocOL` -- dst <- (dst[snd q0],dst[snd q0],r1[snd p0],r1[snd p0]) = (v2[snd q0],v2[snd q0],v1[snd p0],v1[snd p0])+                           (SHUF fmt (ImmInt imm2) (OpReg r1) dst) `appOL`+                           inplaceShuffle pairs dst+                return $ Fixed fmt dst code++        -- We partition the list of indices into those that refer to the first vector and those that+        -- refer to the second, and handle each case depending on the number of indices in each group.+        let (from_first, from_second) = partition (\(_dstPos, srcPos) -> srcPos < 4) (zip [0..] is)+        case (from_first, map (\(dst, src) -> (dst, src - 4)) from_second) of+          ([p0,p1,p2,p3], []) -> oneSource p0 p1 p2 p3 v1+          ([], [q0,q1,q2,q3]) -> oneSource q0 q1 q2 q3 v2+          ([p0,p1], [q0,q1]) -> twoAndTwo p0 p1 q0 q1 v1 v2+          ([p0], [q0,q1,q2]) -> threeAndOne q0 q1 q2 p0 v2 v1+          ([p0,p1,p2], [q0]) -> threeAndOne p0 p1 p2 q0 v1 v2+          _ -> pprPanic "vector shuffle: cannot occur" (ppr is)+      | otherwise = pprPanic "vector shuffle: wrong indices" (ppr is)++    -- Shuffle with AVX instructions.+    -- The components above 128 bits are shuffled in the same way as the lower 128 bits.+    -- For example, `l == 8 && is == [0,2,5,7]` would represent `shuffleFloatX8# _ _ (# 0#, 2#, 9#, 11#, 4#, 6#, 13#, 15# #)`.+    vector_shuffle_float_avx :: Length -- Vector length. 4 for XMM, 8 for YMM, 16 for ZMM.+                             -> CmmExpr+                             -> CmmExpr+                             -> [Int] -- 4-element list of indices+                             -> NatM Register+    vector_shuffle_float_avx l v1 v2 is+      | length is == 4, all (\i -> 0 <= i && i < 8) is = do+        let fmt = VecFormat l FmtFloat++            -- A helper function to shuffle a vector using (dst,src) pairs+            -- (dst[d0],dst[d1],...) <- (r[s0],r[s1],...)+            inplaceShuffle pairs r dst = do+              let mask = foldl' (\acc (dst,src) -> acc .|. (src `shiftL` (2 * dst))) 0 pairs+              case mask of+                0b11_10_01_00 | r == dst -> nilOL+                              | otherwise -> unitOL (VMOVU fmt (OpReg r) (OpReg dst)) -- trivial+                0b01_00_01_00 | l == 4 -> unitOL (VMOVLHPS fmt r r dst) -- 128-bit only+                0b11_10_11_10 | l == 4 -> unitOL (VMOVHLPS fmt r r dst) -- 128-bit only+                0b01_01_00_00 -> unitOL (VUNPCKL fmt (OpReg r) r dst)+                0b11_11_10_10 -> unitOL (VUNPCKH fmt (OpReg r) r dst)+                _ -> unitOL (VSHUF fmt (ImmInt mask) (OpReg r) r dst)++            -- All elements are from one source vector+            oneSource p0 p1 p2 p3 v = do+              (r, exp) <- getSomeReg v+              let code dst = exp `appOL`+                             inplaceShuffle [p0,p1,p2,p3] r dst+              return $ Any fmt code++            -- Two elements from one vector, other two from the other vector+            twoAndTwo (0,0) (1,1) (2,0) (3,1) v1 v2 | l == 4 = vector_op_avx_reg VMOVLHPS fmt v1 v2+            twoAndTwo (2,0) (3,1) (0,0) (1,1) v1 v2 | l == 4 = vector_op_avx_reg VMOVLHPS fmt v2 v1+            twoAndTwo (2,2) (3,3) (0,2) (1,3) v1 v2 | l == 4 = vector_op_avx_reg VMOVHLPS fmt v1 v2+            twoAndTwo (0,2) (1,3) (2,2) (3,3) v1 v2 | l == 4 = vector_op_avx_reg VMOVHLPS fmt v2 v1+            twoAndTwo (0,0) (2,1) (1,0) (3,1) v1 v2 = vector_float_op_avx VUNPCKL l W32 v1 v2+            twoAndTwo (1,0) (3,1) (0,0) (2,1) v1 v2 = vector_float_op_avx VUNPCKL l W32 v2 v1+            twoAndTwo (0,2) (2,3) (1,2) (3,3) v1 v2 = vector_float_op_avx VUNPCKH l W32 v1 v2+            twoAndTwo (1,2) (3,3) (0,2) (2,3) v1 v2 = vector_float_op_avx VUNPCKH l W32 v2 v1+            twoAndTwo p0 p1 q0 q1 v1 v2 =+              if l <= 8 && all (\(dst,src) -> dst == src) [p0,p1,q0,q1] then+                -- VBLENDPS does not support ZMM (no EVEX-encoded variant)+                let imm = (1 `shiftL` fst q0) .|. (1 `shiftL` fst q1)+                    imm' = if l == 4 then imm .|. (imm `shiftL` 4) else imm+                in vector_float_op_avx (`VBLEND` (ImmInt imm')) l W32 v1 v2+              else do+                let imm1 = snd p0 .|. (snd p1 `shiftL` 2) .|. (snd q0 `shiftL` 4) .|. (snd q1 `shiftL` 6)+                reg <- vector_float_op_avx (`VSHUF` (ImmInt imm1)) l W32 v1 v2+                exp <- anyReg reg+                let code dst = exp dst `appOL`+                               inplaceShuffle [(fst p0,0),(fst p1,1),(fst q0,2),(fst q1,3)] dst dst+                return $ Any fmt code++            -- Three elements from one vector, the last one from the other vector+            threeAndOne p0 p1 p2 q0 v1 v2+              | l == 4, (_, 0) <- q0, 0 `notElem` [snd p0,snd p1,snd p2] = do -- Use VMOVSS (128-bit only)+                (r1, exp1) <- getSomeReg v1+                (r2, exp2) <- getSomeReg v2+                let code dst = exp1 `appOL` exp2 `snocOL`+                               (VMOV_MERGE fmt r2 r1 dst) `appOL`+                               inplaceShuffle [p0,p1,p2,(fst q0,0)] dst dst+                return $ Any fmt code++              | l == 4 = do -- Use VINSERTPS (128-bit only)+                (r1, exp1) <- getSomeReg v1+                (r2, exp2) <- getSomeReg v2+                let i = case [0, 1, 2, 3] \\ [snd p0, snd p1, snd p2] of+                          i:_ -> i -- We can clobber this position of r1+                          _ -> panic "cannot occur"+                    imm = (snd q0 `shiftL` 6) .|. (i `shiftL` 4)+                    code dst = exp1 `appOL` exp2 `snocOL`+                               (VINSERTPS fmt (ImmInt imm) (OpReg r2) r1 dst) `appOL`+                               inplaceShuffle [p0,p1,p2,(fst q0,i)] dst dst+                return $ Any fmt code++              | otherwise = do -- Use two or three VSHUFPSs+                (r1, exp1) <- getSomeReg v1+                exp2 <- getAnyReg v2+                let makeMask i0 i1 i2 i3 = i0 .|. (i1 `shiftL` 2) .|. (i2 `shiftL` 4) .|. (i3 `shiftL` 6)+                let imm1 = makeMask (snd q0) (snd q0) (snd p0) (snd p0)+                    (imm2, pairs) =+                      if fst q0 == 1 then+                        (makeMask 2 1 (snd p1) (snd p2), [(fst p0,0),(fst q0,1),(fst p1,2),(fst p2,3)])+                        -- dst <- (dst[2],dst[1],r1[snd p1],r1[snd p2]) = (v1[snd p0],v2[snd q0],v1[snd p1],v1[snd p2])+                        -- (dst[fst p0],dst[fst q0],dst[fst p1],dst[fst p2]) <- dst+                      else+                        (makeMask 0 2 (snd p1) (snd p2), [(fst q0,0),(fst p0,1),(fst p1,2),(fst p2,3)])+                        -- dst <- (dst[0],dst[2],r1[snd p1],r1[snd p2]) = (v2[snd q0],v1[snd p0],v1[snd p1],v1[snd p2])+                        -- (dst[fst p0],dst[fst q0],dst[fst p1],dst[fst p2]) <- dst+                dst <- getNewRegNat fmt+                let code = exp1 `appOL` exp2 dst `snocOL`+                           (VSHUF fmt (ImmInt imm1) (OpReg r1) dst dst) `snocOL` -- dst <- (dst[snd q0],dst[snd q0],r1[snd p0],r1[snd p0]) = (v2[snd q0],v2[snd q0],v1[snd p0],v1[snd p0])+                           (VSHUF fmt (ImmInt imm2) (OpReg r1) dst dst) `appOL`+                           inplaceShuffle pairs dst dst+                return $ Fixed fmt dst code++        -- We partition the list of indices into those that refer to the first vector and those that+        -- refer to the second, and handle each case depending on the number of indices in each group.+        let (from_first, from_second) = partition (\(_dstPos, srcPos) -> srcPos < 4) (zip [0..] is)+        case (from_first, map (\(dst, src) -> (dst, src - 4)) from_second) of+          ([p0,p1,p2,p3], []) -> oneSource p0 p1 p2 p3 v1+          ([], [q0,q1,q2,q3]) -> oneSource q0 q1 q2 q3 v2+          ([p0,p1], [q0,q1]) -> twoAndTwo p0 p1 q0 q1 v1 v2+          ([p0], [q0,q1,q2]) -> threeAndOne q0 q1 q2 p0 v2 v1+          ([p0,p1,p2], [q0]) -> threeAndOne p0 p1 p2 q0 v1 v2+          _ -> pprPanic "vector shuffle: cannot occur" (ppr is)+      | otherwise = pprPanic "vector shuffle: wrong indices" (ppr is)++    vector_shuffle_doublex2_sse :: CmmExpr -> CmmExpr -> [Int] -> NatM Register+    vector_shuffle_doublex2_sse v1 v2 is+      | [i0, i1] <- is =+        let fmt = VecFormat 2 FmtDouble+        in case (i0, i1) of+          -- Trivial cases+          (0, 1) -> getRegister' platform is32Bit v1+          (2, 3) -> getRegister' platform is32Bit v2++          -- MOVSD/UNPCKLPD/UNPCKHPD have shorter encoding than SHUFPD+          -- If SSE4.1 is available, BLENDPD could also be used in place of MOVSD (the encoding is longer though)+          (0, 3) -> vector_op_sse (\_ src -> MOV fmt src . OpReg) fmt v2 v1 -- MOVSD+          (2, 1) -> vector_op_sse (\_ src -> MOV fmt src . OpReg) fmt v1 v2 -- MOVSD+          _ | i0 == i1 -> do+            exp <- getAnyReg (if i0 <= 1 then v1 else v2)+            let unpck = if i0 == 0 || i0 == 2+                        then UNPCKL+                        else UNPCKH+                code dst = exp dst `snocOL`+                           (unpck fmt (OpReg dst) dst)+            return (Any fmt code)+          (0, 2) -> vector_op_sse UNPCKL fmt v1 v2+          (2, 0) -> vector_op_sse UNPCKL fmt v2 v1+          (1, 3) -> vector_op_sse UNPCKH fmt v1 v2+          (3, 1) -> vector_op_sse UNPCKH fmt v2 v1++          -- SHUFPD+          (1, 2) -> vector_op_sse (`SHUF` (ImmInt 0b01)) fmt v1 v2+          (3, 0) -> vector_op_sse (`SHUF` (ImmInt 0b01)) fmt v2 v1+          (1, 0) -> do+            exp <- getAnyReg v1+            let code dst = exp dst `snocOL`+                           (SHUF fmt (ImmInt 0b01) (OpReg dst) dst)+            return (Any fmt code)+          (3, 2) -> do+            exp <- getAnyReg v2+            let code dst = exp dst `snocOL`+                           (SHUF fmt (ImmInt 0b01) (OpReg dst) dst)+            return (Any fmt code)+          _ -> pprPanic "vector shuffle: indices out of bounds 0 <= i <= 3" (ppr is)+      | otherwise = pprPanic "vector shuffle: wrong number of indices (expected 2)" (ppr is)++    -- Shuffle with AVX instructions.+    -- The components above 128 bits are shuffled in the same way as the lower 128 bits.+    -- For example, `l == 4 && is == [0,3]` would represent `shuffleDoubleX4# _ _ (# 0#, 5#, 2#, 7# #)`.+    vector_shuffle_double_avx :: Length -- Vector length. 2 for XMM, 4 for YMM, 8 for ZMM.+                              -> CmmExpr+                              -> CmmExpr+                              -> [Int] -- 2-element list of indices+                              -> NatM Register+    vector_shuffle_double_avx l v1 v2 is+      | [i0, i1] <- is =+        let fmt = VecFormat l FmtDouble+            repeatShufpdMask m = case l of+              8 -> m .|. (m `shiftL` 2) .|. (m `shiftL` 4) .|. (m `shiftL` 6)+              4 -> m .|. (m `shiftL` 2)+              _ -> m+        in case (i0, i1) of+          -- Trivial cases+          (0, 1) -> getRegister' platform is32Bit v1+          (2, 3) -> getRegister' platform is32Bit v2++          -- VMOVSD/VUNPCKLPD/VUNPCKHPD have shorter encoding than VSHUFPD+          (0, 3) | l == 2 -> do+                   (r1, exp1) <- getSomeReg v1+                   (r2, exp2) <- getSomeReg v2+                   let code dst = exp1 `appOL` exp2 `snocOL`+                                  (VMOV_MERGE fmt r1 r2 dst) -- VMOVSD+                   return (Any fmt code)+                 | otherwise -> vector_float_op_avx (`VSHUF` (ImmInt $ repeatShufpdMask 0b10)) l W64 v1 v2+          (2, 1) | l == 2 -> do+                   (r1, exp1) <- getSomeReg v1+                   (r2, exp2) <- getSomeReg v2+                   let code dst = exp1 `appOL` exp2 `snocOL`+                                  (VMOV_MERGE fmt r2 r1 dst) -- VMOVSD+                   return (Any fmt code)+                 | otherwise -> vector_float_op_avx (`VSHUF` (ImmInt $ repeatShufpdMask 0b10)) l W64 v2 v1+          _ | i0 == i1 -> do+            (r, exp) <- getSomeReg (if i0 <= 1 then v1 else v2)+            let unpck = if i0 == 0 || i0 == 2+                        then VUNPCKL+                        else VUNPCKH+                code dst = exp `snocOL`+                           (unpck fmt (OpReg r) r dst)+            return (Any fmt code)+          (0, 2) -> vector_float_op_avx VUNPCKL l W64 v1 v2+          (2, 0) -> vector_float_op_avx VUNPCKL l W64 v2 v1+          (1, 3) -> vector_float_op_avx VUNPCKH l W64 v1 v2+          (3, 1) -> vector_float_op_avx VUNPCKH l W64 v2 v1++          -- SHUFPD+          (1, 2) -> vector_float_op_avx (`VSHUF` (ImmInt $ repeatShufpdMask 0b01)) l W64 v1 v2+          (3, 0) -> vector_float_op_avx (`VSHUF` (ImmInt $ repeatShufpdMask 0b01)) l W64 v2 v1+          (1, 0) -> do+            (r, exp) <- getSomeReg v1+            let code dst = exp `snocOL`+                           (VSHUF fmt (ImmInt $ repeatShufpdMask 0b01) (OpReg r) r dst)+            return (Any fmt code)+          (3, 2) -> do+            (r, exp) <- getSomeReg v2+            let code dst = exp `snocOL`+                           (VSHUF fmt (ImmInt $ repeatShufpdMask 0b01) (OpReg r) r dst)+            return (Any fmt code)+          _ -> pprPanic "vector shuffle: indices out of bounds 0 <= i <= 3" (ppr is)+      | otherwise = pprPanic "vector shuffle: wrong number of indices (expected 2)" (ppr is)++    isZeroVecLit :: CmmExpr -> Bool+    isZeroVecLit (CmmLit (CmmVec elems)) = all (\lit -> case lit of CmmInt 0 _ -> True; _ -> False) elems+    isZeroVecLit _ = False++    vector_shuffle_int128_common :: Bool -> Format -> CmmExpr -> CmmExpr -> [Int] -> Maybe (NatM Register)+    vector_shuffle_int128_common sse4_1 fmt v1 v2 is+      | length is == n, all (\i -> 0 <= i && i < 2 * n) is = if+        -- Trivial cases+        | is == [0..n-1] -> Just $ getRegister' platform is32Bit v1+        | is == [n..2*n-1] -> Just $ getRegister' platform is32Bit v2++        -- We would like to emit PXOR for these trivial cases, instead of PSLLDQ.+        -- These conditions can be generalized to the cases where all elements are equal,+        -- or more generally, a constant-folding rule.+        | v1IsZero, all (< n) is -> Just $ getRegister' platform is32Bit v1+        | v2IsZero, all (>= n) is -> Just $ getRegister' platform is32Bit v2++        -- PSLLDQ: v2 == 0 && is == [n..(2n-1),...,n..(2n-1);0,1,2,3,...,n-i-1]+        | v2IsZero, (z, js) <- span (>= n) is, and (zipWith (==) js [0..]) -> Just $ do+          exp1 <- getAnyReg v1+          let code dst = exp1 dst `snocOL`+                         (PSLLDQ fmt (ImmInt (widthInBytes * length z)) dst)+          return (Any fmt code)++        -- PSLLDQ: v1 == 0 && is == [0..(n-1),...,0..(n-1);n,n+1,...,2n-i-1]+        | v1IsZero, (z, js) <- span (< n) is, and (zipWith (==) js [n..]) -> Just $ do+          exp2 <- getAnyReg v2+          let code dst = exp2 dst `snocOL`+                         (PSLLDQ fmt (ImmInt (widthInBytes * length z)) dst)+          return (Any fmt code)++        -- PSRLDQ: v2 == 0 && is == [i,i+1,...,n-2,n-1;n..(2n-1),...,n..(2n-1)]+        | v2IsZero, (js, z) <- span (< n) is, all (>= n) z, and (zipWith (==) (reverse js) [n-1,n-2..]) -> Just $ do+          exp1 <- getAnyReg v1+          let code dst = exp1 dst `snocOL`+                         (PSRLDQ fmt (ImmInt (widthInBytes * length z)) dst)+          return (Any fmt code)++        -- PSRLDQ: v1 == 0 && is == [n+i,...,2n-2,2n-1;0..(n-1),...,0..(n-1)]+        | v1IsZero, (js, z) <- span (>= n) is, all (< n) z, and (zipWith (==) (reverse js) [2*n-1,2*n-2..]) -> Just $ do+          exp2 <- getAnyReg v2+          let code dst = exp2 dst `snocOL`+                         (PSRLDQ fmt (ImmInt (widthInBytes * length z)) dst)+          return (Any fmt code)++        -- PALIGNR (SSSE3) or PSLLDQ + PSRLDQ: is == [i,i+1,...,n-2,n-1;n,n+1,...,n+i-1]+        | (js, ks) <- span (< n) is, and (zipWith (==) (reverse js) [n-1,n-2..]), and (zipWith (==) ks [n..]) -> Just $ do+          ssse3 <- ssse3Enabled+          let amountInBytes = widthInBytes * length ks+          if ssse3+            then vector_op_sse (`PALIGNR` (ImmInt amountInBytes)) fmt v2 v1+            else do+              exp1 <- getAnyReg v1+              exp2 <- getAnyReg v2+              tmp <- getNewRegNat fmt+              let code dst = exp1 tmp `snocOL`+                             (PSRLDQ fmt (ImmInt amountInBytes) tmp) `appOL`+                             exp2 dst `snocOL`+                             (PSLLDQ fmt (ImmInt (16 - amountInBytes)) dst) `snocOL`+                             (POR fmt (OpReg tmp) dst)+              return (Any fmt code)++        -- PALIGNR (SSSE3) or PSLLDQ + PSRLDQ: is == [n+i,n+i+1,...,2n-2,2n-1;0,1,...,i-1]+        | (js, ks) <- span (>= n) is, and (zipWith (==) (reverse js) [2*n-1,2*n-2..]), and (zipWith (==) ks [0..]) -> Just $ do+          ssse3 <- ssse3Enabled+          let amountInBytes = widthInBytes * length ks+          if ssse3+            then vector_op_sse (`PALIGNR` (ImmInt amountInBytes)) fmt v1 v2+            else do+              exp1 <- getAnyReg v1+              exp2 <- getAnyReg v2+              tmp <- getNewRegNat fmt+              let code dst = exp2 tmp `snocOL`+                             (PSRLDQ fmt (ImmInt amountInBytes) tmp) `appOL`+                             exp1 dst `snocOL`+                             (PSLLDQ fmt (ImmInt (16 - amountInBytes)) dst) `snocOL`+                             (POR fmt (OpReg tmp) dst)+              return (Any fmt code)++        -- PBLENDW (SSE4.1): map (`mod` n) is == [0,1,...,n-1] if widthInBytes >= 2+        | sse4_1, widthInBytes >= 2, and (zipWith (\i j -> i `rem` n == j) is [0..]) -> Just $ do+          let k = widthInBytes `quot` 2+              m = bit k - 1+              imm = foldr (\i acc -> if i >= n then (acc `shiftL` k) .|. m else acc `shiftL` k) 0 is+          vector_op_sse (`PBLENDW` (ImmInt imm)) fmt v1 v2++        | otherwise -> Nothing++      | otherwise = pprPanic "vector shuffle: wrong indices" (ppr is)+      where+        (n, widthInBytes) = case fmt of+          VecFormat 16 FmtInt8 -> (16, 1)+          VecFormat 8 FmtInt16 -> (8, 2)+          VecFormat 4 FmtInt32 -> (4, 4)+          VecFormat 2 FmtInt64 -> (2, 8)+          _ -> pprPanic "Invalid format" (ppr fmt)+        v1IsZero = isZeroVecLit v1+        v2IsZero = isZeroVecLit v2++    vector_shuffle_int8x16 :: Bool -> CmmExpr -> CmmExpr -> [Int] -> NatM Register+    vector_shuffle_int8x16 sse4_1 v1 v2 is+      | Just commonCase <- vector_shuffle_int128_common sse4_1 fmt v1 v2 is = commonCase+      | otherwise = do+        ssse3 <- ssse3Enabled+        let fmtInt16X8 = VecFormat 8 FmtInt16+            v1IsZero = isZeroVecLit v1+            v2IsZero = isZeroVecLit v2+            tryInt16X8Mask [] = Just []+            tryInt16X8Mask (j0:j1:js)+              | even j0, j1 == j0 + 1 = (j0 `quot` 2 :) <$> tryInt16X8Mask js+            tryInt16X8Mask _ = Nothing+        if+          -- PUNPCKLBW / PUNPCKHBW+          | [0,16,1,17,2,18,3,19,4,20,5,21,6,22,7,23] <- is -> vector_op_sse PUNPCKLBW fmt v1 v2+          | [16,0,17,1,18,2,19,3,20,4,21,5,22,6,23,7] <- is -> vector_op_sse PUNPCKLBW fmt v2 v1+          | [8,24,9,25,10,26,11,27,12,28,13,29,14,30,15,31] <- is -> vector_op_sse PUNPCKHBW fmt v1 v2+          | [24,8,25,9,26,10,27,11,28,12,29,13,30,14,31,15] <- is -> vector_op_sse PUNPCKHBW fmt v2 v1++          -- PSHUFB (SSSE3)+          | ssse3, all (< 16) is || v2IsZero -> do+            exp1 <- getAnyReg v1+            let mask1 = CmmVec $ map (\i -> CmmInt (toInteger $ if i < 16 then i else 255) W8) is+            Amode amode1 amode_code1 <- memConstant (mkAlignment 16) mask1+            let code dst = exp1 dst `appOL`+                           amode_code1 `snocOL`+                           (PSHUFB fmt (OpAddr amode1) dst)+            return (Any fmt code)++          -- PSHUFB (SSSE3)+          | ssse3, all (>= 16) is || v1IsZero -> do+            exp2 <- getAnyReg v2+            let mask2 = CmmVec $ map (\i -> CmmInt (toInteger $ if i >= 16 then i - 16 else 255) W8) is+            Amode amode2 amode_code2 <- memConstant (mkAlignment 16) mask2+            let code dst = exp2 dst `appOL`+                           amode_code2 `snocOL`+                           (PSHUFB fmt (OpAddr amode2) dst)+            return (Any fmt code)++          -- PBLENDW (SSE4.1): js <- tryInt16X8Mask is, map (`mod` 8) js == [0,1,...,7]+          | sse4_1, Just js <- tryInt16X8Mask is, and (zipWith (\i j -> i `rem` 8 == j) js [0..]) -> do+            let imm = foldr (\i acc -> if i >= 8 then (acc `shiftL` 1) .|. 1 else acc `shiftL` 1) 0 js+            vector_op_sse (`PBLENDW` (ImmInt imm)) fmt v1 v2++          -- General case with SSSE3: PSHUFB + PSHUFB + POR+          | ssse3 -> do+            exp1 <- getAnyReg v1+            exp2 <- getAnyReg v2+            tmp1 <- getNewRegNat fmt+            let mask1 = CmmVec $ map (\i -> CmmInt (toInteger $ if i < 16 then i else 255) W8) is+                mask2 = CmmVec $ map (\i -> CmmInt (toInteger $ if i >= 16 then i - 16 else 255) W8) is+            Amode amode1 amode_code1 <- memConstant (mkAlignment 16) mask1+            Amode amode2 amode_code2 <- memConstant (mkAlignment 16) mask2+            let code dst = exp1 tmp1 `appOL` exp2 dst `appOL`+                           amode_code1 `snocOL`+                           (PSHUFB fmt (OpAddr amode1) tmp1) `appOL`+                           amode_code2 `snocOL`+                           (PSHUFB fmt (OpAddr amode2) dst) `snocOL`+                           (POR fmt (OpReg tmp1) dst)+            return (Any fmt code)++          -- General case with SSE2: GPR + MOVQ + PUNPCKLQDQ+          | otherwise -> do+            (r1, exp1) <- getSomeReg v1+            (r2, exp2) <- getSomeReg v2+            tmp <- getNewRegNat II64+            tmpLo <- getNewRegNat II64+            tmpHi <- getNewRegNat II64+            tmpXmm <- getNewRegNat fmt+            dst <- getNewRegNat fmt+            let place8Bits srcPos dstPos dst =+                  -- Assumption: 0 <= srcPos < 32, 0 <= dstPos < 8+                  -- tmp <- (src[srcPos] `shiftR` ((srcPos `rem` 16) * 8)) .&. 0xff+                  -- dst <- dst .|. (tmp `shiftL` (dstPos * 8))+                  let r = if srcPos < 16 then r1 else r2+                  in case (srcPos `rem` 16) `quotRem` 2 of+                      (k, 0) -> toOL [ PEXTR II32 fmtInt16X8 (ImmInt k) r (OpReg tmp)+                                     , MOVZxL II8 (OpReg tmp) (OpReg tmp)+                                     , SHL II64 (OpImm (ImmInt (8 * dstPos))) (OpReg tmp)+                                     , OR II64 (OpReg tmp) (OpReg dst)+                                     ]+                      (k, _) -> (PEXTR II32 fmtInt16X8 (ImmInt k) r (OpReg tmp)) `consOL`+                                ((case dstPos of+                                    0 -> unitOL (SHR II32 (OpImm (ImmInt 8)) (OpReg tmp))+                                    1 -> unitOL (AND II32 (OpImm (ImmInt 0xff00)) (OpReg tmp))+                                    _ -> toOL [ AND II32 (OpImm (ImmInt 0xff00)) (OpReg tmp)+                                              , SHL II64 (OpImm (ImmInt (8 * (dstPos - 1)))) (OpReg tmp) ]) `snocOL`+                                 (OR II64 (OpReg tmp) (OpReg dst)))+                makeInt8x8OnGPR dst js = (XOR II32 (OpReg dst) (OpReg dst)) `consOL`+                                         concatOL [ place8Bits srcPos dstPos dst | (srcPos, dstPos) <- zip js [0..] ]+                code = exp1 `appOL` exp2 `appOL`+                       makeInt8x8OnGPR tmpLo (take 8 is) `snocOL`+                       (MOVD II64 fmt (OpReg tmpLo) (OpReg dst)) `appOL`+                       makeInt8x8OnGPR tmpHi (drop 8 is) `snocOL`+                       (MOVD II64 fmt (OpReg tmpHi) (OpReg tmpXmm)) `snocOL`+                       (PUNPCKLQDQ fmt (OpReg tmpXmm) dst)+            return (Fixed fmt dst code)+      where fmt = VecFormat 16 FmtInt8++    vector_shuffle_int16x8 :: Bool -> CmmExpr -> CmmExpr -> [Int] -> NatM Register+    vector_shuffle_int16x8 sse4_1 v1 v2 is@(i0:i1:i2:i3:i4567@[i4,i5,i6,i7])+      | Just commonCase <- vector_shuffle_int128_common sse4_1 fmt v1 v2 is = commonCase+      | otherwise = do+        (r1, exp1) <- getSomeReg v1+        (r2, exp2) <- getSomeReg v2+        let -- shufL src dst k0 k1 k2 k3 (0 <= k_i < 4):+            --   dst <- (src[k0],src[k1],src[k2],src[k3],src[4],src[5],src[6],src[7])+            shufL src dst 0 1 2 3 | src == dst = nilOL+                                  | otherwise = unitOL (MOVDQU fmt (OpReg src) (OpReg dst))+            shufL src dst k0 k1 k2 k3 = let imm = k0 + (k1 `shiftL` 2) + (k2 `shiftL` 4) + (k3 `shiftL` 6)+                                        in unitOL (PSHUFLW fmt (ImmInt imm) (OpReg src) dst)+            -- shufH src dst k0 k1 k2 k3 (4 <= k_i < 8):+            --   dst <- (src[0],src[1],src[2],src[3],src[k0],src[k1],src[k2],src[k3])+            shufH src dst 4 5 6 7 | src == dst = nilOL+                                  | otherwise = unitOL (MOVDQU fmt (OpReg src) (OpReg dst))+            shufH src dst k0 k1 k2 k3 = let imm = (k0 - 4) + ((k1 - 4) `shiftL` 2) + ((k2 - 4) `shiftL` 4) + ((k3 - 4) `shiftL` 6)+                                        in unitOL (PSHUFHW fmt (ImmInt imm) (OpReg src) dst)++            shufLHImm src dst immLo immHi = case (immLo, immHi) of+              (0b11_10_01_00, 0b11_10_01_00)+                | src == dst -> nilOL+                | otherwise -> unitOL (MOVDQU fmt (OpReg src) (OpReg dst))+              (0b11_10_01_00, _) -> unitOL (PSHUFHW fmt (ImmInt immHi) (OpReg src) dst)+              (_, 0b11_10_01_00) -> unitOL (PSHUFLW fmt (ImmInt immLo) (OpReg src) dst)+              (_, _) -> toOL [PSHUFLW fmt (ImmInt immLo) (OpReg src) dst,+                              PSHUFHW fmt (ImmInt immHi) (OpReg dst) dst]++            -- ks = [k0,...,k7]+            -- Assumption: 0 <= k_i < 4 for 0 <= i < 4, 4 <= k_i < 8 for 4 <= i < 8+            -- dst <- (src[k0],...,src[k7])+            shufLH src dst ks+              = let (k_lo, k_hi) = splitAt 4 ks+                    immLo = foldr (\k acc -> (acc `shiftL` 2) + k) 0 k_lo+                    immHi = foldr (\k acc -> (acc `shiftL` 2) + (k - 4)) 0 k_hi+                in shufLHImm src dst immLo immHi++            -- shufRev src dst j0 j1 j2 j3 j4 j5 j6 j7:+            -- Assumption: [j0,j1,j2,j3] `elem` permutations [0,1,2,3] && [j4,j5,j6,j7] `elem` permutations [4,5,6,7]:+            --   dst[j0] <- src[0]; dst[j1] <- src[1]; dst[j2] <- src[2]; dst[j3] <- src[3];+            --   dst[j4] <- src[4]; dst[j5] <- src[5]; dst[j6] <- src[6]; dst[j7] <- src[7];+            shufRev src dst _j0 j1 j2 j3 _j4 j5 j6 j7+              = let immLo = (1 `shiftL` (2 * j1)) + (2 `shiftL` (2 * j2)) + (3 `shiftL` (2 * j3))+                    immHi = (1 `shiftL` (2 * (j5 - 4))) + (2 `shiftL` (2 * (j6 - 4))) + (3 `shiftL` (2 * (j7 - 4)))+                in shufLHImm src dst immLo immHi+            i0123 = [i0, i1, i2, i3]+        if+          -- PSHUFLW + PSHUFHW+          | all (\i -> i < 4) i0123+          , all (\i -> 4 <= i && i < 8) i4567+          -> do+            let code dst = exp1 `appOL`+                           shufLH r1 dst is+            return (Any fmt code)++          -- PSHUFLW + PSHUFHW+          | all (\i -> 8 <= i && i < 12) i0123+          , all (\i -> 12 <= i) i4567+          -> do+            let code dst = exp2 `appOL`+                           shufLH r2 dst (map (subtract 8) is)+            return (Any fmt code)++          -- PSHUF{L,H}W + PBLENDW (SSE4.1)+          | sse4_1+          , all (\i -> i `rem` 8 < 4) i0123+          , all (\i -> 4 <= i `rem` 8) i4567+          -> do+            tmp <- getNewRegNat fmt+            let imm = foldl' (\acc (i,p) -> if i >= 8 then setBit acc p else acc) 0 (zip is [0..])+                js = zipWith (\i p -> if i >= 8 then p else i) is [0..]+                ks = zipWith (\i p -> if i >= 8 then i - 8 else p) is [0..]+                code dst = exp1 `appOL` exp2 `appOL`+                           shufLH r2 tmp ks `appOL`+                           shufLH r1 dst js `snocOL`+                           (PBLENDW fmt (ImmInt imm) (OpReg tmp) dst)+            return (Any fmt code)++          -- PSHUFLW + PSHUFLW + PUNPCKLWD + PSHUFLW + PSHUFHW+          | all (\i -> i < 4 || (8 <= i && i < 12)) is+          , ([(j0, k0), (j1, k1)], [(j2, k2), (j3, k3)]) <- partition (\(_, i) -> i < 4) [(0, i0), (1, i1), (2, i2), (3, i3)]+          , ([(j4, k4), (j5, k5)], [(j6, k6), (j7, k7)]) <- partition (\(_, i) -> i < 4) [(4, i4), (5, i5), (6, i6), (7, i7)]+          -> do+            tmp1 <- getNewRegNat fmt+            tmp2 <- getNewRegNat fmt+            let code dst = exp1 `appOL` exp2 `appOL`+                           shufL r1 tmp1 k0 k1 k4 k5 `appOL`+                           shufL r2 tmp2 (k2 - 8) (k3 - 8) (k6 - 8) (k7 - 8) `snocOL`+                           (PUNPCKLWD fmt (OpReg tmp2) tmp1) `appOL`+                           shufRev tmp1 dst j0 j2 j1 j3 j4 j6 j5 j7+            return (Any fmt code)++          -- PSHUFHW + PSHUFHW + PUNPCKHWD + PSHUFLW + PSHUFHW+          | all (\i -> (4 <= i && i < 8) || 12 <= i) is+          , ([(j0, k0), (j1, k1)], [(j2, k2), (j3, k3)]) <- partition (\(_, i) -> i < 8) [(0, i0), (1, i1), (2, i2), (3, i3)]+          , ([(j4, k4), (j5, k5)], [(j6, k6), (j7, k7)]) <- partition (\(_, i) -> i < 8) [(4, i4), (5, i5), (6, i6), (7, i7)]+          -> do+            tmp1 <- getNewRegNat fmt+            tmp2 <- getNewRegNat fmt+            let code dst = exp1 `appOL` exp2 `appOL`+                           shufH r1 tmp1 k0 k1 k4 k5 `appOL`+                           shufH r2 tmp2 (k2 - 8) (k3 - 8) (k6 - 8) (k7 - 8) `snocOL`+                           (PUNPCKHWD fmt (OpReg tmp2) tmp1) `appOL`+                           shufRev tmp1 dst j0 j2 j1 j3 j4 j6 j5 j7+            return (Any fmt code)++          -- Generic implementation+          | otherwise -> do+            tmp0 <- getNewRegNat II32+            tmps <- replicateM 7 (getNewRegNat II32)+            let code dst = exp1 `appOL` exp2 `appOL`+                           toOL [ PEXTR II32 fmt (ImmInt i') r (OpReg tmp)+                                | (i, tmp) <- zip is (tmp0:tmps)+                                , let (i', r) = if i < 8 then (i, r1) else (i - 8, r2)+                                ] `snocOL`+                           (MOVD II32 fmt (OpReg tmp0) (OpReg dst)) `appOL`+                           toOL [ PINSR II32 fmt (ImmInt i) (OpReg tmp) dst+                                | (i, tmp) <- zip [1..] tmps+                                ]+            return (Any fmt code)+      where fmt = VecFormat 8 FmtInt16+    vector_shuffle_int16x8 _ _ _ is = pprPanic "vector shuffle: wrong number of indices (expected 8)" (ppr is)++    vector_shuffle_int32x4 :: Bool -> CmmExpr -> CmmExpr -> [Int] -> NatM Register+    vector_shuffle_int32x4 sse4_1 v1 v2 is+      | Just commonCase <- vector_shuffle_int128_common sse4_1 fmt v1 v2 is = commonCase+      | otherwise = do+        let -- `pshufd imm src dst` is equivalent to `PSHUFD fmt (ImmInt imm) (OpReg src) dst`+            pshufd 0b11_10_01_00 src dst+              | src == dst = nilOL+              | otherwise = unitOL (MOVDQU fmt (OpReg src) (OpReg dst))+            pshufd imm src dst = unitOL (PSHUFD fmt (ImmInt imm) (OpReg src) dst)++            -- PSHUFD (composeImm imm1 imm2) src dst == (PSHUFD imm1 src tmp; PSHUFD imm2 tmp dst)+            composeMask :: Int -> Int -> Int+            composeMask imm1 imm2 = foldr (\i acc -> let j = (imm2 `shiftR` (2 * i)) .&. 3+                                                     in (imm1 `shiftR` (2 * j) .&. 3) .|. (acc `shiftL` 2)+                                          ) 0 [0..3]++            makeMask :: [(Int, Int)] -- List of (dst,src). If src == -1, the value there can be anything.+                     -> Int+            makeMask m = foldl' (.|.) 0 [ src `shiftL` (2 * dst) | dst <- [0..3], let src = fromMaybe dst (mfilter (>= 0) $ lookup dst m) ]++            twoAndTwo p0@(1,_) p1@(3,_) q0@(0,_) q1@(2,_) imm4 v1 v2 = twoAndTwo' q0 q1 p0 p1 imm4 v2 v1+            twoAndTwo p0 p1 q0 q1 imm4 v1 v2 = twoAndTwo' p0 p1 q0 q1 imm4 v1 v2+            twoAndTwo' p0 p1 q0 q1 imm4 v1 v2 = do+              (r1, exp1) <- getSomeReg v1+              (r2, exp2) <- getSomeReg v2+              tmp <- getNewRegNat fmt+              let (instr, imm1, imm2) =+                    if all (\(_,i) -> 2 <= i || i == -1) [p0,p1,q0,q1] then+                      -- The inputs are all from higher lanes+                      (PUNPCKHDQ, makeMask [(2,snd p0),(3,snd p1)], makeMask [(2,snd q0),(3,snd q1)])+                    else+                      (PUNPCKLDQ, makeMask [(0,snd p0),(1,snd p1)], makeMask [(0,snd q0),(1,snd q1)])+                  imm3 = makeMask [(fst p0,0),(fst q0,1),(fst p1,2),(fst q1,3)]+                  code dst = exp1 `appOL` exp2 `appOL`+                             pshufd imm2 r2 tmp `appOL`             -- tmp <- (*,*,r2[snd q0],r2[snd q1]) or (r2[snd q0],r2[snd q1],*,*)+                             pshufd imm1 r1 dst `snocOL`            -- dst <- (*,*,r1[snd p0],r1[snd p1]) or (r1[snd p0],r1[snd p1],*,*)+                             instr fmt (OpReg tmp) dst `appOL`      -- dst <- (dst[0],tmp[0],dst[1],tmp[1]) = (r1[snd p0],r2[snd q0],r1[snd p1],r2[snd q1])+                             pshufd (composeMask imm3 imm4) dst dst -- (dst[fst p0],dst[fst q0],dst[fst p1],dst[fst q1]) <- dst+              return $ Any fmt code++            threeAndOne p0 p1 p2 q0+              | snd p0 == snd p1 = twoAndTwo p0 p2 q0 (fst p1,-1) (makeMask [(fst p0,fst p0),(fst p1,fst p0),(fst p2,fst p2),(fst q0,fst q0)])+              | snd p0 == snd p2 = twoAndTwo p0 p1 q0 (fst p2,-1) (makeMask [(fst p0,fst p0),(fst p1,fst p1),(fst p2,fst p0),(fst q0,fst q0)])+              | snd p1 == snd p2 = twoAndTwo p0 p1 q0 (fst p2,-1) (makeMask [(fst p0,fst p0),(fst p1,fst p1),(fst p2,fst p1),(fst q0,fst q0)])+              | otherwise = \v1 v2 -> do+                (r1, exp1) <- getSomeReg v1+                (r2, exp2) <- getSomeReg v2+                tmp1 <- getNewRegNat fmt+                if sse4_1+                  then do+                    let imm1 = makeMask [p0,p1,p2]+                        imm2 = makeMask [q0]+                        imm3 = foldl' (.|.) 0 [ (if i == fst q0 then 0 else 3) `shiftL` (2 * i) | i <- [0..3] ]+                    let code dst = exp1 `appOL` exp2 `appOL`+                                   pshufd imm1 r1 tmp1 `appOL`+                                   pshufd imm2 r2 dst `snocOL`+                                   PBLENDW fmt (ImmInt imm3) (OpReg tmp1) dst+                    return $ Any fmt code+                  else do+                    tmp2 <- getNewRegNat fmt+                    tmp3 <- getNewRegNat fmt+                    let imm1 = snd q0 .|. 0b11_10_01_00+                        imm2 = snd p1 .|. 0b11_10_01_00+                        imm3 = snd p0 .|. (snd p2 `shiftL` 2) .|. 0b11_10_00_00+                        imm6 = makeMask [(fst q0,0),(fst p0,1),(fst p1,2),(fst p2,3)]+                        code dst = exp1 `appOL` exp2 `appOL`+                                   pshufd imm1 r2 tmp1 `appOL`              -- tmp1 <- (y0,*,*,*)+                                   pshufd imm2 r1 tmp2 `appOL`              -- tmp2 <- (x1,*,*,*)+                                   pshufd imm3 r1 tmp3 `snocOL`             -- tmp3 <- (x0,x2,*,*)+                                   PUNPCKLDQ fmt (OpReg tmp2) tmp1 `snocOL` -- tmp1 <- unpckldq tmp1 tmp2 = (y0,x1,*,*)+                                   PUNPCKLDQ fmt (OpReg tmp3) tmp1 `appOL`  -- tmp1 <- unpckldq tmp1 tmp3 = (y0,x0,x1,x2)+                                   pshufd imm6 tmp1 dst                     -- dst <- shuffle tmp1+                    return $ Any fmt code++        let (from_first, from_second) = partition (\(_dstPos,srcPos) -> srcPos < 4) (zip [0..] is)+        case (from_first, map (\(dstPos,srcPos) -> (dstPos, srcPos - 4)) from_second) of+          ([p0,p1,p2,p3], []) -> do+            (r, exp) <- getSomeReg v1+            let imm = makeMask [p0,p1,p2,p3]+                code dst = exp `appOL` pshufd imm r dst+            return $ Any fmt code++          ([], [q0,q1,q2,q3]) -> do+            (r, exp) <- getSomeReg v2+            let imm = makeMask [q0,q1,q2,q3]+                code dst = exp `appOL` pshufd imm r dst+            return $ Any fmt code++          ([p0,p1], [q0,q1]) -> twoAndTwo p0 p1 q0 q1 0b11_10_01_00 v1 v2+          ([p0], [q0,q1,q2]) -> threeAndOne q0 q1 q2 p0 v2 v1+          ([p0,p1,p2], [q0]) -> threeAndOne p0 p1 p2 q0 v1 v2++          _ -> pprPanic "vector shuffle: cannot occur" (ppr is)+      where fmt = VecFormat 4 FmtInt32++    vector_shuffle_int64x2 :: Bool -> CmmExpr -> CmmExpr -> [Int] -> NatM Register+    vector_shuffle_int64x2 sse4_1 v1 v2 is+      | Just commonCase <- vector_shuffle_int128_common sse4_1 fmt v1 v2 is = commonCase+      | otherwise = case is of+        -- PUNPCKLQDQ / PUNPCKHQDQ+        [i, i'] | i == i' -> do+          exp <- getAnyReg $ if i < 2 then v1 else v2+          let instr = if i == 0 || i == 2+                      then PUNPCKLQDQ+                      else PUNPCKHQDQ+              code dst = exp dst `snocOL`+                         (instr fmt (OpReg dst) dst)+          return $ Any fmt code+        [0, 2] -> vector_op_sse PUNPCKLQDQ fmt v1 v2+        [2, 0] -> vector_op_sse PUNPCKLQDQ fmt v2 v1+        [1, 3] -> vector_op_sse PUNPCKHQDQ fmt v1 v2+        [3, 1] -> vector_op_sse PUNPCKHQDQ fmt v2 v1++        -- PSHUFD+        [1, 0] -> do+          (r1, exp1) <- getSomeReg v1+          let code dst = exp1 `snocOL`+                         (PSHUFD fmt (ImmInt 0b01_00_11_10) (OpReg r1) dst)+          return $ Any fmt code+        [3, 2] -> do+          (r2, exp2) <- getSomeReg v2+          let code dst = exp2 `snocOL`+                         (PSHUFD fmt (ImmInt 0b01_00_11_10) (OpReg r2) dst)+          return $ Any fmt code++        -- Others:+        -- If SSE4.1 is available, use PBLENDW (see vector_shuffle_int128_common).+        -- Otherwise, we resort to SHUFPD.+        [0, 3] -> vector_op_sse (\_ -> SHUF doubleFormat (ImmInt 2)) fmt v1 v2+        [2, 1] -> vector_op_sse (\_ -> SHUF doubleFormat (ImmInt 2)) fmt v2 v1++        -- [0, 1], [2, 3], [1, 2], [3, 0] are covered by the common cases++        -- Indices are checked in vector_shuffle_int128_common, so the following line should be unreachable:+        _ -> pprPanic "vector shuffle: wrong number of indices (expected 2)" (ppr is)+      where fmt = VecFormat 2 FmtInt64+            doubleFormat = VecFormat 2 FmtDouble+++getRegister' platform _is32Bit (CmmMachOp mop [x, y, z]) = do -- ternary MachOps+  avx    <- avxEnabled+  sse4_1 <- sse4_1Enabled+  case mop of+      -- Floating point fused multiply-add operations @ ± x*y ± z@+      MO_FMA var l w+        | l * widthInBits w > 256+        -> sorry "Please use -fllvm for wide vector FMA support"+        | otherwise+        -> genFMA3Code l w var x y z++      -- Ternary vector operations+      MO_VF_Insert l W32  | l == 4 -> vector_floatx4_insert_sse sse4_1 x y z+                          | otherwise ->+         sorry $ "FloatX" ++ show l ++ "# insert operations require -fllvm"+           -- SIMD NCG TODO:+           --+           --   - add support for FloatX8, FloatX16.+      MO_VF_Insert l W64  -> vector_double_insert avx l x y z+      MO_V_Insert 16 W8 | sse4_1 -> vector_int_insert_pinsr 16 W8 x y z+                        | otherwise -> vector_int8x16_insert_sse2 x y z+      MO_V_Insert 8 W16 -> vector_int_insert_pinsr 8 W16 x y z -- PINSRW (SSE2)+      MO_V_Insert 4 W32 | sse4_1 -> vector_int_insert_pinsr 4 W32 x y z+                        | otherwise -> vector_int32x4_insert_sse2 x y z+      MO_V_Insert 2 W64 | sse4_1 -> vector_int_insert_pinsr 2 W64 x y z+                        | otherwise -> vector_int64x2_insert_sse2 x y z+      MO_V_Insert _ _ -> sorry "Unsupported integer vector insert operation; please use -fllvm"++      _other -> pprPanic "getRegister(x86) - ternary CmmMachOp (1)"+                  (pprMachOp mop)++  where+    -- SIMD NCG TODO:+    --+    --   - add support for FloatX8, FloatX16.+    vector_floatx4_insert_sse :: Bool+                              -> CmmExpr+                              -> CmmExpr+                              -> CmmExpr+                              -> NatM Register+    vector_floatx4_insert_sse sse4_1 vecExpr valExpr (CmmLit (CmmInt offset _))+      | sse4_1 = do+        (r, exp)    <- getNonClobberedReg valExpr+        fn          <- getAnyReg vecExpr+        let fmt      = VecFormat 4 FmtFloat+            imm      = litToImm (CmmInt (offset `shiftL` 4) W32)+            code dst = exp `appOL`+                      (fn dst) `snocOL`+                      (INSERTPS fmt imm (OpReg r) dst)+         in return $ Any fmt code+      | otherwise = do -- SSE <= 3+        (r, exp)    <- getNonClobberedReg valExpr+        fn          <- getAnyReg vecExpr+        let fmt      = VecFormat 4 FmtFloat+        tmp <- getNewRegNat fmt+        let code dst+              = case offset of+                  0 -> exp `appOL`+                      (fn dst) `snocOL`+                      -- The following MOV compiles to MOVSS instruction and merges two vectors+                      (MOV fmt (OpReg r) (OpReg dst))  -- dst <- (r[0],dst[1],dst[2],dst[3])+                  1 -> exp `appOL`+                      (fn dst) `snocOL`+                      (MOVU fmt (OpReg dst) (OpReg tmp)) `snocOL`  -- tmp <- dst+                      (UNPCKL fmt (OpReg r) dst) `snocOL`          -- dst <- (dst[0],r[0],dst[1],r[1])+                      (SHUF fmt (ImmInt 0xe4) (OpReg tmp) dst)     -- dst <- (dst[0],dst[1],tmp[2],tmp[3])+                  2 -> exp `appOL`+                       (fn dst) `snocOL`+                       (MOVU fmt (OpReg dst) (OpReg tmp)) `snocOL`  -- tmp <- dst+                       (MOV fmt (OpReg r) (OpReg tmp)) `snocOL`     -- tmp <- (r[0],tmp[1],tmp[2],tmp[3]) with MOVSS+                       (SHUF fmt (ImmInt 0xc4) (OpReg tmp) dst)     -- dst <- (dst[0],dst[1],tmp[0],tmp[3])+                  3 -> exp `appOL`+                       (fn dst) `snocOL`+                       (MOVU fmt (OpReg dst) (OpReg tmp)) `snocOL`  -- tmp <- dst+                       (MOV fmt (OpReg r) (OpReg tmp)) `snocOL`     -- tmp <- (r[0],tmp[1],tmp[2],tmp[3]) with MOVSS+                       (SHUF fmt (ImmInt 0x24) (OpReg tmp) dst)     -- dst <- (dst[0],dst[1],tmp[2],tmp[0])+                  _ -> panic "MO_VF_Insert FloatX4: unsupported offset"+         in return $ Any fmt code+    vector_floatx4_insert_sse _ _ _ offset+      = pprPanic "Unsupported vector insert operation" $+          vcat+            [ text "FloatX4#"+            , text "offset:" <+> pdoc platform offset ]+++    -- SIMD NCG TODO:+    --+    --   - add support for DoubleX4#, DoubleX8#.+    vector_double_insert :: Bool+                         -> Length+                         -> CmmExpr+                         -> CmmExpr+                         -> CmmExpr+                         -> NatM Register+    -- DoubleX2+    vector_double_insert avx len@2 vecExpr valExpr (CmmLit offset)+      = do+        (valReg, valExp) <- getNonClobberedReg valExpr+        (vecReg, vecExp) <- getSomeReg vecExpr -- NB: vector regs never clobbered by instruction+        let movu = if avx then VMOVU else MOVU+            fmt = VecFormat len FmtDouble+            code dst+              = case offset of+                  CmmInt 0 _ -> valExp `appOL`+                                vecExp `snocOL`+                                (movu (VecFormat 2 FmtDouble) (OpReg vecReg) (OpReg dst)) `snocOL`+                                -- The following MOV compiles to MOVSD instruction and merges two vectors+                                (MOV (VecFormat 2 FmtDouble) (OpReg valReg) (OpReg dst))+                  CmmInt 1 _ -> valExp `appOL`+                                vecExp `snocOL`+                                (movu (VecFormat 2 FmtDouble) (OpReg vecReg) (OpReg dst)) `snocOL`+                                (SHUF fmt (ImmInt 0b00) (OpReg valReg) dst)+                  _ -> pprPanic "MO_VF_Insert DoubleX2: unsupported offset" (ppr offset)+         in return $ Any fmt code+    vector_double_insert _ _ _ _ _ =+      sorry "Unsupported floating-point vector insert operation; please use -fllvm"+    -- For DoubleX4: use VSHUFPD.+    -- For DoubleX8: use something like vinsertf64x2 followed by vpblendd?++    -- SIMD NCG TODO:+    --+    --   - only supports 128-bit vector types (Int64X2, Int32X4, Int16X8, Int8X16),+    --     add support for 256-bit and 512-bit vector types.++    -- PINSRW is an SSE2 instruction, whereas PINSR{B,D,Q} require SSE4.1.+    vector_int_insert_pinsr :: HasCallStack => Length+                            -> Width+                            -> CmmExpr+                            -> CmmExpr+                            -> CmmExpr+                            -> NatM Register+    vector_int_insert_pinsr len w vecExpr valExpr (CmmLit (CmmInt offset _))+      | 0 <= offset, offset < toInteger len+      = do+        (valReg, valExp) <- getNonClobberedReg valExpr+        vecCode <- getAnyReg vecExpr+        let (scalarFormat, vectorFormat) = case w of+              W8 -> (II32, VecFormat len FmtInt8)+              W16 -> (II32, VecFormat len FmtInt16)+              W32 -> (II32, VecFormat len FmtInt32)+              W64 -> (II64, VecFormat len FmtInt64)+              _ -> sorry "Unsupported vector format"+            code dst = valExp `appOL`+                       (vecCode dst) `snocOL`+                       (PINSR scalarFormat vectorFormat (ImmInteger offset) (OpReg valReg) dst)+        return $ Any vectorFormat code+    vector_int_insert_pinsr _ _ _ _ offset = pprPanic "MO_V_Insert: unsupported offset" (pdoc platform offset)++    vector_int8x16_insert_sse2 :: CmmExpr+                               -> CmmExpr+                               -> CmmExpr+                               -> NatM Register+    vector_int8x16_insert_sse2 vecExpr valExpr (CmmLit (CmmInt offset _))+      | 0 <= offset, offset < 16+      = do+        (valReg, valExp) <- getNonClobberedReg valExpr+        vecCode <- getAnyReg vecExpr+        tmp <- getNewRegNat II32+        let vectorFormat = VecFormat 16 FmtInt8+            code dst+              = case offset `quotRem` 2 of+                  (j, 0) -> valExp `appOL`+                            (vecCode dst) `snocOL`+                            (PEXTR II32 (VecFormat 8 FmtInt16) (ImmInteger j) dst (OpReg tmp)) `snocOL` -- PEXTRW+                            (AND II32 (OpImm (ImmInt 0xff00)) (OpReg tmp)) `snocOL`+                            (MOVZxL II8 (OpReg valReg) (OpReg valReg)) `snocOL`+                            (OR II32 (OpReg valReg) (OpReg tmp)) `snocOL`+                            (PINSR II32 (VecFormat 8 FmtInt16) (ImmInteger j) (OpReg tmp) dst) -- PINSRW+                  (j, _) -> valExp `appOL`+                            (vecCode dst) `snocOL`+                            (PEXTR II32 (VecFormat 8 FmtInt16) (ImmInteger j) dst (OpReg tmp)) `snocOL` -- PEXTRW+                            (MOVZxL II8 (OpReg tmp) (OpReg tmp)) `snocOL`+                            (SHL II32 (OpImm (ImmInt 8)) (OpReg valReg)) `snocOL`+                            (OR II32 (OpReg valReg) (OpReg tmp)) `snocOL`+                            (PINSR II32 (VecFormat 8 FmtInt16) (ImmInteger j) (OpReg tmp) dst) -- PINSRW+        return $ Any vectorFormat code+    vector_int8x16_insert_sse2 _ _ offset = pprPanic "MO_V_Insert: unsupported offset" (pdoc platform offset)++    vector_int32x4_insert_sse2 :: CmmExpr+                               -> CmmExpr+                               -> CmmExpr+                               -> NatM Register+    vector_int32x4_insert_sse2 vecExpr valExpr (CmmLit (CmmInt offset _))+      | 0 <= offset, offset < 4+      = do+        (valReg, valExp) <- getNonClobberedReg valExpr+        vecCode <- getAnyReg vecExpr+        -- Since SSE2 does not have an integer vector instruction to achieve this,+        -- we are forced to either use floating-point vector instructions+        -- or lots of integer vector instructions. (sigh)+        let floatVectorFormat = VecFormat 4 FmtFloat+        tmp1 <- getNewRegNat floatVectorFormat+        tmp2 <- getNewRegNat floatVectorFormat+        let vectorFormat = VecFormat 4 FmtInt32+            code dst+              = case offset of+                  0 -> valExp `appOL`+                       (vecCode dst) `snocOL`+                       (MOVD II32 vectorFormat (OpReg valReg) (OpReg tmp1)) `snocOL`+                       (MOV floatVectorFormat (OpReg tmp1) (OpReg dst)) -- MOVSS; dst <- (tmp1[0],dst[1],dst[2],dst[3])+                  1 -> valExp `appOL`+                       (vecCode tmp1) `snocOL`+                       (MOVD II32 vectorFormat (OpReg valReg) (OpReg dst)) `snocOL` -- dst <- (val,0,0,0)+                       (PUNPCKLQDQ vectorFormat (OpReg tmp1) dst) `snocOL` -- dst <- (dst[0],dst[1],tmp1[0],tmp1[1])+                       (SHUF floatVectorFormat (ImmInt 0b11_10_00_10) (OpReg tmp1) dst) -- SHUFPS; dst <- (dst[2],dst[0],tmp1[2],tmp1[3])+                  2 -> valExp `appOL`+                       (vecCode dst) `snocOL`+                       (MOVD II32 vectorFormat (OpReg valReg) (OpReg tmp1)) `snocOL` -- tmp1 <- (val,0,0,0)+                       (MOVU floatVectorFormat (OpReg dst) (OpReg tmp2)) `snocOL` -- MOVUPS; tmp2 <- dst+                       (SHUF floatVectorFormat (ImmInt 0b01_00_01_11) (OpReg tmp1) tmp2) `snocOL` -- SHUFPS; tmp2 <- (tmp2[3],tmp2[1],tmp1[0],tmp1[1])+                       (SHUF floatVectorFormat (ImmInt 0b00_10_01_00) (OpReg tmp2) dst) -- SHUFPS; dst <- (dst[0],dst[1],tmp2[2],tmp2[0])+                  _ -> valExp `appOL`+                       (vecCode dst) `snocOL`+                       (MOVD II32 vectorFormat (OpReg valReg) (OpReg tmp1)) `snocOL` -- tmp1 <- (val,0,0,0)+                       (SHUF floatVectorFormat (ImmInt 0b11_10_01_00) (OpReg dst) tmp1) `snocOL` -- SHUFPS; tmp1 <- (tmp1[0],tmp1[1],dst[2],dst[3])+                       (SHUF floatVectorFormat (ImmInt 0b00_10_01_00) (OpReg tmp1) dst) -- SHUFPS; dst <- (dst[0],dst[1],tmp1[2],tmp1[0])+        return $ Any vectorFormat code+    vector_int32x4_insert_sse2 _ _ offset = pprPanic "MO_V_Insert: unsupported offset" (pdoc platform offset)++    vector_int64x2_insert_sse2 :: CmmExpr+                               -> CmmExpr+                               -> CmmExpr+                               -> NatM Register+    vector_int64x2_insert_sse2 vecExpr valExpr (CmmLit offset)+      = do+        (valReg, valExp) <- getNonClobberedReg valExpr+        (vecReg, vecExp) <- getSomeReg vecExpr -- NB: vector regs never clobbered by instruction+        let fmt = VecFormat 2 FmtInt64+        tmp <- getNewRegNat fmt+        let code dst+              = case offset of+                  CmmInt 0 _ -> valExp `appOL`+                                vecExp `snocOL`+                                (MOVHLPS FF64 vecReg tmp) `snocOL`+                                (MOVD II64 fmt (OpReg valReg) (OpReg dst)) `snocOL`+                                (PUNPCKLQDQ fmt (OpReg tmp) dst)+                  CmmInt 1 _ -> valExp `appOL`+                                vecExp `snocOL`+                                (MOVDQU fmt (OpReg vecReg) (OpReg dst)) `snocOL`+                                (MOVD II64 fmt (OpReg valReg) (OpReg tmp)) `snocOL`+                                (PUNPCKLQDQ fmt (OpReg tmp) dst)+                  _ -> pprPanic "MO_V_Insert Int64X2: unsupported offset" (ppr offset)+         in return $ Any fmt code+    vector_int64x2_insert_sse2 _ _ offset = pprPanic "MO_V_Insert Int64X2: unsupported offset" (pdoc platform offset)++getRegister' _ _ (CmmMachOp mop (_:_:_:_:_)) =+  pprPanic "getRegister(x86): MachOp with >= 4 arguments" (text $ show mop)++getRegister' platform is32Bit load@(CmmLoad mem ty _)+  | isVecType ty+  = do+    config <- getConfig+    Amode addr mem_code <- getAmode mem+    let code dst =+          mem_code `snocOL`+            movInstr config format (OpAddr addr) (OpReg dst)+    return (Any format code)+  | isFloatType ty+  = do+    Amode addr mem_code <- getAmode mem+    loadAmode (floatFormat width) addr mem_code++  | is32Bit && not (isWord64 ty)+  = do+    let+      instr = case width of+                W8     -> MOVZxL II8+                  -- We always zero-extend 8-bit loads, if we+                  -- can't think of anything better.  This is because+                  -- we can't guarantee access to an 8-bit variant of every register+                  -- (esi and edi don't have 8-bit variants), so to make things+                  -- simpler we do our 8-bit arithmetic with full 32-bit registers.+                _other -> MOV format+    code <- intLoadCode instr mem+    return (Any format code)++  | not is32Bit+  -- Simpler memory load code on x86_64+  = do+    code <- intLoadCode (MOV format) mem+    return (Any format code)++  | otherwise+  = pprPanic "getRegister(x86) CmmLoad" (pdoc platform load)+  where+    format = cmmTypeFormat ty+    width = typeWidth ty++-- Handle symbol references with LEA and %rip-relative addressing.+-- See Note [%rip-relative addressing on x86-64].+getRegister' platform is32Bit (CmmLit lit)+  | is_label lit+  , not is32Bit+  = do let format = cmmTypeFormat (cmmLitType platform lit)+           imm = litToImm lit+           op = OpAddr (AddrBaseIndex EABaseRip EAIndexNone imm)+           code dst = unitOL (LEA format op (OpReg dst))+       return (Any format code)+  where+    is_label (CmmLabel {})        = True+    is_label (CmmLabelOff {})     = True+    is_label (CmmLabelDiffOff {}) = True+    is_label _                    = False++getRegister' platform is32Bit (CmmLit lit) = do+  avx <- avxEnabled++  -- NB: it is important that the code produced here (to load a literal into+  -- a register) doesn't clobber any registers other than the destination+  -- register; the code for generating C calls relies on this property.+  --+  -- In particular, we have:+  --+  -- > loadIntoRegMightClobberOtherReg (CmmLit _) = False+  --+  -- which means that we assume that loading a literal into a register+  -- will not clobber any other registers.++  -- TODO: this function mishandles floating-point negative zero,+  -- because -0.0 == 0.0 returns True and because we represent CmmFloat as+  -- Rational, which can't properly represent negative zero.++  if+    -- Zero: use XOR.+    | isZeroLit lit+    -> let code dst+             | isIntFormat fmt+             = let fmt'+                     | is32Bit+                     = fmt+                     | otherwise+                     -- x86_64: 32-bit xor is one byte shorter,+                     -- and zero-extends to 64 bits+                     = case fmt of+                         II64 -> II32+                         _ -> fmt+               in unitOL (XOR fmt' (OpReg dst) (OpReg dst))+             | avx+             = if float_or_floatvec+               then unitOL (VXOR fmt (OpReg dst) dst dst)+               else unitOL (VPXOR fmt dst dst dst)+             | otherwise+             = if float_or_floatvec+               then unitOL (XOR fmt (OpReg dst) (OpReg dst))+               else unitOL (PXOR fmt (OpReg dst) dst)+       in return $ Any fmt code++    -- Constant vector: use broadcast.+    | VecFormat l sFmt <- fmt+    , CmmVec (f:fs) <- lit+    , all (== f) fs+    -> do let w = scalarWidth sFmt+              broadcast = if isFloatScalarFormat sFmt+                          then MO_VF_Broadcast l w+                          else MO_V_Broadcast l w+          valCode <- getAnyReg (CmmMachOp broadcast [CmmLit f])+          return $ Any fmt valCode++    -- Optimisation for loading small literals on x86_64: take advantage+    -- of the automatic zero-extension from 32 to 64 bits, because the 32-bit+    -- instruction forms are shorter.+    | not is32Bit, isWord64 cmmTy, not (isBigLit lit)+    -> let+          imm = litToImm lit+          code dst = unitOL (MOV II32 (OpImm imm) (OpReg dst))+      in+          return (Any II64 code)++    -- Scalar integer: use an immediate.+    | isIntFormat fmt+    -> let imm = litToImm lit+           code dst = unitOL (MOV fmt (OpImm imm) (OpReg dst))+       in return (Any fmt code)++    -- General case: load literal from data address.+    | otherwise+    -> do let w = formatToWidth fmt+          Amode addr addr_code <- memConstant (mkAlignment $ widthInBytes w) lit+          loadAmode fmt addr addr_code++    where+      cmmTy = cmmLitType platform lit+      fmt = cmmTypeFormat cmmTy+      float_or_floatvec = isFloatOrFloatVecFormat fmt+      isZeroLit (CmmInt i _) = i == 0+      isZeroLit (CmmFloat f _) = f == 0 -- TODO: mishandles negative zero+      isZeroLit (CmmVec fs) = all isZeroLit fs+      isZeroLit _ = False++      isBigLit (CmmInt i _) = i < 0 || i > 0xffffffff+      isBigLit _ = False+        -- note1: not the same as (not.is32BitLit), because that checks for+        -- signed literals that fit in 32 bits, but we want unsigned+        -- literals here.+        -- note2: all labels are small, because we're assuming the+        -- small memory model. See Note [%rip-relative addressing on x86-64].++getRegister' platform _ slot@(CmmStackSlot {}) =+  pprPanic "getRegister(x86) CmmStackSlot" (pdoc platform slot)++intLoadCode :: (Operand -> Operand -> Instr) -> CmmExpr+   -> NatM (Reg -> InstrBlock)+intLoadCode instr mem = do+  Amode src mem_code <- getAmode mem+  return (\dst -> mem_code `snocOL` instr (OpAddr src) (OpReg dst))++-- Compute an expression into *any* register, adding the appropriate+-- move instruction if necessary.+getAnyReg :: HasDebugCallStack => CmmExpr -> NatM (Reg -> InstrBlock)+getAnyReg expr = do+  r <- getRegister expr+  anyReg r++anyReg :: HasDebugCallStack => Register -> NatM (Reg -> InstrBlock)+anyReg (Any _ code)          = return code+anyReg (Fixed rep reg fcode) = do+  config <- getConfig+  return (\dst -> fcode `snocOL` mkRegRegMoveInstr config rep reg dst)++-- A bit like getSomeReg, but we want a reg that can be byte-addressed.+-- Fixed registers might not be byte-addressable, so we make sure we've+-- got a temporary, inserting an extra reg copy if necessary.+getByteReg :: HasDebugCallStack => CmmExpr -> NatM (Reg, InstrBlock)+getByteReg expr = do+  config <- getConfig+  is32Bit <- is32BitPlatform+  if is32Bit+      then do r <- getRegister expr+              case r of+                Any rep code -> do+                    tmp <- getNewRegNat rep+                    return (tmp, code tmp)+                Fixed rep reg code+                    | isVirtualReg reg -> return (reg,code)+                    | otherwise -> do+                        tmp <- getNewRegNat rep+                        return (tmp, code `snocOL` mkRegRegMoveInstr config rep reg tmp)+                    -- ToDo: could optimise slightly by checking for+                    -- byte-addressable real registers, but that will+                    -- happen very rarely if at all.+      else getSomeReg expr -- all regs are byte-addressable on x86_64++-- Another variant: this time we want the result in a register that cannot+-- be modified by code to evaluate an arbitrary expression.+getNonClobberedReg :: HasDebugCallStack => CmmExpr -> NatM (Reg, InstrBlock)+getNonClobberedReg expr = do+  r <- getRegister expr+  config <- getConfig+  let platform = ncgPlatform config+  case r of+    Any rep code -> do+        tmp <- getNewRegNat rep+        return (tmp, code tmp)+    Fixed rep reg code+        -- only certain regs can be clobbered+        | reg `elem` instrClobberedRegs platform+        -> do+                tmp <- getNewRegNat rep+                return (tmp, code `snocOL` mkRegRegMoveInstr config rep reg tmp)+        | otherwise ->+                return (reg, code)++--------------------------------------------------------------------------------++-- | Convert a 'CmmExpr' representing a memory address into an 'Amode'.+--+-- An 'Amode' is a datatype representing a valid address form for the target+-- (e.g. "Base + Index + disp" or immediate) and the code to compute it.+getAmode :: CmmExpr -> NatM Amode+getAmode e = do+   platform <- getPlatform+   let is32Bit = target32Bit platform++   case e of+      CmmRegOff r n+         -> getAmode $ mangleIndexTree r n++      CmmMachOp (MO_Add W64) [CmmReg (CmmGlobal (GlobalRegUse PicBaseReg _)), CmmLit displacement]+         | not is32Bit+         -> return $ Amode (ripRel (litToImm displacement)) nilOL++      -- This is all just ridiculous, since it carefully undoes+      -- what mangleIndexTree has just done.+      CmmMachOp (MO_Sub _rep) [x, CmmLit lit@(CmmInt i _)]+         | is32BitLit platform lit+         -- assert (rep == II32)???+         -> do+            (x_reg, x_code) <- getSomeReg x+            let off = ImmInt (-(fromInteger i))+            return (Amode (AddrBaseIndex (EABaseReg x_reg) EAIndexNone off) x_code)++      CmmMachOp (MO_Add _rep) [x, CmmLit lit]+         | is32BitLit platform lit+         -- assert (rep == II32)???+         -> do+            (x_reg, x_code) <- getSomeReg x+            let off = litToImm lit+            return (Amode (AddrBaseIndex (EABaseReg x_reg) EAIndexNone off) x_code)++      -- Turn (lit1 << n  + lit2) into  (lit2 + lit1 << n) so it will be+      -- recognised by the next rule.+      CmmMachOp (MO_Add rep) [a@(CmmMachOp (MO_Shl _) _), b@(CmmLit _)]+         -> getAmode (CmmMachOp (MO_Add rep) [b,a])++      -- Matches: (x + offset) + (y << shift)+      CmmMachOp (MO_Add _) [CmmRegOff x offset, CmmMachOp (MO_Shl _) [y, CmmLit (CmmInt shift _)]]+         | shift == 0 || shift == 1 || shift == 2 || shift == 3+         -> x86_complex_amode (CmmReg x) y shift (fromIntegral offset)++      CmmMachOp (MO_Add _) [x, CmmMachOp (MO_Shl _) [y, CmmLit (CmmInt shift _)]]+         | shift == 0 || shift == 1 || shift == 2 || shift == 3+         -> x86_complex_amode x y shift 0++      CmmMachOp (MO_Add _) [x, CmmMachOp (MO_Add _) [CmmMachOp (MO_Shl _)+                                                    [y, CmmLit (CmmInt shift _)], CmmLit (CmmInt offset _)]]+         | shift == 0 || shift == 1 || shift == 2 || shift == 3+         && is32BitInteger offset+         -> x86_complex_amode x y shift offset++      CmmMachOp (MO_Add _) [x,y]+         | not (isLit y) -- we already handle valid literals above.+         -> x86_complex_amode x y 0 0++      CmmLit lit@(CmmFloat {})+        -> pprPanic "X86 CodeGen: attempt to use floating-point value as a memory address"+             (ppr lit)++      -- Handle labels with %rip-relative addressing since in general the image+      -- may be loaded anywhere in the 64-bit address space (e.g. on Windows+      -- with high-entropy ASLR). See Note [%rip-relative addressing on x86-64].+      CmmLit lit+         | not is32Bit+         , is_label lit+         -> return (Amode (AddrBaseIndex EABaseRip EAIndexNone (litToImm lit)) nilOL)++      CmmLit lit+         | is32BitLit platform lit+         -> return (Amode (ImmAddr (litToImm lit) 0) nilOL)++      -- Literal with offsets too big (> 32 bits) fails during the linking phase+      -- (#15570). We already handled valid literals above so we don't have to+      -- test anything here.+      CmmLit (CmmLabelOff l off)+         -> getAmode (CmmMachOp (MO_Add W64) [ CmmLit (CmmLabel l)+                                             , CmmLit (CmmInt (fromIntegral off) W64)+                                             ])+      CmmLit (CmmLabelDiffOff l1 l2 off w)+         -> getAmode (CmmMachOp (MO_Add W64) [ CmmLit (CmmLabelDiffOff l1 l2 0 w)+                                             , CmmLit (CmmInt (fromIntegral off) W64)+                                             ])++      -- in case we can't do something better, we just compute the expression+      -- and put the result in a register+      _ -> do+        (reg,code) <- getSomeReg e+        return (Amode (AddrBaseIndex (EABaseReg reg) EAIndexNone (ImmInt 0)) code)+  where+    is_label (CmmLabel{}) = True+    is_label (CmmLabelOff{}) = True+    is_label (CmmLabelDiffOff{}) = True+    is_label _ = False+++-- | Like 'getAmode', but on 32-bit use simple register addressing+-- (i.e. no index register). This stops us from running out of+-- registers on x86 when using instructions such as cmpxchg, which can+-- use up to three virtual registers and one fixed register.+getSimpleAmode :: CmmExpr -> NatM Amode+getSimpleAmode addr = is32BitPlatform >>= \case+  False -> getAmode addr+  True  -> do+    addr_code <- getAnyReg addr+    config <- getConfig+    addr_r <- getNewRegNat (intFormat (ncgWordWidth config))+    let amode = AddrBaseIndex (EABaseReg addr_r) EAIndexNone (ImmInt 0)+    return $! Amode amode (addr_code addr_r)++x86_complex_amode :: CmmExpr -> CmmExpr -> Integer -> Integer -> NatM Amode+x86_complex_amode base index shift offset+  = do (x_reg, x_code) <- getNonClobberedReg base+        -- x must be in a temp, because it has to stay live over y_code+        -- we could compare x_reg and y_reg and do something better here...+       (y_reg, y_code) <- getSomeReg index+       let+           code = x_code `appOL` y_code+           base = case shift of 0 -> 1; 1 -> 2; 2 -> 4; 3 -> 8;+                                n -> panic $ "x86_complex_amode: unhandled shift! (" ++ show n ++ ")"+       return (Amode (AddrBaseIndex (EABaseReg x_reg) (EAIndex y_reg base) (ImmInt (fromIntegral offset)))+               code)+++++-- -----------------------------------------------------------------------------+-- getOperand: sometimes any operand will do.++-- getNonClobberedOperand: the value of the operand will remain valid across+-- the computation of an arbitrary expression, unless the expression+-- is computed directly into a register which the operand refers to+-- (see trivialCode where this function is used for an example).++getNonClobberedOperand :: CmmExpr -> NatM (Operand, InstrBlock)+getNonClobberedOperand (CmmLit lit)+  | Just w <- isSuitableFloatingPointLit_maybe lit = do+    Amode addr code <- memConstant (mkAlignment $ widthInBytes w) lit+    return (OpAddr addr, code)+  | otherwise = do+    platform <- getPlatform+    if is32BitLit platform lit && isIntFormat (cmmTypeFormat (cmmLitType platform lit))+    then return (OpImm (litToImm lit), nilOL)+    else getNonClobberedOperand_generic (CmmLit lit)++getNonClobberedOperand (CmmLoad mem ty _) = do+  is32Bit <- is32BitPlatform+  -- this logic could be simplified+  -- TODO FIXME+  if   (if is32Bit then not (isWord64 ty) else True)+      -- if 32bit and ty is at float/double/simd value+      -- or if 64bit+      --  this could use some eyeballs or i'll need to stare at it more later+    then do+      platform <- ncgPlatform <$> getConfig+      Amode src mem_code <- getAmode mem+      (src',save_code) <-+        if (amodeCouldBeClobbered platform src)+                then do+                   tmp <- getNewRegNat (archWordFormat is32Bit)+                   return (AddrBaseIndex (EABaseReg tmp) EAIndexNone (ImmInt 0),+                           unitOL (LEA (archWordFormat is32Bit)+                                       (OpAddr src)+                                       (OpReg tmp)))+                else+                   return (src, nilOL)+      return (OpAddr src', mem_code `appOL` save_code)+    else+      -- if its a word or gcptr on 32bit?+      getNonClobberedOperand_generic (CmmLoad mem ty NaturallyAligned)++getNonClobberedOperand e = getNonClobberedOperand_generic e++getNonClobberedOperand_generic :: CmmExpr -> NatM (Operand, InstrBlock)+getNonClobberedOperand_generic e = do+  (reg, code) <- getNonClobberedReg e+  return (OpReg reg, code)++amodeCouldBeClobbered :: Platform -> AddrMode -> Bool+amodeCouldBeClobbered platform amode = any (regClobbered platform) (addrModeRegs amode)++regClobbered :: Platform -> Reg -> Bool+regClobbered platform (RegReal (RealRegSingle rr)) = freeReg platform rr+regClobbered _ _ = False++-- getOperand: the operand is not required to remain valid across the+-- computation of an arbitrary expression.+getOperand :: CmmExpr -> NatM (Operand, InstrBlock)++getOperand (CmmLit lit) = case isSuitableFloatingPointLit_maybe lit of+    Just w -> do+        Amode addr code <- memConstant (mkAlignment $ widthInBytes w) lit+        return (OpAddr addr, code)+    Nothing -> do+        platform <- getPlatform+        if is32BitLit platform lit && (isIntFormat $ cmmTypeFormat (cmmLitType platform lit))+            then return (OpImm (litToImm lit), nilOL)+            else getOperand_generic (CmmLit lit)++getOperand (CmmLoad mem ty _) = do+  is32Bit <- is32BitPlatform+  if isIntFormat (cmmTypeFormat ty) && (if is32Bit then not (isWord64 ty) else True)+     then do+       Amode src mem_code <- getAmode mem+       return (OpAddr src, mem_code)+     else+       getOperand_generic (CmmLoad mem ty NaturallyAligned)++getOperand e = getOperand_generic e++getOperand_generic :: CmmExpr -> NatM (Operand, InstrBlock)+getOperand_generic e = do+    (reg, code) <- getSomeReg e+    return (OpReg reg, code)++isOperand :: Platform -> CmmExpr -> Bool+isOperand _ (CmmLoad _ _ _) = True+isOperand platform (CmmLit lit)+                          = is32BitLit platform lit+                          || isSuitableFloatingPointLit lit+isOperand _ _            = False++-- | Given a 'Register', produce a new 'Register' with an instruction block+-- which will check the value for alignment. Used for @-falignment-sanitisation@.+addAlignmentCheck :: Int -> Register -> Register+addAlignmentCheck align reg =+    case reg of+      Fixed fmt reg code -> Fixed fmt reg (code `appOL` check fmt reg)+      Any fmt f          -> Any fmt (\reg -> f reg `appOL` check fmt reg)+  where+    check :: Format -> Reg -> InstrBlock+    check fmt reg =+        assert (isIntFormat fmt) $+        toOL [ TEST fmt (OpImm $ ImmInt $ align-1) (OpReg reg)+             , JXX_GBL NE $ ImmCLbl mkBadAlignmentLabel+             ]++memConstant :: Alignment -> CmmLit -> NatM Amode+memConstant align lit = do+  lbl <- getNewLabelNat+  let rosection = Section ReadOnlyData lbl+  config <- getConfig+  platform <- getPlatform+  (addr, addr_code) <- if target32Bit platform+                       then do dynRef <- cmmMakeDynamicReference+                                             config+                                             DataReference+                                             lbl+                               Amode addr addr_code <- getAmode dynRef+                               return (addr, addr_code)+                       else return (ripRel (ImmCLbl lbl), nilOL)+  let code =+        LDATA rosection (align, CmmStaticsRaw lbl [CmmStaticLit lit])+        `consOL` addr_code+  return (Amode addr code)++-- | Load the value at the given address into any register.+loadAmode :: Format -> AddrMode -> InstrBlock -> NatM Register+loadAmode fmt addr addr_code = do+  config <- getConfig+  let load dst = movInstr config fmt (OpAddr addr) (OpReg dst)+  return $ Any fmt (\ dst -> addr_code `snocOL` load dst)++-- if we want a floating-point literal as an operand, we can+-- use it directly from memory.  However, if the literal is+-- zero, we're better off generating it into a register using+-- xor.+isSuitableFloatingPointLit :: CmmLit -> Bool+isSuitableFloatingPointLit = isJust . isSuitableFloatingPointLit_maybe++isSuitableFloatingPointLit_maybe :: CmmLit -> Maybe Width+isSuitableFloatingPointLit_maybe (CmmFloat f w) = w <$ guard (f /= 0.0)+isSuitableFloatingPointLit_maybe _ = Nothing++getRegOrMem :: CmmExpr -> NatM (Operand, InstrBlock)+getRegOrMem e@(CmmLoad mem ty _) = do+  is32Bit <- is32BitPlatform+  if isIntFormat (cmmTypeFormat ty) && (if is32Bit then not (isWord64 ty) else True)+     then do+       Amode src mem_code <- getAmode mem+       return (OpAddr src, mem_code)+     else do+       (reg, code) <- getNonClobberedReg e+       return (OpReg reg, code)+getRegOrMem e = do+    (reg, code) <- getNonClobberedReg e+    return (OpReg reg, code)++is32BitLit :: Platform -> CmmLit -> Bool+is32BitLit platform _lit+   | target32Bit platform = True+is32BitLit platform lit =+   case lit of+      CmmInt i W64              -> is32BitInteger i+      -- Except on Windows, assume that labels are in the range 0-2^31-1: this+      -- assumes the small memory model. Note [%rip-relative addressing on+      -- x86-64].+      CmmLabel _                -> low_image+      -- however we can't assume that label offsets are in this range+      -- (see #15570)+      CmmLabelOff _ off         -> low_image && is32BitInteger (fromIntegral off)+      CmmLabelDiffOff _ _ off _ -> low_image && is32BitInteger (fromIntegral off)+      _                         -> True+  where+    -- Is the executable image certain to be located below 4GB? As noted in+    -- Note [%rip-relative addressing on x86-64], this is not true on Windows.+    low_image =+      case platformOS platform of+        OSMinGW32 -> False   -- See Note [%rip-relative addressing on x86-64]+        _         -> True+++-- Set up a condition code for a conditional branch.++getCondCode :: CmmExpr -> NatM CondCode++-- yes, they really do seem to want exactly the same!++getCondCode (CmmMachOp mop [x, y])+  =+    case mop of+      MO_F_Eq W32 -> condFltCode EQQ x y+      MO_F_Ne W32 -> condFltCode NE  x y+      MO_F_Gt W32 -> condFltCode GTT x y+      MO_F_Ge W32 -> condFltCode GE  x y+      -- Invert comparison condition and swap operands+      -- See Note [SSE Parity Checks]+      MO_F_Lt W32 -> condFltCode GTT  y x+      MO_F_Le W32 -> condFltCode GE   y x++      MO_F_Eq W64 -> condFltCode EQQ x y+      MO_F_Ne W64 -> condFltCode NE  x y+      MO_F_Gt W64 -> condFltCode GTT x y+      MO_F_Ge W64 -> condFltCode GE  x y+      MO_F_Lt W64 -> condFltCode GTT y x+      MO_F_Le W64 -> condFltCode GE  y x++      _ -> condIntCode (machOpToCond mop) x y++getCondCode other = do+   platform <- getPlatform+   pprPanic "getCondCode(2)(x86,x86_64)" (pdoc platform other)++machOpToCond :: MachOp -> Cond+machOpToCond mo = case mo of+  MO_Eq _   -> EQQ+  MO_Ne _   -> NE+  MO_S_Gt _ -> GTT+  MO_S_Ge _ -> GE+  MO_S_Lt _ -> LTT+  MO_S_Le _ -> LE+  MO_U_Gt _ -> GU+  MO_U_Ge _ -> GEU+  MO_U_Lt _ -> LU+  MO_U_Le _ -> LEU+  _other -> pprPanic "machOpToCond" (pprMachOp mo)++{-  Note [64-bit integer comparisons on 32-bit]+    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~++    When doing these comparisons there are 2 kinds of+    comparisons.++    * Comparison for equality (or lack thereof)++    We use xor to check if high/low bits are+    equal. Then combine the results using or.++    * Other comparisons:++    We first compare the low registers+    and use a subtraction with borrow to compare the high registers.++    For signed numbers the condition is determined by+    the sign and overflow flags agreeing or not+    and for unsigned numbers the condition is the carry flag.++-}++-- @cond(Int|Flt)Code@: Turn a boolean expression into a condition, to be+-- passed back up the tree.++condIntCode :: Cond -> CmmExpr -> CmmExpr -> NatM CondCode+condIntCode cond x y = do platform <- getPlatform+                          condIntCode' platform cond x y++condIntCode' :: Platform -> Cond -> CmmExpr -> CmmExpr -> NatM CondCode++-- 64-bit integer comparisons on 32-bit+-- See Note [64-bit integer comparisons on 32-bit]+condIntCode' platform cond x y+  | target32Bit platform && isWord64 (cmmExprType platform x) = do++  RegCode64 code1 r1hi r1lo <- iselExpr64 x+  RegCode64 code2 r2hi r2lo <- iselExpr64 y++  -- we mustn't clobber r1/r2 so we use temporaries+  tmp1 <- getNewRegNat II32+  tmp2 <- getNewRegNat II32++  let (cond', cmpCode) = intComparison cond r1hi r1lo r2hi r2lo tmp1 tmp2+  return $ CondCode False cond' (code1 `appOL` code2 `appOL` cmpCode)++  where+    intComparison cond r1_hi r1_lo r2_hi r2_lo tmp1 tmp2 =+      case cond of+        -- These don't occur as argument of condIntCode'+        ALWAYS  -> panic "impossible"+        NEG     -> panic "impossible"+        POS     -> panic "impossible"+        CARRY   -> panic "impossible"+        OFLO    -> panic "impossible"+        PARITY  -> panic "impossible"+        NOTPARITY -> panic "impossible"+        -- Special case #1 x == y and x != y+        EQQ -> (EQQ, cmpExact)+        NE  -> (NE, cmpExact)+        -- [x >= y]+        GE  -> (GE, cmpGE)+        GEU -> (GEU, cmpGE)+        -- [x >  y]+        GTT -> (LTT, cmpLE)+        GU  -> (LU, cmpLE)+        -- [x <= y]+        LE  -> (GE, cmpLE)+        LEU -> (GEU, cmpLE)+        -- [x <  y]+        LTT -> (LTT, cmpGE)+        LU  -> (LU, cmpGE)+      where+        cmpExact :: OrdList Instr+        cmpExact =+          toOL+            [ MOV II32 (OpReg r1_hi) (OpReg tmp1)+            , MOV II32 (OpReg r1_lo) (OpReg tmp2)+            , XOR II32 (OpReg r2_hi) (OpReg tmp1)+            , XOR II32 (OpReg r2_lo) (OpReg tmp2)+            , OR  II32 (OpReg tmp1)  (OpReg tmp2)+            ]+        cmpGE = toOL+            [ MOV II32 (OpReg r1_hi) (OpReg tmp1)+            , CMP II32 (OpReg r2_lo) (OpReg r1_lo)+            , SBB II32 (OpReg r2_hi) (OpReg tmp1)+            ]+        cmpLE = toOL+            [ MOV II32 (OpReg r2_hi) (OpReg tmp1)+            , CMP II32 (OpReg r1_lo) (OpReg r2_lo)+            , SBB II32 (OpReg r1_hi) (OpReg tmp1)+            ]++-- memory vs immediate+condIntCode' platform cond (CmmLoad x ty _) (CmmLit lit)+ | is32BitLit platform lit = do+    Amode x_addr x_code <- getAmode x+    let+        imm  = litToImm lit+        code = x_code `snocOL`+                  CMP (cmmTypeFormat ty) (OpImm imm) (OpAddr x_addr)+    --+    return (CondCode False cond code)++-- anything vs zero, using a mask+-- TODO: Add some sanity checking!!!!+condIntCode' platform cond (CmmMachOp (MO_And _) [x,o2]) (CmmLit (CmmInt 0 ty))+    | (CmmLit lit@(CmmInt mask _)) <- o2, is32BitLit platform lit+    = do+      (x_reg, x_code) <- getSomeReg x+      let+         code = x_code `snocOL`+                TEST (intFormat ty) (OpImm (ImmInteger mask)) (OpReg x_reg)+      --+      return (CondCode False cond code)++-- anything vs zero+condIntCode' _ cond x (CmmLit (CmmInt 0 ty)) = do+    (x_reg, x_code) <- getSomeReg x+    let+        code = x_code `snocOL`+                  TEST (intFormat ty) (OpReg x_reg) (OpReg x_reg)+    --+    return (CondCode False cond code)++-- anything vs operand+condIntCode' platform cond x y+ | isOperand platform y = do+    (x_reg, x_code) <- getNonClobberedReg x+    (y_op,  y_code) <- getOperand y+    let+        code = x_code `appOL` y_code `snocOL`+                  CMP (cmmTypeFormat (cmmExprType platform x)) y_op (OpReg x_reg)+    return (CondCode False cond code)+-- operand vs. anything: invert the comparison so that we can use a+-- single comparison instruction.+ | isOperand platform x+ , Just revcond <- maybeFlipCond cond = do+    (y_reg, y_code) <- getNonClobberedReg y+    (x_op,  x_code) <- getOperand x+    let+        code = y_code `appOL` x_code `snocOL`+                  CMP (cmmTypeFormat (cmmExprType platform x)) x_op (OpReg y_reg)+    return (CondCode False revcond code)++-- anything vs anything+condIntCode' platform cond x y = do+  (y_reg, y_code) <- getNonClobberedReg y+  (x_op, x_code) <- getRegOrMem x+  let+        code = y_code `appOL`+               x_code `snocOL`+                  CMP (cmmTypeFormat (cmmExprType platform x)) (OpReg y_reg) x_op+  return (CondCode False cond code)++++--------------------------------------------------------------------------------+condFltCode :: Cond -> CmmExpr -> CmmExpr -> NatM CondCode++condFltCode cond x y+  =  condFltCode_sse2+  where+++  -- in the SSE2 comparison ops (ucomiss, ucomisd) the left arg may be+  -- an operand, but the right must be a reg.  We can probably do better+  -- than this general case...+  condFltCode_sse2 = do+    platform <- getPlatform+    (x_reg, x_code) <- getNonClobberedReg x+    (y_op, y_code) <- getOperand y+    let+        code = x_code `appOL`+               y_code `snocOL`+                  CMP (floatFormat $ cmmExprWidth platform x) y_op (OpReg x_reg)+        -- NB(1): we need to use the unsigned comparison operators on the+        -- result of this comparison.+    return (CondCode True (condToUnsigned cond) code)++-- -----------------------------------------------------------------------------+-- Generating assignments++-- Assignments are really at the heart of the whole code generation+-- business.  Almost all top-level nodes of any real importance are+-- assignments, which correspond to loads, stores, or register+-- transfers.  If we're really lucky, some of the register transfers+-- will go away, because we can use the destination register to+-- complete the code generation for the right hand side.  This only+-- fails when the right hand side is forced into a fixed register+-- (e.g. the result of a call).++assignMem_IntCode :: Format -> CmmExpr -> CmmExpr -> NatM InstrBlock+assignReg_IntCode ::           CmmReg  -> CmmExpr -> NatM InstrBlock++assignMem_FltCode :: Format -> CmmExpr -> CmmExpr -> NatM InstrBlock+assignReg_FltCode ::           CmmReg  -> CmmExpr -> NatM InstrBlock++assignMem_VecCode :: Format -> CmmExpr -> CmmExpr -> NatM InstrBlock+assignReg_VecCode ::           CmmReg  -> CmmExpr -> NatM InstrBlock++-- integer assignment to memory++-- specific case of adding/subtracting an integer to a particular address.+-- ToDo: catch other cases where we can use an operation directly on a memory+-- address.+assignMem_IntCode ty addr (CmmMachOp op [CmmLoad addr2 _ _,+                                                 CmmLit (CmmInt i _)])+   | addr == addr2, ty /= II64 || is32BitInteger i,+     Just instr <- check op+   = do Amode amode code_addr <- getAmode addr+        let code = code_addr `snocOL`+                   instr ty (OpImm (ImmInt (fromIntegral i))) (OpAddr amode)+        return code+   where+        check (MO_Add _) = Just ADD+        check (MO_Sub _) = Just SUB+        check _ = Nothing+        -- ToDo: more?++-- general case+assignMem_IntCode ty addr src = do+    platform <- getPlatform+    Amode addr code_addr <- getAmode addr+    (code_src, op_src)   <- get_op_RI platform src+    let+        code = code_src `appOL`+               code_addr `snocOL`+                  MOV ty op_src (OpAddr addr)+        -- NOTE: op_src is stable, so it will still be valid+        -- after code_addr.  This may involve the introduction+        -- of an extra MOV to a temporary register, but we hope+        -- the register allocator will get rid of it.+    --+    return code+  where+    get_op_RI :: Platform -> CmmExpr -> NatM (InstrBlock,Operand)   -- code, operator+    get_op_RI platform (CmmLit lit) | is32BitLit platform lit+      = return (nilOL, OpImm (litToImm lit))+    get_op_RI _ op+      = do (reg,code) <- getNonClobberedReg op+           return (code, OpReg reg)+++-- Assign; dst is a reg, rhs is mem+assignReg_IntCode reg (CmmLoad src _ _) = do+  let ty = cmmTypeFormat $ cmmRegType reg+  load_code <- intLoadCode (MOV ty) src+  platform <- ncgPlatform <$> getConfig+  return (load_code (getRegisterReg platform reg))++-- dst is a reg, but src could be anything+assignReg_IntCode reg src = do+  platform <- ncgPlatform <$> getConfig+  code <- getAnyReg src+  return (code (getRegisterReg platform reg))+++-- Floating point assignment to memory+assignMem_FltCode ty addr src = do+  (src_reg, src_code) <- getNonClobberedReg src+  Amode addr addr_code <- getAmode addr+  let+        code = src_code `appOL`+               addr_code `snocOL`+               MOV ty (OpReg src_reg) (OpAddr addr)++  return code++-- Floating point assignment to a register/temporary+assignReg_FltCode reg src = do+  src_code <- getAnyReg src+  platform <- ncgPlatform <$> getConfig+  return (src_code (getRegisterReg platform reg))++-- Vector assignment to a register/temporary+assignMem_VecCode ty addr src = do+  (src_reg, src_code) <- getNonClobberedReg src+  Amode addr addr_code <- getAmode addr+  config <- getConfig+  let+    code = src_code `appOL`+           addr_code `snocOL`+           movInstr config ty (OpReg src_reg) (OpAddr addr)+  return code++assignReg_VecCode reg src = do+  platform <- ncgPlatform <$> getConfig+  src_code <- getAnyReg src+  return (src_code (getRegisterReg platform reg))++genJump :: CmmExpr{-the branch target-} -> [RegWithFormat] -> NatM InstrBlock++genJump (CmmLoad mem _ _) regs = do+  Amode target code <- getAmode mem+  return (code `snocOL` JMP (OpAddr target) regs)++genJump (CmmLit lit) regs =+  return (unitOL (JMP (OpImm (litToImm lit)) regs))++genJump expr regs = do+  (reg,code) <- getSomeReg expr+  return (code `snocOL` JMP (OpReg reg) regs)+++-- -----------------------------------------------------------------------------+--  Unconditional branches++genBranch :: BlockId -> InstrBlock+genBranch = toOL . mkJumpInstr++++-- -----------------------------------------------------------------------------+--  Conditional jumps/branches++{-+Conditional jumps are always to local labels, so we can use branch+instructions.  We peek at the arguments to decide what kind of+comparison to do.++I386: First, we have to ensure that the condition+codes are set according to the supplied comparison operation.+-}++genCondBranch+    :: BlockId      -- the source of the jump+    -> BlockId      -- the true branch target+    -> BlockId      -- the false branch target+    -> CmmExpr      -- the condition on which to branch+    -> NatM InstrBlock -- Instructions++genCondBranch bid id false expr = do+  is32Bit <- is32BitPlatform+  genCondBranch' is32Bit bid id false expr++-- | We return the instructions generated.+genCondBranch' :: Bool -> BlockId -> BlockId -> BlockId -> CmmExpr+               -> NatM InstrBlock++genCondBranch' _ bid id false bool = do+  CondCode is_float cond cond_code <- getCondCode bool+  if not is_float+    then+        return (cond_code `snocOL` JXX cond id `appOL` genBranch false)+    else do+        -- See Note [SSE Parity Checks]+        let jmpFalse = genBranch false+            code+                = case cond of+                  NE  -> or_unordered+                  GU  -> plain_test+                  GEU -> plain_test+                  -- Use ASSERT so we don't break releases if+                  -- LTT/LE creep in somehow.+                  LTT ->+                    assertPpr False (text "Should have been turned into >")+                    and_ordered+                  LE  ->+                    assertPpr False (text "Should have been turned into >=")+                    and_ordered+                  _   -> and_ordered++            plain_test = unitOL (+                  JXX cond id+                ) `appOL` jmpFalse+            or_unordered = toOL [+                  JXX cond id,+                  JXX PARITY id+                ] `appOL` jmpFalse+            and_ordered = toOL [+                  JXX PARITY false,+                  JXX cond id,+                  JXX ALWAYS false+                ]+        updateCfgNat (\cfg -> adjustEdgeWeight cfg (+3) bid false)+        return (cond_code `appOL` code)++{-  Note [Introducing cfg edges inside basic blocks]+    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~++    During instruction selection a statement `s`+    in a block B with control of the sort: B -> C+    will sometimes result in control+    flow of the sort:++            ┌ < ┐+            v   ^+      B ->  B1  ┴ -> C++    as is the case for some atomic operations.++    Now to keep the CFG in sync when introducing B1 we clearly+    want to insert it between B and C. However there is+    a catch when we have to deal with self loops.++    We might start with code and a CFG of these forms:++    loop:+        stmt1               ┌ < ┐+        ....                v   ^+        stmtX              loop ┘+        stmtY+        ....+        goto loop:++    Now we introduce B1:+                            ┌ ─ ─ ─ ─ ─┐+        loop:               │   ┌ <  ┐ │+        instrs              v   │    │ ^+        ....               loop ┴ B1 ┴ ┘+        instrsFromX+        stmtY+        goto loop:++    This is simple, all outgoing edges from loop now simply+    start from B1 instead and the code generator knows which+    new edges it introduced for the self loop of B1.++    Disaster strikes if the statement Y follows the same pattern.+    If we apply the same rule that all outgoing edges change then+    we end up with:++        loop ─> B1 ─> B2 ┬─┐+          │      │    └─<┤ │+          │      └───<───┘ │+          └───────<────────┘++    This is problematic. The edge B1->B1 is modified as expected.+    However the modification is wrong!++    The assembly in this case looked like this:++    _loop:+        <instrs>+    _B1:+        ...+        cmpxchgq ...+        jne _B1+        <instrs>+        <end _B1>+    _B2:+        ...+        cmpxchgq ...+        jne _B2+        <instrs>+        jmp loop++    There is no edge _B2 -> _B1 here. It's still a self loop onto _B1.++    The problem here is that really B1 should be two basic blocks.+    Otherwise we have control flow in the *middle* of a basic block.+    A contradiction!++    So to account for this we add yet another basic block marker:++    _B:+        <instrs>+    _B1:+        ...+        cmpxchgq ...+        jne _B1+        jmp _B1'+    _B1':+        <instrs>+        <end _B1>+    _B2:+        ...++    Now when inserting B2 we will only look at the outgoing edges of B1' and+    everything will work out nicely.++    You might also wonder why we don't insert jumps at the end of _B1'. There is+    no way another block ends up jumping to the labels _B1 or _B2 since they are+    essentially invisible to other blocks. View them as control flow labels local+    to the basic block if you'd like.++    Not doing this ultimately caused (part 2 of) #17334.+-}+++-- -----------------------------------------------------------------------------+--  Generating C calls++-- Now the biggest nightmare---calls.  Most of the nastiness is buried in+-- @get_arg@, which moves the arguments to the correct registers/stack+-- locations.  Apart from that, the code is easy.+--+-- (If applicable) Do not fill the delay slots here; you will confuse the+-- register allocator.+--+-- See Note [Keeping track of the current block] for information why we need+-- to take/return a block id.++genForeignCall+    :: ForeignTarget -- ^ function to call+    -> [CmmFormal]   -- ^ where to put the result+    -> [CmmActual]   -- ^ arguments (of mixed type)+    -> BlockId       -- ^ The block we are in+    -> NatM (InstrBlock, Maybe BlockId)++genForeignCall target dst args bid = do+  case target of+    PrimTarget prim         -> genPrim bid prim dst args+    ForeignTarget addr conv -> (,Nothing) <$> genCCall bid addr conv dst args++genPrim+    :: BlockId       -- ^ The block we are in+    -> CallishMachOp -- ^ MachOp+    -> [CmmFormal]   -- ^ where to put the result+    -> [CmmActual]   -- ^ arguments (of mixed type)+    -> NatM (InstrBlock, Maybe BlockId)++-- First we deal with cases which might introduce new blocks in the stream.+genPrim bid (MO_AtomicRMW width amop) [dst] [addr, n]+  = genAtomicRMW bid width amop dst addr n+genPrim bid (MO_Ctz width) [dst] [src]+  = genCtz bid width dst src++-- Then we deal with cases which not introducing new blocks in the stream.+genPrim bid prim dst args+  = (,Nothing) <$> genSimplePrim bid prim dst args++genSimplePrim+    :: BlockId       -- ^ the block we are in+    -> CallishMachOp -- ^ MachOp+    -> [CmmFormal]   -- ^ where to put the result+    -> [CmmActual]   -- ^ arguments (of mixed type)+    -> NatM InstrBlock+genSimplePrim bid (MO_Memcpy align)    []      [dst,src,n]    = genMemCpy  bid align dst src n+genSimplePrim bid (MO_Memmove align)   []      [dst,src,n]    = genMemMove bid align dst src n+genSimplePrim bid (MO_Memcmp align)    [res]   [dst,src,n]    = genMemCmp  bid align res dst src n+genSimplePrim bid (MO_Memset align)    []      [dst,c,n]      = genMemSet  bid align dst c n+genSimplePrim _   MO_AcquireFence      []      []             = return nilOL -- barriers compile to no code on x86/x86-64;+genSimplePrim _   MO_ReleaseFence      []      []             = return nilOL -- we keep it this long in order to prevent earlier optimisations.+genSimplePrim _   MO_SeqCstFence       []      []             = return $ unitOL MFENCE+genSimplePrim _   MO_Touch             []      [_]            = return nilOL+genSimplePrim _   (MO_Prefetch_Data n) []      [src]          = genPrefetchData n src+genSimplePrim _   (MO_BSwap width)     [dst]   [src]          = genByteSwap width dst src+genSimplePrim bid (MO_BRev width)      [dst]   [src]          = genBitRev bid width dst src+genSimplePrim bid (MO_PopCnt width)    [dst]   [src]          = genPopCnt bid width dst src+genSimplePrim bid (MO_Pdep width)      [dst]   [src,mask]     = genPdep bid width dst src mask+genSimplePrim bid (MO_Pext width)      [dst]   [src,mask]     = genPext bid width dst src mask+genSimplePrim bid (MO_Clz width)       [dst]   [src]          = genClz bid width dst src+genSimplePrim bid (MO_UF_Conv width)   [dst]   [src]          = genWordToFloat bid width dst src+genSimplePrim _   (MO_AtomicRead w mo)  [dst]  [addr]         = genAtomicRead w mo dst addr+genSimplePrim _   (MO_AtomicWrite w mo) []     [addr,val]     = genAtomicWrite w mo addr val+genSimplePrim bid (MO_Cmpxchg width)   [dst]   [addr,old,new] = genCmpXchg bid width dst addr old new+genSimplePrim _   (MO_Xchg width)      [dst]   [addr, value]  = genXchg width dst addr value+genSimplePrim _   (MO_AddWordC w)      [r,c]   [x,y]          = genAddSubRetCarry w ADD_CC (const Nothing) CARRY r c x y+genSimplePrim _   (MO_SubWordC w)      [r,c]   [x,y]          = genAddSubRetCarry w SUB_CC (const Nothing) CARRY r c x y+genSimplePrim _   (MO_AddIntC w)       [r,c]   [x,y]          = genAddSubRetCarry w ADD_CC (Just . ADD_CC) OFLO  r c x y+genSimplePrim _   (MO_SubIntC w)       [r,c]   [x,y]          = genAddSubRetCarry w SUB_CC (const Nothing) OFLO  r c x y+genSimplePrim _   (MO_Add2 w)          [h,l]   [x,y]          = genAddWithCarry w h l x y+genSimplePrim _   (MO_U_Mul2 w)        [h,l]   [x,y]          = genUnsignedLargeMul w h l x y+genSimplePrim _   (MO_S_Mul2 w)        [c,h,l] [x,y]          = genSignedLargeMul w c h l x y+genSimplePrim _   (MO_S_QuotRem w)     [q,r]   [x,y]          = genQuotRem w True  q r Nothing   x  y+genSimplePrim _   (MO_U_QuotRem w)     [q,r]   [x,y]          = genQuotRem w False q r Nothing   x  y+genSimplePrim _   (MO_U_QuotRem2 w)    [q,r]   [hx,lx,y]      = genQuotRem w False q r (Just hx) lx y+genSimplePrim _   MO_F32_Fabs          [dst]   [src]          = genFloatAbs W32 dst src+genSimplePrim _   MO_F64_Fabs          [dst]   [src]          = genFloatAbs W64 dst src+genSimplePrim _   MO_F32_Sqrt          [dst]   [src]          = genFloatSqrt FF32 dst src+genSimplePrim _   MO_F64_Sqrt          [dst]   [src]          = genFloatSqrt FF64 dst src+genSimplePrim bid MO_F32_Sin           [dst]   [src]          = genLibCCall bid (fsLit "sinf") [dst] [src]+genSimplePrim bid MO_F32_Cos           [dst]   [src]          = genLibCCall bid (fsLit "cosf") [dst] [src]+genSimplePrim bid MO_F32_Tan           [dst]   [src]          = genLibCCall bid (fsLit "tanf") [dst] [src]+genSimplePrim bid MO_F32_Exp           [dst]   [src]          = genLibCCall bid (fsLit "expf") [dst] [src]+genSimplePrim bid MO_F32_ExpM1         [dst]   [src]          = genLibCCall bid (fsLit "expm1f") [dst] [src]+genSimplePrim bid MO_F32_Log           [dst]   [src]          = genLibCCall bid (fsLit "logf") [dst] [src]+genSimplePrim bid MO_F32_Log1P         [dst]   [src]          = genLibCCall bid (fsLit "log1pf") [dst] [src]+genSimplePrim bid MO_F32_Asin          [dst]   [src]          = genLibCCall bid (fsLit "asinf") [dst] [src]+genSimplePrim bid MO_F32_Acos          [dst]   [src]          = genLibCCall bid (fsLit "acosf") [dst] [src]+genSimplePrim bid MO_F32_Atan          [dst]   [src]          = genLibCCall bid (fsLit "atanf") [dst] [src]+genSimplePrim bid MO_F32_Sinh          [dst]   [src]          = genLibCCall bid (fsLit "sinhf") [dst] [src]+genSimplePrim bid MO_F32_Cosh          [dst]   [src]          = genLibCCall bid (fsLit "coshf") [dst] [src]+genSimplePrim bid MO_F32_Tanh          [dst]   [src]          = genLibCCall bid (fsLit "tanhf") [dst] [src]+genSimplePrim bid MO_F32_Pwr           [dst]   [x,y]          = genLibCCall bid (fsLit "powf")  [dst] [x,y]+genSimplePrim bid MO_F32_Asinh         [dst]   [src]          = genLibCCall bid (fsLit "asinhf") [dst] [src]+genSimplePrim bid MO_F32_Acosh         [dst]   [src]          = genLibCCall bid (fsLit "acoshf") [dst] [src]+genSimplePrim bid MO_F32_Atanh         [dst]   [src]          = genLibCCall bid (fsLit "atanhf") [dst] [src]+genSimplePrim bid MO_F64_Sin           [dst]   [src]          = genLibCCall bid (fsLit "sin") [dst] [src]+genSimplePrim bid MO_F64_Cos           [dst]   [src]          = genLibCCall bid (fsLit "cos") [dst] [src]+genSimplePrim bid MO_F64_Tan           [dst]   [src]          = genLibCCall bid (fsLit "tan") [dst] [src]+genSimplePrim bid MO_F64_Exp           [dst]   [src]          = genLibCCall bid (fsLit "exp") [dst] [src]+genSimplePrim bid MO_F64_ExpM1         [dst]   [src]          = genLibCCall bid (fsLit "expm1") [dst] [src]+genSimplePrim bid MO_F64_Log           [dst]   [src]          = genLibCCall bid (fsLit "log") [dst] [src]+genSimplePrim bid MO_F64_Log1P         [dst]   [src]          = genLibCCall bid (fsLit "log1p") [dst] [src]+genSimplePrim bid MO_F64_Asin          [dst]   [src]          = genLibCCall bid (fsLit "asin") [dst] [src]+genSimplePrim bid MO_F64_Acos          [dst]   [src]          = genLibCCall bid (fsLit "acos") [dst] [src]+genSimplePrim bid MO_F64_Atan          [dst]   [src]          = genLibCCall bid (fsLit "atan") [dst] [src]+genSimplePrim bid MO_F64_Sinh          [dst]   [src]          = genLibCCall bid (fsLit "sinh") [dst] [src]+genSimplePrim bid MO_F64_Cosh          [dst]   [src]          = genLibCCall bid (fsLit "cosh") [dst] [src]+genSimplePrim bid MO_F64_Tanh          [dst]   [src]          = genLibCCall bid (fsLit "tanh") [dst] [src]+genSimplePrim bid MO_F64_Pwr           [dst]   [x,y]          = genLibCCall bid (fsLit "pow")  [dst] [x,y]+genSimplePrim bid MO_F64_Asinh         [dst]   [src]          = genLibCCall bid (fsLit "asinh") [dst] [src]+genSimplePrim bid MO_F64_Acosh         [dst]   [src]          = genLibCCall bid (fsLit "acosh") [dst] [src]+genSimplePrim bid MO_F64_Atanh         [dst]   [src]          = genLibCCall bid (fsLit "atanh") [dst] [src]+genSimplePrim bid MO_SuspendThread     [tok]   [rs,i]         = genRTSCCall bid (fsLit "suspendThread") [tok] [rs,i]+genSimplePrim bid MO_ResumeThread      [rs]    [tok]          = genRTSCCall bid (fsLit "resumeThread") [rs] [tok]+genSimplePrim bid MO_I64_Quot          [dst]   [x,y]          = genPrimCCall bid (fsLit "hs_quotInt64") [dst] [x,y]+genSimplePrim bid MO_I64_Rem           [dst]   [x,y]          = genPrimCCall bid (fsLit "hs_remInt64") [dst] [x,y]+genSimplePrim bid MO_W64_Quot          [dst]   [x,y]          = genPrimCCall bid (fsLit "hs_quotWord64") [dst] [x,y]+genSimplePrim bid MO_W64_Rem           [dst]   [x,y]          = genPrimCCall bid (fsLit "hs_remWord64") [dst] [x,y]+genSimplePrim bid (MO_VS_Quot 16 W8)   [dst]   [x,y]          = genPrimCCall bid (fsLit "hs_quotInt8X16") [dst] [x,y]+genSimplePrim bid (MO_VS_Quot 8 W16)   [dst]   [x,y]          = genPrimCCall bid (fsLit "hs_quotInt16X8") [dst] [x,y]+genSimplePrim bid (MO_VS_Quot 4 W32)   [dst]   [x,y]          = genPrimCCall bid (fsLit "hs_quotInt32X4") [dst] [x,y]+genSimplePrim bid (MO_VS_Quot 2 W64)   [dst]   [x,y]          = genPrimCCall bid (fsLit "hs_quotInt64X2") [dst] [x,y]+genSimplePrim _   op@(MO_VS_Quot {})   _       _              = pprPanic "Unsupported vector instruction for the native code generator:" (pprCallishMachOp op)+genSimplePrim bid (MO_VS_Rem 16 W8)    [dst]   [x,y]          = genPrimCCall bid (fsLit "hs_remInt8X16") [dst] [x,y]+genSimplePrim bid (MO_VS_Rem 8 W16)    [dst]   [x,y]          = genPrimCCall bid (fsLit "hs_remInt16X8") [dst] [x,y]+genSimplePrim bid (MO_VS_Rem 4 W32)    [dst]   [x,y]          = genPrimCCall bid (fsLit "hs_remInt32X4") [dst] [x,y]+genSimplePrim bid (MO_VS_Rem 2 W64)    [dst]   [x,y]          = genPrimCCall bid (fsLit "hs_remInt64X2") [dst] [x,y]+genSimplePrim _   op@(MO_VS_Rem {})    _       _              = pprPanic "Unsupported vector instruction for the native code generator:" (pprCallishMachOp op)+genSimplePrim bid (MO_VU_Quot 16 W8)   [dst]   [x,y]          = genPrimCCall bid (fsLit "hs_quotWord8X16") [dst] [x,y]+genSimplePrim bid (MO_VU_Quot 8 W16)   [dst]   [x,y]          = genPrimCCall bid (fsLit "hs_quotWord16X8") [dst] [x,y]+genSimplePrim bid (MO_VU_Quot 4 W32)   [dst]   [x,y]          = genPrimCCall bid (fsLit "hs_quotWord32X4") [dst] [x,y]+genSimplePrim bid (MO_VU_Quot 2 W64)   [dst]   [x,y]          = genPrimCCall bid (fsLit "hs_quotWord64X2") [dst] [x,y]+genSimplePrim _   op@(MO_VU_Quot {})   _       _              = pprPanic "Unsupported vector instruction for the native code generator:" (pprCallishMachOp op)+genSimplePrim bid (MO_VU_Rem 16 W8)    [dst]   [x,y]          = genPrimCCall bid (fsLit "hs_remWord8X16") [dst] [x,y]+genSimplePrim bid (MO_VU_Rem 8 W16)    [dst]   [x,y]          = genPrimCCall bid (fsLit "hs_remWord16X8") [dst] [x,y]+genSimplePrim bid (MO_VU_Rem 4 W32)    [dst]   [x,y]          = genPrimCCall bid (fsLit "hs_remWord32X4") [dst] [x,y]+genSimplePrim bid (MO_VU_Rem 2 W64)    [dst]   [x,y]          = genPrimCCall bid (fsLit "hs_remWord64X2") [dst] [x,y]+genSimplePrim _   op@(MO_VU_Rem {})    _       _              = pprPanic "Unsupported vector instruction for the native code generator:" (pprCallishMachOp op)+genSimplePrim bid MO_I64X2_Min         [dst]   [x,y]          = genPrimCCall bid (fsLit "hs_minInt64X2") [dst] [x,y]+genSimplePrim bid MO_I64X2_Max         [dst]   [x,y]          = genPrimCCall bid (fsLit "hs_maxInt64X2") [dst] [x,y]+genSimplePrim bid MO_W64X2_Min         [dst]   [x,y]          = genPrimCCall bid (fsLit "hs_minWord64X2") [dst] [x,y]+genSimplePrim bid MO_W64X2_Max         [dst]   [x,y]          = genPrimCCall bid (fsLit "hs_maxWord64X2") [dst] [x,y]+genSimplePrim _   op                   dst     args           = do+  platform <- ncgPlatform <$> getConfig+  pprPanic "genSimplePrim: unhandled primop" (ppr (pprCallishMachOp op, dst, fmap (pdoc platform) args))++{- Note [Evaluate C-call arguments before placing in destination registers]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+When producing code for C calls we must take care when placing arguments+in their final registers. Specifically, we must ensure that temporary register+usage due to evaluation of one argument does not clobber a register in which we+already placed a previous argument (e.g. as the code generation logic for+MO_Shl can clobber %rcx due to x86 instruction limitations).++This is precisely what happened in #18527. Consider this C--:++    (result::I64) = call "ccall" doSomething(_s2hp::I64, 2244, _s2hq::I64, _s2hw::I64 | (1 << _s2hz::I64));++Here we are calling the C function `doSomething` with three arguments, the last+involving a non-trivial expression involving MO_Shl. In this case the NCG could+naively generate the following assembly (where $tmp denotes some temporary+register and $argN denotes the register for argument N, as dictated by the+platform's calling convention):++    mov _s2hp, $arg1   # place first argument+    mov _s2hq, $arg2   # place second argument++    # Compute 1 << _s2hz+    mov _s2hz, %rcx+    shl %cl, $tmp++    # Compute (_s2hw | (1 << _s2hz))+    mov _s2hw, $arg3+    or $tmp, $arg3++    # Perform the call+    call func++This code is outright broken on Windows which assigns $arg1 to %rcx. This means+that the evaluation of the last argument clobbers the first argument.++To avoid this we use a rather awful hack: when producing code for a C call with+at least one non-trivial argument, we first evaluate all of the arguments into+local registers before moving them into their final calling-convention-defined+homes.  This is performed by 'evalArgs'. Here we define "non-trivial" to be an+expression which might contain a MachOp since these are the only cases which+might clobber registers. Furthermore, we use a conservative approximation of+this condition (only looking at the top-level of CmmExprs) to avoid spending+too much effort trying to decide whether we want to take the fast path.++Note that this hack *also* applies to calls to out-of-line PrimTargets (which+are lowered via a C call), which will ultimately end up in+genForeignCall{32,64}.+-}++-- | See Note [Evaluate C-call arguments before placing in destination registers]+evalArgs :: BlockId -> [CmmActual] -> NatM (InstrBlock, [CmmActual])+evalArgs bid actuals+  | any loadIntoRegMightClobberOtherReg actuals = do+      regs_blks <- mapM evalArg actuals+      return (concatOL $ map fst regs_blks, map snd regs_blks)+  | otherwise = return (nilOL, actuals)+  where++    evalArg :: CmmActual -> NatM (InstrBlock, CmmExpr)+    evalArg actual = do+        platform <- getPlatform+        lreg <- newLocalReg $ cmmExprType platform actual+        (instrs, bid1) <- stmtToInstrs bid $ CmmAssign (CmmLocal lreg) actual+        -- The above assignment shouldn't change the current block+        massert (isNothing bid1)+        return (instrs, CmmReg $ CmmLocal lreg)++    newLocalReg :: CmmType -> NatM LocalReg+    newLocalReg ty = LocalReg <$> getUniqueM <*> pure ty++-- | Might the code to put this expression into a register+-- clobber any other registers?+loadIntoRegMightClobberOtherReg :: CmmExpr -> Bool+loadIntoRegMightClobberOtherReg (CmmReg _)      = False+loadIntoRegMightClobberOtherReg (CmmRegOff _ _) = False+loadIntoRegMightClobberOtherReg (CmmLit _)      = False+  -- NB: this last 'False' is slightly risky, because the code for loading+  -- a literal into a register is not entirely trivial.+loadIntoRegMightClobberOtherReg _               = True++-- Note [DIV/IDIV for bytes]+-- ~~~~~~~~~~~~~~~~~~~~~~~~~+-- IDIV reminder:+--   Size    Dividend   Divisor   Quotient    Remainder+--   byte    %ax         r/m8      %al          %ah+--   word    %dx:%ax     r/m16     %ax          %dx+--   dword   %edx:%eax   r/m32     %eax         %edx+--   qword   %rdx:%rax   r/m64     %rax         %rdx+--+-- We do a special case for the byte division because the current+-- codegen doesn't deal well with accessing %ah register (also,+-- accessing %ah in 64-bit mode is complicated because it cannot be an+-- operand of many instructions). So we just widen operands to 16 bits+-- and get the results from %al, %dl. This is not optimal, but a few+-- register moves are probably not a huge deal when doing division.+++-- | Generate C call to the given function in ghc-prim+genPrimCCall+  :: BlockId+  -> FastString+  -> [CmmFormal]+  -> [CmmActual]+  -> NatM InstrBlock+genPrimCCall bid lbl_txt dsts args = do+  config <- getConfig+  -- FIXME: we should use mkForeignLabel instead of mkCmmCodeLabel+  let lbl = mkCmmCodeLabel ghcInternalUnitId lbl_txt+  addr <- cmmMakeDynamicReference config CallReference lbl+  let conv = ForeignConvention CCallConv [] [] CmmMayReturn+  genCCall bid addr conv dsts args++-- | Generate C call to the given function in libc+genLibCCall+  :: BlockId+  -> FastString+  -> [CmmFormal]+  -> [CmmActual]+  -> NatM InstrBlock+genLibCCall bid lbl_txt dsts args = do+  config <- getConfig+  -- Assume we can call these functions directly, and that they're not in a dynamic library.+  -- TODO: Why is this ok? Under linux this code will be in libm.so+  --       Is it because they're really implemented as a primitive instruction by the assembler??  -- BL 2009/12/31+  let lbl = mkForeignLabel lbl_txt ForeignLabelInThisPackage IsFunction+  addr <- cmmMakeDynamicReference config CallReference lbl+  let conv = ForeignConvention CCallConv [] [] CmmMayReturn+  genCCall bid addr conv dsts args++-- | Generate C call to the given function in the RTS+genRTSCCall+  :: BlockId+  -> FastString+  -> [CmmFormal]+  -> [CmmActual]+  -> NatM InstrBlock+genRTSCCall bid lbl_txt dsts args = do+  config <- getConfig+  -- Assume we can call these functions directly, and that they're not in a dynamic library.+  let lbl = mkForeignLabel lbl_txt ForeignLabelInThisPackage IsFunction+  addr <- cmmMakeDynamicReference config CallReference lbl+  let conv = ForeignConvention CCallConv [] [] CmmMayReturn+  genCCall bid addr conv dsts args++-- | Generate a real C call to the given address with the given convention+genCCall+  :: BlockId+  -> CmmExpr+  -> ForeignConvention+  -> [CmmFormal]+  -> [CmmActual]+  -> NatM InstrBlock+genCCall bid addr conv@(ForeignConvention _ argHints _ _) dest_regs args = do+  platform <- getPlatform+  is32Bit <- is32BitPlatform+  let args_hints = zip args (argHints ++ repeat NoHint)+      prom_args = map (maybePromoteCArgToW32 platform) args_hints+  (instrs0, args') <- evalArgs bid prom_args+  instrs1 <- if is32Bit+    then genCCall32 addr conv dest_regs args'+    else genCCall64 addr conv dest_regs args'+  return (instrs0 `appOL` instrs1)++maybePromoteCArgToW32 :: Platform -> (CmmExpr, ForeignHint) -> CmmExpr+maybePromoteCArgToW32 platform (arg, hint)+ | wfrom < wto =+    -- As wto=W32, we only need to handle integer conversions,+    -- never Float -> Double.+    case hint of+      SignedHint -> CmmMachOp (MO_SS_Conv wfrom wto) [arg]+      _          -> CmmMachOp (MO_UU_Conv wfrom wto) [arg]+ | otherwise   = arg+ where+   ty = cmmExprType platform arg+   wfrom = typeWidth ty+   wto = W32++genCCall32 :: CmmExpr           -- ^ address of the function to call+           -> ForeignConvention -- ^ calling convention+           -> [CmmFormal]       -- ^ where to put the result+           -> [CmmActual]       -- ^ arguments (of mixed type)+           -> NatM InstrBlock+genCCall32 addr _conv dest_regs args = do+        config <- getConfig+        let platform = ncgPlatform config++            -- If the size is smaller than the word, we widen things (see maybePromoteCArg)+            arg_size_bytes :: CmmType -> Int+            arg_size_bytes ty = max (widthInBytes (typeWidth ty)) (widthInBytes (wordWidth platform))++            roundTo a x | x `mod` a == 0 = x+                        | otherwise = x + a - (x `mod` a)++            push_arg :: CmmActual {-current argument-}+                            -> NatM InstrBlock  -- code++            push_arg  arg -- we don't need the hints on x86+              | isWord64 arg_ty = do+                RegCode64 code r_hi r_lo <- iselExpr64 arg+                delta <- getDeltaNat+                setDeltaNat (delta - 8)+                return (       code `appOL`+                               toOL [PUSH II32 (OpReg r_hi), DELTA (delta - 4),+                                     PUSH II32 (OpReg r_lo), DELTA (delta - 8),+                                     DELTA (delta-8)]+                    )++              | isFloatType arg_ty || isVecType arg_ty = do+                (reg, code) <- getSomeReg arg+                delta <- getDeltaNat+                setDeltaNat (delta-size)+                return (code `appOL`+                                toOL [SUB II32 (OpImm (ImmInt size)) (OpReg esp),+                                      DELTA (delta-size),+                                      let addr = AddrBaseIndex (EABaseReg esp)+                                                                EAIndexNone+                                                                (ImmInt 0)+                                          format = cmmTypeFormat arg_ty+                                      in++                                       movInstr config format (OpReg reg) (OpAddr addr)++                                     ]+                               )++              | otherwise = do+                -- Arguments can be smaller than 32-bit, but we still use @PUSH+                -- II32@ - the usual calling conventions expect integers to be+                -- 4-byte aligned.+                massert ((typeWidth arg_ty) <= W32)+                (operand, code) <- getOperand arg+                delta <- getDeltaNat+                setDeltaNat (delta-size)+                return (code `snocOL`+                        PUSH II32 operand `snocOL`+                        DELTA (delta-size))++              where+                 arg_ty = cmmExprType platform arg+                 size = arg_size_bytes arg_ty -- Byte size++        let+            -- Align stack to 16n for calls, assuming a starting stack+            -- alignment of 16n - word_size on procedure entry. Which we+            -- maintain. See Note [Stack Alignment on X86] in rts/StgCRun.c.+            sizes               = map (arg_size_bytes . cmmExprType platform) (reverse args)+            raw_arg_size        = sum sizes + platformWordSizeInBytes platform+            arg_pad_size        = (roundTo 16 $ raw_arg_size) - raw_arg_size+            tot_arg_size        = raw_arg_size + arg_pad_size - platformWordSizeInBytes platform+++        delta0 <- getDeltaNat+        setDeltaNat (delta0 - arg_pad_size)++        push_codes <- mapM push_arg (reverse args)+        delta <- getDeltaNat+        massert (delta == delta0 - tot_arg_size)++        -- deal with static vs dynamic call targets+        callinsns <-+          case addr of+            CmmLit (CmmLabel lbl)+               -> return $ unitOL (CALL (Left fn_imm) [])+               where fn_imm = ImmCLbl lbl+            _+               -> do { (dyn_r, dyn_c) <- getSomeReg addr+                     ; massert (isWord32 (cmmExprType platform addr))+                     ; return $ dyn_c `snocOL` CALL (Right dyn_r) [] }+        let push_code+                | arg_pad_size /= 0+                = toOL [SUB II32 (OpImm (ImmInt arg_pad_size)) (OpReg esp),+                        DELTA (delta0 - arg_pad_size)]+                  `appOL` concatOL push_codes+                | otherwise+                = concatOL push_codes++            call = callinsns `appOL`+                   toOL (+                      (if tot_arg_size == 0 then [] else+                       [ADD II32 (OpImm (ImmInt tot_arg_size)) (OpReg esp)])+                      +++                      [DELTA delta0]+                   )+        setDeltaNat delta0++        let+            -- assign the results, if necessary+            assign_code []     = nilOL+            assign_code [dest]+              | isVecType ty+              = unitOL (mkRegRegMoveInstr config (cmmTypeFormat ty) xmm0 r_dest)+              | isFloatType ty =+                  -- we assume SSE2+                  let tmp_amode = AddrBaseIndex (EABaseReg esp)+                                                       EAIndexNone+                                                       (ImmInt 0)+                      fmt = floatFormat w+                         in toOL [ SUB II32 (OpImm (ImmInt b)) (OpReg esp),+                                   DELTA (delta0 - b),+                                   X87Store fmt  tmp_amode,+                                   -- X87Store only supported for the CDECL ABI+                                   -- NB: This code will need to be+                                   -- revisited once GHC does more work around+                                   -- SIGFPE f+                                   MOV fmt (OpAddr tmp_amode) (OpReg r_dest),+                                   ADD II32 (OpImm (ImmInt b)) (OpReg esp),+                                   DELTA delta0]+              | isWord64 ty    = toOL [MOV II32 (OpReg eax) (OpReg r_dest),+                                        MOV II32 (OpReg edx) (OpReg r_dest_hi)]+              | otherwise      = unitOL (MOV (intFormat w)+                                             (OpReg eax)+                                             (OpReg r_dest))+              where+                    ty = localRegType dest+                    w  = typeWidth ty+                    b  = widthInBytes w+                    r_dest_hi = getHiVRegFromLo r_dest+                    r_dest    = getLocalRegReg dest+            assign_code many = pprPanic "genForeignCall.assign_code - too many return values:" (ppr many)++        return (push_code `appOL`+                call `appOL`+                assign_code dest_regs)++genCCall64 :: CmmExpr           -- ^ address of function to call+           -> ForeignConvention -- ^ calling convention+           -> [CmmFormal]       -- ^ where to put the result+           -> [CmmActual]       -- ^ arguments (of mixed type)+           -> NatM InstrBlock+genCCall64 addr conv dest_regs args = do+    config <- getConfig+    let platform = ncgPlatform config+        word_size = platformWordSizeInBytes platform+        wordFmt = archWordFormat (target32Bit platform)++    -- Compute the code for loading arguments into registers,+    -- returning the leftover arguments that will need to be passed on the stack.+    --+    -- NB: the code for loading references to data into registers is computed+    -- later (in 'pushArgs'), because we don't yet know where the data will be+    -- placed (due to alignment requirements).+    LoadArgs+      { stackArgs       = proper_stack_args+      , stackDataArgs   = stack_data_args+      , usedRegs        = arg_regs_used+      , assignArgsCode  = assign_args_code+      }+      <- loadArgs config args++    let++    -- Pad all arguments and data passed on stack to align them properly.+        (stk_args_with_padding, args_aligned_16) =+          padStackArgs platform (proper_stack_args, stack_data_args)++    -- Align stack to 16n for calls, assuming a starting stack+    -- alignment of 16n - word_size on procedure entry. Which we+    -- maintain. See Note [Stack Alignment on X86] in rts/StgCRun.c+        need_realign_call = args_aligned_16+    align_call_code <-+      if need_realign_call+      then addStackPadding word_size+      else return nilOL++    -- Compute the code that pushes data to the stack, and also+    -- the code that loads references to that data into registers,+    -- when the data is passed by reference in a register.+    (load_data_refs, push_code) <-+      pushArgs config proper_stack_args stk_args_with_padding++    -- On Windows, leave stack space for the arguments that we are passing+    -- in registers (the so-called shadow space).+    let shadow_space =+          if platformOS platform == OSMinGW32+          then 8 * length (allArgRegs platform)+            -- NB: the shadow store is always 8 * 4 = 32 bytes large,+            -- i.e. the cumulative size of rcx, rdx, r8, r9 (see 'allArgRegs').+          else 0+    shadow_space_code <- addStackPadding shadow_space++    let total_args_size+          = shadow_space+          + sum (map (stackArgSpace platform) stk_args_with_padding)+        real_size =+          total_args_size + if need_realign_call then word_size else 0++    -- End of argument passing.+    --+    -- Next step: emit the appropriate call instruction.+    delta <- getDeltaNat++    let -- The System V AMD64 ABI requires us to set %al to the number of SSE2+        -- registers that contain arguments, if the called routine+        -- is a varargs function.  We don't know whether it's a+        -- varargs function or not, so we have to assume it is.+        --+        -- It's not safe to omit this assignment, even if the number+        -- of SSE2 regs in use is zero.  If %al is larger than 8+        -- on entry to a varargs function, seg faults ensue.+        nb_sse_regs_used = count (isFloatFormat . regWithFormat_format) arg_regs_used+        assign_eax_sse_regs+          = unitOL (MOV II32 (OpImm (ImmInt nb_sse_regs_used)) (OpReg eax))+          -- Note: we do this on Windows as well. It's not entirely clear why+          -- it's needed (the Windows X86_64 calling convention does not+          -- dictate it), but we get segfaults without it.+          --+          -- One test case exhibiting the issue is T20030_test1j;+          -- if you change this, make sure to run it in a loop for a while+          -- with at least -j8 to check.++        -- Live registers we are annotating the call instruction with+        arg_regs = [RegWithFormat eax wordFmt] ++ arg_regs_used++    -- deal with static vs dynamic call targets+    (callinsns,_cconv) <- case addr of+      CmmLit (CmmLabel lbl) ->+        return (unitOL (CALL (Left (ImmCLbl lbl)) arg_regs), conv)+      _ -> do+        (dyn_r, dyn_c) <- getSomeReg addr+        return (dyn_c `snocOL` CALL (Right dyn_r) arg_regs, conv)++    let call = callinsns `appOL`+               toOL (+                    -- Deallocate parameters after call for ccall+                  (if real_size==0 then [] else+                   [ADD (intFormat (platformWordWidth platform)) (OpImm (ImmInt real_size)) (OpReg esp)])+                  +++                  [DELTA (delta + real_size)]+               )+    setDeltaNat (delta + real_size)++    let+        -- assign the results, if necessary+        assign_code []     = nilOL+        assign_code [dest] =+          unitOL $+            mkRegRegMoveInstr config fmt reg r_dest+          where+            reg = if isIntFormat fmt then rax else xmm0+            fmt = cmmTypeFormat rep+            rep = localRegType dest+            r_dest = getRegisterReg platform (CmmLocal dest)+        assign_code _many = panic "genForeignCall.assign_code many"++    return (align_call_code     `appOL`+            push_code           `appOL`+            assign_args_code    `appOL`+            load_data_refs      `appOL`+            shadow_space_code   `appOL`+            assign_eax_sse_regs `appOL`+            call                `appOL`+            assign_code dest_regs)++-- -----------------------------------------------------------------------------+-- Loading arguments into registers for 64-bit C calls.++-- | Information needed to know how to pass arguments in a C call,+-- and in particular how to load them into registers.+data LoadArgs+  = LoadArgs+  -- | Arguments that should be passed on the stack+  { stackArgs     :: [RawStackArg]+  -- | Additional values to store onto the stack.+  , stackDataArgs :: [CmmExpr]+  -- | Which registers are we using for argument passing?+  , usedRegs      :: [RegWithFormat]+  -- | The code to assign arguments to registers used for argument passing.+  , assignArgsCode :: InstrBlock+  }+instance Semigroup LoadArgs where+  LoadArgs a1 d1 r1 j1 <> LoadArgs a2 d2 r2 j2+    = LoadArgs (a1 ++ a2) (d1 ++ d2) (r1 ++ r2) (j1 S.<> j2)+instance Monoid LoadArgs where+  mempty = LoadArgs [] [] [] nilOL++-- | An argument passed on the stack, either directly or by reference.+--+-- The padding information hasn't yet been computed (see 'StackArg').+data RawStackArg+  -- | Pass the argument on the stack directly.+  = RawStackArg { stackArgExpr :: CmmExpr }+  -- | Pass the argument by reference.+  | RawStackArgRef+    { stackRef :: StackRef+       -- ^ is the reference passed in a register, or on the stack?+    , stackRefArgSize :: Int+        -- ^ the size of the data pointed to+    }+  deriving ( Show )++-- | An argument passed on the stack, either directly or by reference,+-- with additional padding information.+data StackArg+  -- | Pass the argument on the stack directly.+  = StackArg+      { stackArgExpr :: CmmExpr+      , stackArgPadding :: Int+        -- ^ padding required (in bytes)+      }+  -- | Pass the argument by reference.+  | StackArgRef+     { stackRef :: StackRef+        -- ^ where the reference is passed+     , stackRefArgSize :: Int+        -- ^ the size of the data pointed to+     , stackRefArgPadding :: Int+       -- ^ padding of the data pointed to+       -- (the reference itself never requires padding)+     }+  deriving ( Show )++-- | Where is a reference to data on the stack passed?+data StackRef+  -- | In a register.+  = InReg Reg+  -- | On the stack.+  | OnStack+  deriving ( Eq, Ord, Show )++newtype Padding = Padding { paddingBytes :: Int }+  deriving ( Show, Eq, Ord )++-- | How much space does this 'StackArg' take up on the stack?+--+-- Only counts the "reference" part for references, not the data it points to.+stackArgSpace :: Platform -> StackArg -> Int+stackArgSpace platform = \case+  StackArg arg padding ->+    argSize platform arg + padding+  StackArgRef { stackRef = ref } ->+    case ref of+      InReg   {} -> 0+      OnStack {} -> 8++-- | Pad arguments, assuming we start aligned to a 16-byte boundary.+--+-- Returns padded arguments, together with whether we end up aligned+-- to a 16-byte boundary.+padStackArgs :: Platform+             -> ([RawStackArg], [CmmExpr])+             -> ([StackArg], Bool)+padStackArgs platform (args0, data_args0) =+  let+    -- Pad the direct args+    (args, align_16_mid) = pad_args True args0++    -- Pad the data section+    (data_args, align_16_end) = pad_args align_16_mid (map RawStackArg data_args0)++    -- Now figure out where the data is placed relative to the direct arguments,+    -- in order to resolve references.+    resolve_args :: [(RawStackArg, Padding)] -> [Padding] -> [StackArg]+    resolve_args [] _ = []+    resolve_args ((stk_arg, Padding pad):rest) pads =+      let (this_arg, pads') =+            case stk_arg of+              RawStackArg arg -> (StackArg arg pad, pads)+              RawStackArgRef ref size -> case pads of+                  Padding arg_pad : rest_pads ->+                    let arg = StackArgRef+                          { stackRef = ref+                          , stackRefArgSize = size+                          , stackRefArgPadding = arg_pad }+                    in (arg, rest_pads)+                  _ -> panic "padStackArgs: no padding info found for StackArgRef"+      in this_arg : resolve_args rest pads'++  in+    ( resolve_args args (fmap snd data_args) +++        [ case data_arg of+            RawStackArg arg -> StackArg arg pad+            RawStackArgRef {} -> panic "padStackArgs: reference in data section"+        | (data_arg, Padding pad) <- data_args+        ]+    , align_16_end )++  where+    pad_args :: Bool -> [RawStackArg] -> ([(RawStackArg, Padding)], Bool)+    pad_args aligned_16 [] = ([], aligned_16)+    pad_args aligned_16 (arg:args)+      | needed_alignment > 16+      -- We don't know if the stack is aligned to 8 (mod 32) or 24 (mod 32).+      -- This makes aligning the stack to a 32 or 64 byte boundary more+      -- complicated, in particular with DELTA.+      = sorry $ unlines+        [ "X86_86 C call: unsupported argument."+        , "  Alignment requirement: " ++ show needed_alignment ++ " bytes."+        , if platformOS platform == OSMinGW32+          then "  The X86_64 NCG does not (yet) support Windows C calls with 256/512 bit vectors."+          else "  The X86_64 NCG cannot (yet) pass 256/512 bit vectors on the stack for C calls."+        , "  Please use the LLVM backend (-fllvm)." ]+      | otherwise+      = let ( rest, final_align_16 ) = pad_args next_aligned_16 args+        in  ( (arg, Padding padding) : rest, final_align_16 )++      where+        needed_alignment = case arg of+          RawStackArg arg   -> argSize platform arg+          RawStackArgRef {} -> platformWordSizeInBytes platform+        padding+          | needed_alignment < 16 || aligned_16+          = 0+          | otherwise+          = 8+        next_aligned_16 = not ( aligned_16 && needed_alignment < 16 )++-- | Load arguments into available registers.+loadArgs :: NCGConfig -> [CmmExpr] -> NatM LoadArgs+loadArgs config args+  | platformOS platform == OSMinGW32+  = evalStateT (loadArgsWin config args) (allArgRegs platform)+  | otherwise+  = evalStateT (loadArgsSysV config args) (allIntArgRegs platform+                                          ,allFPArgRegs  platform)+  where+    platform = ncgPlatform config++-- | Load arguments into available registers (System V AMD64 ABI).+loadArgsSysV :: NCGConfig+             -> [CmmExpr]+             -> StateT ([Reg], [Reg]) NatM LoadArgs+loadArgsSysV _ [] = return mempty+loadArgsSysV config (arg:rest) = do+  (iregs, fregs) <- get+  -- No available registers: pass everything on the stack (shortcut).+  if null iregs && null fregs+  then return $+          LoadArgs+            { stackArgs       = map RawStackArg (arg:rest)+            , stackDataArgs   = []+            , assignArgsCode  = nilOL+            , usedRegs        = []+            }+  else do+    mbReg <-+      if+        | isIntFormat arg_fmt+        , ireg:iregs' <- iregs+        -> do put (iregs', fregs)+              return $ Just ireg+        | isFloatFormat arg_fmt || isVecFormat arg_fmt+        , freg:fregs' <- fregs+        -> do put (iregs, fregs')+              return $ Just freg+        | otherwise+        -> return Nothing+    this_arg <-+      case mbReg of+        Just reg -> do+          assign_code <- lift $ loadArgIntoReg arg reg+          return $+            LoadArgs+                { stackArgs       = [] -- passed in register+                , stackDataArgs   = []+                , assignArgsCode  = assign_code+                , usedRegs        = [RegWithFormat reg arg_fmt]+                }+        Nothing -> do+          return $+            -- No available register for this argument: pass it on the stack.+            LoadArgs+                { stackArgs       = [RawStackArg arg]+                , stackDataArgs   = []+                , assignArgsCode  = nilOL+                , usedRegs        = []+                }+    others <- loadArgsSysV config rest+    return $ this_arg S.<> others++  where+    platform = ncgPlatform config+    arg_fmt = cmmTypeFormat (cmmExprType platform arg)++-- | Compute all things that will need to be pushed to the stack.+--+-- On Windows, an argument passed by reference will require two pieces of data:+--+--  - the reference (returned in the first position)+--  - the actual data (returned in the second position)+computeWinPushArgs :: Platform -> [CmmExpr] -> ([RawStackArg], [CmmExpr])+computeWinPushArgs platform = go+  where+    go :: [CmmExpr] -> ([RawStackArg], [CmmExpr])+    go [] = ([], [])+    go (arg:args) =+      let+        arg_size = argSize platform arg+        (this_arg, add_this_arg)+          | arg_size > 8+          = ( RawStackArgRef OnStack arg_size, (arg :) )+          | otherwise+          = ( RawStackArg arg, id )+        (stk_args, stk_data) = go args+      in+        (this_arg:stk_args, add_this_arg stk_data)++-- | Load arguments into available registers (Windows C X64 calling convention).+loadArgsWin :: NCGConfig -> [CmmExpr] -> StateT [(Reg,Reg)] NatM LoadArgs+loadArgsWin _ [] = return mempty+loadArgsWin config (arg:rest) = do+  regs <- get+  case regs of+    reg:regs' -> do+      put regs'+      this_arg <- lift $ load_arg_win reg+      rest <- loadArgsWin config rest+      return $ this_arg S.<> rest+    [] -> do+      -- No more registers available: pass all (remaining) arguments on the stack.+      let (stk_args, data_args) = computeWinPushArgs platform (arg:rest)+      return $+        LoadArgs+          { stackArgs       = stk_args+          , stackDataArgs   = data_args+          , assignArgsCode  = nilOL+          , usedRegs        = []+          }+  where+    platform = ncgPlatform config+    arg_fmt = cmmTypeFormat $ cmmExprType platform arg+    load_arg_win (ireg, freg)+      | isVecFormat arg_fmt+       -- Vectors are passed by reference.+       -- See Note [The Windows X64 C calling convention].+      = do return $+             LoadArgs+                -- Pass the reference in a register,+                -- and the argument data on the stack.+                { stackArgs       = [RawStackArgRef (InReg ireg) (argSize platform arg)]+                , stackDataArgs   = [arg] -- we don't yet know where the data will reside,+                , assignArgsCode  = nilOL -- so we defer computing the reference and storing it+                                          -- in the register until later+                , usedRegs        = [RegWithFormat ireg II64]+                }+      | otherwise+      = do let arg_reg+                  | isFloatFormat arg_fmt+                  = freg+                  | otherwise+                  = ireg+           assign_code <- loadArgIntoReg arg arg_reg+           -- Recall that, for varargs, we must pass floating-point+           -- arguments in both fp and integer registers.+           let (assign_code', regs')+                | isFloatFormat arg_fmt =+                    ( assign_code `snocOL` MOVD FF64 II64 (OpReg freg) (OpReg ireg),+                      [ RegWithFormat freg FF64+                      , RegWithFormat ireg II64 ])+                | otherwise = (assign_code, [RegWithFormat ireg II64])+           return $+             LoadArgs+               { stackArgs       = [] -- passed in register+               , stackDataArgs   = []+               , assignArgsCode = assign_code'+               , usedRegs = regs'+               }++-- | Load an argument into a register.+--+-- Assumes that the expression does not contain any MachOps,+-- as per Note [Evaluate C-call arguments before placing in destination registers].+loadArgIntoReg :: CmmExpr -> Reg -> NatM InstrBlock+loadArgIntoReg arg reg = do+  when (debugIsOn && loadIntoRegMightClobberOtherReg arg) $ do+    platform <- getPlatform+    massertPpr False $+      vcat [ text "loadArgIntoReg: arg might contain MachOp"+           , text "arg:" <+> pdoc platform arg ]+  arg_code <- getAnyReg arg+  return $ arg_code reg++-- -----------------------------------------------------------------------------+-- Pushing arguments onto the stack for 64-bit C calls.++-- | The size of an argument (in bytes).+--+-- Never smaller than the platform word width.+argSize :: Platform -> CmmExpr -> Int+argSize platform arg =+  max (platformWordSizeInBytes platform) $+    widthInBytes (typeWidth $ cmmExprType platform arg)++-- | Add the given amount of padding on the stack.+addStackPadding :: Int -- ^ padding (in bytes)+                -> NatM InstrBlock+addStackPadding pad_bytes+  | pad_bytes == 0+  = return nilOL+  | otherwise+  = do delta <- getDeltaNat+       setDeltaNat (delta - pad_bytes)+       return $+         toOL [ SUB II64 (OpImm (ImmInt pad_bytes)) (OpReg rsp)+              , DELTA (delta - pad_bytes)+              ]++-- | Push one argument directly to the stack (by value).+--+-- Assumes the current stack pointer fulfills any necessary alignment requirements.+pushArgByValue :: NCGConfig -> CmmExpr -> NatM InstrBlock+pushArgByValue config arg+   -- For 64-bit integer arguments, use PUSH II64.+   --+   -- Note: we *must not* do this for smaller arguments.+   -- For example, if we tried to push an argument such as @CmmLoad addr W32 aln@,+   -- we could end up reading unmapped memory and segfaulting.+   | isIntFormat fmt+   , formatInBytes fmt == 8+   = do+     (arg_op, arg_code) <- getOperand arg+     delta <- getDeltaNat+     setDeltaNat (delta-arg_size)+     return $+       arg_code `appOL` toOL+       [ PUSH II64 arg_op+       , DELTA (delta-arg_size) ]++   | otherwise+   = do+     (arg_reg, arg_code) <- getSomeReg arg+     delta <- getDeltaNat+     setDeltaNat (delta-arg_size)+     return $ arg_code `appOL` toOL+        [ SUB (intFormat (wordWidth platform)) (OpImm (ImmInt arg_size)) (OpReg rsp)+        , DELTA (delta-arg_size)+        , movInstr config fmt (OpReg arg_reg) (OpAddr (spRel platform 0)) ]++    where+      platform = ncgPlatform config+      arg_size = argSize platform arg+      arg_rep = cmmExprType platform arg+      fmt = cmmTypeFormat arg_rep++-- | Load an argument into a register or push it to the stack.+loadOrPushArg :: NCGConfig -> (StackArg, Maybe Int) -> NatM (InstrBlock, InstrBlock)+loadOrPushArg config (stk_arg, mb_off) =+  case stk_arg of+    StackArg arg pad -> do+      push_code <- pushArgByValue config arg+      pad_code  <- addStackPadding pad+      return (nilOL, push_code `appOL` pad_code)+    StackArgRef { stackRef = ref } ->+      case ref of+        -- Pass the reference in a register+        InReg ireg ->+          return (unitOL $ LEA II64 (OpAddr (spRel platform off)) (OpReg ireg), nilOL)+        -- Pass the reference on the stack+        OnStack {} -> do+          tmp <- getNewRegNat II64+          delta <- getDeltaNat+          setDeltaNat (delta-arg_ref_size)+          let push_code = toOL+                [ SUB (intFormat (wordWidth platform)) (OpImm (ImmInt arg_ref_size)) (OpReg rsp)+                , DELTA (delta-arg_ref_size)+                , LEA II64 (OpAddr (spRel platform off)) (OpReg tmp)+                , MOV II64 (OpReg tmp) (OpAddr (spRel platform 0)) ]+          return (nilOL, push_code)+      where off = expectJust mb_off+    where+      arg_ref_size = 8 -- passing a reference to the argument+      platform = ncgPlatform config++-- | Push arguments to the stack, right to left.+--+-- On Windows, some arguments may need to be passed by reference,+-- which requires separately passing the data and the reference.+-- See Note [The Windows X64 C calling convention].+pushArgs :: NCGConfig+         -> [RawStackArg]+            -- ^ arguments proper (i.e. don't include the data for arguments passed by reference)+         -> [StackArg]+            -- ^ arguments we are passing on the stack+         -> NatM (InstrBlock, InstrBlock)+pushArgs config proper_args all_stk_args+  = do { let+            vec_offs :: [Maybe Int]+            vec_offs+              | platformOS platform == OSMinGW32+              = go stack_arg_size all_stk_args+              | otherwise+              = repeat Nothing++    ---------------------+    -- Windows-only code++            -- Size of the arguments we are passing on the stack, counting only+            -- the reference part for arguments passed by reference.+            stack_arg_size = 8 * count not_in_reg proper_args+            not_in_reg (RawStackArg {}) = True+            not_in_reg (RawStackArgRef { stackRef = ref }) =+              case ref of+                InReg {} -> False+                OnStack {} -> True++            -- Check an offset is valid (8-byte aligned), for assertions.+            ok off = off `rem` 8 == 0++            -- Tricky code: compute the stack offset to the vector data+            -- for this argument.+            --+            -- If you're confused, Note [The Windows X64 C calling convention]+            -- contains a helpful diagram.+            go :: Int -> [StackArg] -> [Maybe Int]+            go _ [] = []+            go off (stk_arg:args) =+              assertPpr (ok off) (text "unaligned offset:" <+> ppr off) $+              case stk_arg of+                StackArg {} ->+                  -- Only account for the stack pointer movement.+                  let off' = off - stackArgSpace platform stk_arg+                  in Nothing : go off' args+                StackArgRef+                  { stackRefArgSize    = data_size+                  , stackRefArgPadding = data_pad } ->+                  assertPpr (ok data_size) (text "unaligned data size:" <+> ppr data_size) $+                  assertPpr (ok data_pad) (text "unaligned data padding:" <+> ppr data_pad) $+                  let off' = off+                        -- Next piece of data is after the data for this reference+                           + data_size + data_pad+                        -- ... and account for the stack pointer movement.+                           - stackArgSpace platform stk_arg+                  in Just (data_pad + off) : go off' args++    -- end of Windows-only code+    ----------------------------++         -- Push the stack arguments (right to left),+         -- including both the reference and the data for arguments passed by reference.+       ; (load_regs, push_args) <- foldMapM (loadOrPushArg config) (reverse $ zip all_stk_args vec_offs)+       ; return (load_regs, push_args) }+  where+    platform = ncgPlatform config++{- Note [The Windows X64 C calling convention]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+Here are a few facts about the Windows X64 C calling convention that+are important:++  - any argument larger than 8 bytes must be passed by reference,+    and arguments smaller than 8 bytes are padded to 8 bytes.++  - the first four arguments are passed in registers:+      - floating-point scalar arguments are passed in %xmm0, %xmm1, %xmm2, %xmm3+      - other arguments are passed in %rcx, %rdx, %r8, %r9+        (this includes vector arguments, passed by reference)++    For variadic functions, it is additionally expected that floating point+    scalar arguments are copied to the corresponding integer register, e.g.+    the data in xmm2 should also be copied to r8.++    There is no requirement about setting %al like there is for the+    System V AMD64 ABI.++  - subsequent arguments are passed on the stack.++There are also alignment requirements:++  - the data for vectors must be aligned to the size of the vector,+    e.g. a 32 byte vector must be aligned on a 32 byte boundary,++  - the call instruction must be aligned to 16 bytes.+  (This differs from the System V AMD64 ABI, which mandates that the call+  instruction must be aligned to 32 bytes if there are any 32 byte vectors+  passed on the stack.)++This motivates our handling of vector values. Suppose we have a function call+with many arguments, several of them being vectors. We proceed as follows:++ - Add some padding, if necessary, to ensure the stack, when executing the call+    instruction, is 16-byte aligned. Whether this padding is necessary depends+    on what happens next. (Recall also that we start off at 8 (mod 16) alignment,+    as per Note [Stack Alignment on X86] in rts/StgCRun.c)+  - Push all the vectors to the stack first, adding padding after each one+    if necessary.+  - Then push the arguments:+      - for non-vectors, proceed as usual,+      - for vectors, push the address of the vector data we pushed above.+  - Then assign the registers:+      - for non-vectors, proceed as usual,+      - for vectors, store the address in a general-purpose register, as opposed+        to storing the data in an xmm register.++For a concrete example, suppose we have a call of the form:++  f x1 x2 x3 x4 x5 x6 x7++in which:++  - x2, x3, x5 and x7 are 16 byte vectors+  - the other arguments are all 8 byte wide++Now, x1, x2, x3, x4 will get passed in registers, except that we pass+x2 and x3 by reference, because they are vectors. We proceed as follows:++  - push the vectors to the stack: x7, x5, x3, x2 (in that order)+  - push the stack arguments in order: addr(x7), x6, addr(x5)+  - load the remaining arguments into registers: x4, addr(x3), addr(x2), x1++The tricky part is to get the right offsets for the addresses of the vector+data. The following visualisation will hopefully clear things up:++                                  ┌──┐+                                  │▓▓│ ─── padding to align the call instruction+                      ╭─╴         ╞══╡     (ensures Sp, below, is 16-byte aligned)+                      │           │  │+                      │  x7  ───╴ │  │+                      │           ├──┤+                      │           │  │+                      │  x5  ───╴ │  │+                      │           ├──┤+     vector data  ────┤           │  │+(individually padded) │  x3  ───╴ │  │+                      │           ├──┤+                      │           │  │+                      │  x2  ───╴ │  │+                      │           ├┄┄┤+                      │           │▓▓│ ─── padding to align x2 to 16 bytes+               ╭─╴    ╰─╴         ╞══╡+               │    addr(x7) ───╴ │  │    ╭─ from here: x7 is +64+               │                  ├──┤ ╾──╯    = 64 (position of x5)+     stack  ───┤         x6  ───╴ │  │         + 16 (size of x5) + 0 (padding of x7)+   arguments   │                  ├──┤         - 2 * 8 (x7 is 2 arguments higher than x5)+               │    addr(x5) ───╴ │  │+               ╰─╴            ╭─╴ ╞══╡ ╾─── from here:+                              │   │  │       - x2 is +32 = 24 (stack_arg_size) + 8 (padding of x2)+                   shadow  ───┤   │  │       - x3 is +48 = 32 (position of x2) + 16 (size of x2) + 0 (padding of x3)+                    space     │   │  │       - x5 is +64 = 48 (position of x3) + 16 (size of x3) + 0 (padding of x5)+                              │   │  │+                              ╰─╴ └──┘ ╾─── Sp++This is all tested in the simd013 test.+-}++-- -----------------------------------------------------------------------------+-- Generating a table-branch++{-+Note [Sub-word subtlety during jump-table indexing]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+Offset the index by the start index of the jump table.+It's important that we do this *before* the widening below. To see+why, consider a switch with a sub-word, signed discriminant such as:++    switch [-5...+2] x::I16 {+        case -5: ...+        ...+        case +2: ...+    }++Consider what happens if we offset *after* widening in the case that+x=-4:++                                         // x == -4 == 0xfffc::I16+    indexWidened = UU_Conv(x);           // == 0xfffc::I64+    indexExpr    = indexWidened - (-5);  // == 0x10000::I64++This index is clearly nonsense given that the jump table only has+eight entries.++By contrast, if we widen *after* we offset then we get the correct+index (1),++                                         // x == -4 == 0xfffc::I16+    indexOffset  = x - (-5);             // == 1::I16+    indexExpr    = UU_Conv(indexOffset); // == 1::I64++See #21186.+-}++genSwitch :: CmmExpr -> SwitchTargets -> NatM InstrBlock++genSwitch expr targets = do+  config <- getConfig+  let platform = ncgPlatform config+      expr_w = cmmExprWidth platform expr+      indexExpr0 = cmmOffset platform expr offset+      -- We widen to a native-width register because we cannot use arbitrary sizes+      -- in x86 addressing modes.+      -- See Note [Sub-word subtlety during jump-table indexing].+      indexExpr = CmmMachOp+        (MO_UU_Conv expr_w (platformWordWidth platform))+        [indexExpr0]+  if ncgPIC config+  then do+        (reg,e_code) <- getNonClobberedReg indexExpr+           -- getNonClobberedReg because it needs to survive across t_code+        lbl <- getNewLabelNat+        let is32bit = target32Bit platform+            os = platformOS platform+            -- Might want to use .rodata.<function we're in> instead, but as+            -- long as it's something unique it'll work out since the+            -- references to the jump table are in the appropriate section.+            rosection = case os of+              -- on Mac OS X/x86_64, put the jump table in the text section to+              -- work around a limitation of the linker.+              -- ld64 is unable to handle the relocations for+              --     .quad L1 - L0+              -- if L0 is not preceded by a non-anonymous label in its section.+              OSDarwin | not is32bit -> Section Text lbl+              _ -> Section ReadOnlyData lbl+        dynRef <- cmmMakeDynamicReference config DataReference lbl+        (tableReg,t_code) <- getSomeReg $ dynRef+        let op = OpAddr (AddrBaseIndex (EABaseReg tableReg)+                                       (EAIndex reg (platformWordSizeInBytes platform)) (ImmInt 0))++        return $ e_code `appOL` t_code `appOL` toOL [+                                ADD (intFormat (platformWordWidth platform)) op (OpReg tableReg),+                                JMP_TBL (OpReg tableReg) ids rosection lbl+                       ]+  else do+        (reg,e_code) <- getSomeReg indexExpr+        lbl <- getNewLabelNat+        let is32bit = target32Bit platform+        if is32bit+          then let op = OpAddr (AddrBaseIndex EABaseNone (EAIndex reg (platformWordSizeInBytes platform)) (ImmCLbl lbl))+                   jmp_code = JMP_TBL op ids (Section ReadOnlyData lbl) lbl+               in return $ e_code `appOL` unitOL jmp_code+          else do+            -- See Note [%rip-relative addressing on x86-64].+            tableReg <- getNewRegNat (intFormat (platformWordWidth platform))+            targetReg <- getNewRegNat (intFormat (platformWordWidth platform))+            let op = OpAddr (AddrBaseIndex (EABaseReg tableReg) (EAIndex reg (platformWordSizeInBytes platform)) (ImmInt 0))+                fmt = archWordFormat is32bit+                code = e_code `appOL` toOL+                    [ LEA fmt (OpAddr (AddrBaseIndex EABaseRip EAIndexNone (ImmCLbl lbl))) (OpReg tableReg)+                    , MOV fmt op (OpReg targetReg)+                    , JMP_TBL (OpReg targetReg) ids (Section ReadOnlyData lbl) lbl+                    ]+            return code+  where+    (offset, blockIds) = switchTargetsToTable targets+    ids = map (fmap DestBlockId) blockIds++generateJumpTableForInstr :: NCGConfig -> Instr -> Maybe (NatCmmDecl (Alignment, RawCmmStatics) Instr)+generateJumpTableForInstr config (JMP_TBL _ ids section lbl)+    = let getBlockId (DestBlockId id) = id+          getBlockId _ = panic "Non-Label target in Jump Table"+          blockIds = map (fmap getBlockId) ids+      in Just (createJumpTable config blockIds section lbl)+generateJumpTableForInstr _ _ = Nothing++createJumpTable :: NCGConfig -> [Maybe BlockId] -> Section -> CLabel+                -> GenCmmDecl (Alignment, RawCmmStatics) h g+createJumpTable config ids section lbl+    = let jumpTable+            | ncgPIC config =+                  let ww = ncgWordWidth config+                      jumpTableEntryRel Nothing+                          = CmmStaticLit (CmmInt 0 ww)+                      jumpTableEntryRel (Just blockid)+                          = CmmStaticLit (CmmLabelDiffOff blockLabel lbl 0 ww)+                          where blockLabel = blockLbl blockid+                  in map jumpTableEntryRel ids+            | otherwise = map (jumpTableEntry config) ids+      in CmmData section (mkAlignment 1, CmmStaticsRaw lbl jumpTable)++extractUnwindPoints :: [Instr] -> [UnwindPoint]+extractUnwindPoints instrs =+    [ UnwindPoint lbl unwinds | UNWIND lbl unwinds <- instrs]++-- -----------------------------------------------------------------------------+-- 'condIntReg' and 'condFltReg': condition codes into registers++-- Turn those condition codes into integers now (when they appear on+-- the right hand side of an assignment).+--+-- (If applicable) Do not fill the delay slots here; you will confuse the+-- register allocator.++condIntReg :: Cond -> CmmExpr -> CmmExpr -> NatM Register++condIntReg cond x y = do+  CondCode _ cond cond_code <- condIntCode cond x y+  tmp <- getNewRegNat II8+  let+        code dst = cond_code `appOL` toOL [+                    SETCC cond (OpReg tmp),+                    MOVZxL II8 (OpReg tmp) (OpReg dst)+                  ]+  return (Any II32 code)+++-- Note [SSE Parity Checks]+-- ~~~~~~~~~~~~~~~~~~~~~~~~+-- We have to worry about unordered operands (eg. comparisons+-- against NaN).  If the operands are unordered, the comparison+-- sets the parity flag, carry flag and zero flag.+-- All comparisons are supposed to return false for unordered+-- operands except for !=, which returns true.+--+-- Optimisation: we don't have to test the parity flag if we+-- know the test has already excluded the unordered case: eg >+-- and >= test for a zero carry flag, which can only occur for+-- ordered operands.+--+-- By reversing comparisons we can avoid testing the parity+-- for < and <= as well. If any of the arguments is an NaN we+-- return false either way. If both arguments are valid then+-- x <= y  <->  y >= x  holds. So it's safe to swap these.+--+-- We invert the condition inside getRegister'and  getCondCode+-- which should cover all invertable cases.+-- All other functions translating FP comparisons to assembly+-- use these to two generate the comparison code.+--+-- As an example consider a simple check:+--+-- func :: Float -> Float -> Int+-- func x y = if x < y then 1 else 0+--+-- Which in Cmm gives the floating point comparison.+--+--  if (%MO_F_Lt_W32(F1, F2)) goto c2gg; else goto c2gf;+--+-- We used to compile this to an assembly code block like this:+-- _c2gh:+--  ucomiss %xmm2,%xmm1+--  jp _c2gf+--  jb _c2gg+--  jmp _c2gf+--+-- Where we have to introduce an explicit+-- check for unordered results (using jmp parity):+--+-- We can avoid this by exchanging the arguments and inverting the direction+-- of the comparison. This results in the sequence of:+--+--  ucomiss %xmm1,%xmm2+--  ja _c2g2+--  jmp _c2g1+--+-- Removing the jump reduces the pressure on the branch prediction system+-- and plays better with the uOP cache.++condFltReg :: Bool -> Cond -> CmmExpr -> CmmExpr -> NatM Register+condFltReg is32Bit cond x y = condFltReg_sse2+ where+++  condFltReg_sse2 = do+    CondCode _ cond cond_code <- condFltCode cond x y+    tmp1 <- getNewRegNat (archWordFormat is32Bit)+    tmp2 <- getNewRegNat (archWordFormat is32Bit)+    let -- See Note [SSE Parity Checks]+        code dst =+           cond_code `appOL`+             (case cond of+                NE  -> or_unordered dst+                GU  -> plain_test   dst+                GEU -> plain_test   dst+                -- Use ASSERT so we don't break releases if these creep in.+                LTT -> assertPpr False (text "Should have been turned into >") $+                       and_ordered  dst+                LE  -> assertPpr False (text "Should have been turned into >=") $+                       and_ordered  dst+                _   -> and_ordered  dst)++        plain_test dst = toOL [+                    SETCC cond (OpReg tmp1),+                    MOVZxL II8 (OpReg tmp1) (OpReg dst)+                 ]+        or_unordered dst = toOL [+                    SETCC cond (OpReg tmp1),+                    SETCC PARITY (OpReg tmp2),+                    OR II8 (OpReg tmp1) (OpReg tmp2),+                    MOVZxL II8 (OpReg tmp2) (OpReg dst)+                  ]+        and_ordered dst = toOL [+                    SETCC cond (OpReg tmp1),+                    SETCC NOTPARITY (OpReg tmp2),+                    AND II8 (OpReg tmp1) (OpReg tmp2),+                    MOVZxL II8 (OpReg tmp2) (OpReg dst)+                  ]+    return (Any II32 code)+++-- -----------------------------------------------------------------------------+-- 'trivial*Code': deal with trivial instructions++-- Trivial (dyadic: 'trivialCode', floating-point: 'trivialFCode',+-- unary: 'trivialUCode', unary fl-pt:'trivialUFCode') instructions.+-- Only look for constants on the right hand side, because that's+-- where the generic optimizer will have put them.++-- Similarly, for unary instructions, we don't have to worry about+-- matching an StInt as the argument, because genericOpt will already+-- have handled the constant-folding.+++{-+The Rules of the Game are:++* You cannot assume anything about the destination register dst;+  it may be anything, including a fixed reg.++* You may compute an operand into a fixed reg, but you may not+  subsequently change the contents of that fixed reg.  If you+  want to do so, first copy the value either to a temporary+  or into dst.  You are free to modify dst even if it happens+  to be a fixed reg -- that's not your problem.++* You cannot assume that a fixed reg will stay live over an+  arbitrary computation.  The same applies to the dst reg.++* Temporary regs obtained from getNewRegNat are distinct from+  each other and from all other regs, and stay live over+  arbitrary computations.++--------------------++SDM's version of The Rules:++* If getRegister returns Any, that means it can generate correct+  code which places the result in any register, period.  Even if that+  register happens to be read during the computation.++  Corollary #1: this means that if you are generating code for an+  operation with two arbitrary operands, you cannot assign the result+  of the first operand into the destination register before computing+  the second operand.  The second operand might require the old value+  of the destination register.++  Corollary #2: A function might be able to generate more efficient+  code if it knows the destination register is a new temporary (and+  therefore not read by any of the sub-computations).++* If getRegister returns Any, then the code it generates may modify only:+        (a) fresh temporaries+        (b) the destination register+        (c) known registers (eg. %ecx is used by shifts)+  In particular, it may *not* modify global registers, unless the global+  register happens to be the destination register.+-}++trivialCode :: Width -> (Operand -> Operand -> Instr)+            -> Maybe (Operand -> Operand -> Instr)+            -> CmmExpr -> CmmExpr -> NatM Register+trivialCode width instr m a b+    = do platform <- getPlatform+         trivialCode' platform width instr m a b++trivialCode' :: Platform -> Width -> (Operand -> Operand -> Instr)+             -> Maybe (Operand -> Operand -> Instr)+             -> CmmExpr -> CmmExpr -> NatM Register+trivialCode' platform width _ (Just revinstr) (CmmLit lit_a) b+  | is32BitLit platform lit_a = do+  b_code <- getAnyReg b+  let+       code dst+         = b_code dst `snocOL`+           revinstr (OpImm (litToImm lit_a)) (OpReg dst)+  return (Any (intFormat width) code)++trivialCode' _ width instr _ a b+  = genTrivialCode (intFormat width) (\op2 -> instr op2 . OpReg) a b++-- This is re-used for floating pt instructions too.+genTrivialCode :: Format -> (Operand -> Reg -> Instr)+               -> CmmExpr -> CmmExpr -> NatM Register+genTrivialCode rep instr a b = do+  (b_op, b_code) <- getNonClobberedOperand b+  a_code <- getAnyReg a+  tmp <- getNewRegNat rep+  let+     -- We want the value of 'b' to stay alive across the computation of 'a'.+     -- But, we want to calculate 'a' straight into the destination register,+     -- because the instruction only has two operands (dst := dst `op` src).+     -- The troublesome case is when the result of 'b' is in the same register+     -- as the destination 'reg'.  In this case, we have to save 'b' in a+     -- new temporary across the computation of 'a'.+     code dst+        | dst `regClashesWithOp` b_op =+                b_code `appOL`+                unitOL (MOV rep b_op (OpReg tmp)) `appOL`+                a_code dst `snocOL`+                instr (OpReg tmp) dst+        | otherwise =+                b_code `appOL`+                a_code dst `snocOL`+                instr b_op dst+  return (Any rep code)++regClashesWithOp :: Reg -> Operand -> Bool+reg `regClashesWithOp` OpReg reg2   = reg == reg2+reg `regClashesWithOp` OpAddr amode = any (==reg) (addrModeRegs amode)+_   `regClashesWithOp` _            = False++-- | Generate code for a fused multiply-add operation, of the form @± x * y ± z@,+-- with 3 operands (FMA3 instruction set).+genFMA3Code :: Length+            -> Width+            -> FMASign+            -> CmmExpr -> CmmExpr -> CmmExpr -> NatM Register+genFMA3Code l w signs x y z = do+  config <- getConfig+  -- For the FMA instruction, we want to compute x * y + z+  --+  -- There are three possible instructions we could emit:+  --+  --   - fmadd213 z y x, result in x, z can be a memory address+  --   - fmadd132 x z y, result in y, x can be a memory address+  --   - fmadd231 y x z, result in z, y can be a memory address+  --+  -- This suggests two possible optimisations:+  --+  --   - OPTIMISATION 1+  --     If one argument is an address, use the instruction that allows+  --     a memory address in that position.+  --+  --   - OPTIMISATION 2+  --     If one argument is in a fixed register, use the instruction that puts+  --     the result in that same register.+  --+  -- Currently we follow neither of these optimisations,+  -- opting to always use fmadd213 for simplicity.+  --+  -- We would like to compute the result directly into the requested register.+  -- To do so we must first compute `x` into the destination register. This is+  -- only possible if the other arguments don't use the destination register.+  -- We check for this and if there is a conflict we move the result only after+  -- the computation. See #24496 how this went wrong in the past.+  let rep+        | l == 1+        = floatFormat w+        | otherwise+        = vecFormat (cmmVec l $ cmmFloat w)+  (y_reg, y_code) <- getNonClobberedReg y+  (z_op, z_code) <- getNonClobberedOperand z+  x_code <- getAnyReg x+  x_tmp <- getNewRegNat rep+  let+     fma213 = FMA3 rep signs FMA213++     code, code_direct, code_mov :: Reg -> InstrBlock+     -- Ideal: Compute the result directly into dst+     code_direct dst = x_code dst `snocOL`+                       fma213 z_op y_reg dst+     -- Fallback: Compute the result into a tmp reg and then move it.+     code_mov dst    = x_code x_tmp `snocOL`+                       fma213 z_op y_reg x_tmp `snocOL`+                       mkRegRegMoveInstr config rep x_tmp dst++     code dst =+        y_code `appOL`+        z_code `appOL`+        ( if arg_regs_conflict then code_mov dst else code_direct dst )++      where++        arg_regs_conflict =+          y_reg == dst ||+          case z_op of+            OpReg z_reg -> z_reg == dst+            OpAddr amode -> dst `elem` addrModeRegs amode+            OpImm {} -> False++  -- NB: Computing the result into a desired register using Any can be tricky.+  -- So for now, we keep it simple. (See #24496).+  return (Any rep code)++-----------++trivialUCode :: Format -> (Operand -> Instr)+             -> CmmExpr -> NatM Register+trivialUCode rep instr x = do+  x_code <- getAnyReg x+  let+     code dst =+        x_code dst `snocOL`+        instr (OpReg dst)+  return (Any rep code)++-----------+++trivialFCode_sse2 :: Width -> (Format -> Operand -> Reg -> Instr)+                  -> CmmExpr -> CmmExpr -> NatM Register+trivialFCode_sse2 ty instr x y+    = genTrivialCode format (instr format) x y+    where format = floatFormat ty+++--------------------------------------------------------------------------------+coerceInt2FP :: Width -> Width -> CmmExpr -> NatM Register+coerceInt2FP from to x =  coerce_sse2+ where++   coerce_sse2 = do+     (x_op, x_code) <- getOperand x  -- ToDo: could be a safe operand+     let+           opc  = case to of W32 -> CVTSI2SS; W64 -> CVTSI2SD+                             n -> panic $ "coerceInt2FP.sse: unhandled width ("+                                         ++ show n ++ ")"+           code dst = x_code `snocOL` opc (intFormat from) x_op dst+     return (Any (floatFormat to) code)+        -- works even if the destination rep is <II32++--------------------------------------------------------------------------------+coerceFP2Int :: Width -> Width -> CmmExpr -> NatM Register+coerceFP2Int from to x =  coerceFP2Int_sse2+ where+   coerceFP2Int_sse2 = do+     (x_op, x_code) <- getOperand x  -- ToDo: could be a safe operand+     let+           opc  = case from of W32 -> CVTTSS2SIQ; W64 -> CVTTSD2SIQ;+                               n -> panic $ "coerceFP2Init.sse: unhandled width ("+                                           ++ show n ++ ")"+           code dst = x_code `snocOL` opc (intFormat to) x_op dst+     return (Any (intFormat to) code)+         -- works even if the destination rep is <II32+++--------------------------------------------------------------------------------+coerceFP2FP :: Width -> CmmExpr -> NatM Register+coerceFP2FP to x = do+  (x_reg, x_code) <- getSomeReg x+  let+        opc  = case to of W32 -> CVTSD2SS; W64 -> CVTSS2SD;+                                     n -> panic $ "coerceFP2FP: unhandled width ("+                                                 ++ show n ++ ")"+        code dst = x_code `snocOL` opc x_reg dst+  return (Any ( floatFormat to) code)++--------------------------------------------------------------------------------++sse2NegCode :: Width -> CmmExpr -> NatM Register+sse2NegCode w x = do+  let fmt = floatFormat w+  x_code <- getAnyReg x+  -- This is how gcc does it, so it can't be that bad:+  let+    const = case fmt of+      FF32 -> CmmInt 0x80000000 W32+      FF64 -> CmmInt 0x8000000000000000 W64+      x@II8  -> wrongFmt x+      x@II16 -> wrongFmt x+      x@II32 -> wrongFmt x+      x@II64 -> wrongFmt x+      x@(VecFormat {}) -> wrongFmt x++      where+        wrongFmt x = panic $ "sse2NegCode: " ++ show x+  Amode amode amode_code <- memConstant (mkAlignment $ widthInBytes w) const+  tmp <- getNewRegNat fmt+  let+    code dst = x_code dst `appOL` amode_code `appOL` toOL [+        MOV fmt (OpAddr amode) (OpReg tmp),+        XOR fmt (OpReg tmp) (OpReg dst)+        ]+  --+  return (Any fmt code)++needLlvm :: MachOp -> NatM a+needLlvm mop =+  sorry $ unlines [ "Unsupported vector instruction for the native code generator:"+                  , show mop+                  , "Please use -fllvm." ]++incorrectOperands :: NatM a+incorrectOperands = sorry "Incorrect number of operands"++invalidConversion :: Width -> Width -> NatM a+invalidConversion from to =+  sorry $ "Invalid conversion operation from " ++ show from ++ " to " ++ show to++-- | This works on the invariant that all jumps in the given blocks are required.+--   Starting from there we try to make a few more jumps redundant by reordering+--   them.+--   We depend on the information in the CFG to do so so without a given CFG+--   we do nothing.+invertCondBranches :: Maybe CFG  -- ^ CFG if present+                   -> LabelMap a -- ^ Blocks with info tables+                   -> [NatBasicBlock Instr] -- ^ List of basic blocks+                   -> [NatBasicBlock Instr]+invertCondBranches Nothing _       bs = bs+invertCondBranches (Just cfg) keep bs =+    invert bs+  where+    invert :: [NatBasicBlock Instr] -> [NatBasicBlock Instr]+    invert (BasicBlock lbl1 ins:b2@(BasicBlock lbl2 _):bs)+      | --pprTrace "Block" (ppr lbl1) True,+        Just (jmp1,jmp2) <- last2 ins+      , JXX cond1 target1 <- jmp1+      , target1 == lbl2+      --, pprTrace "CutChance" (ppr b1) True+      , JXX ALWAYS target2 <- jmp2+      -- We have enough information to check if we can perform the inversion+      -- TODO: We could also check for the last asm instruction which sets+      -- status flags instead. Which I suspect is worse in terms of compiler+      -- performance, but might be applicable to more cases+      , Just edgeInfo1 <- getEdgeInfo lbl1 target1 cfg+      , Just edgeInfo2 <- getEdgeInfo lbl1 target2 cfg+      -- Both jumps come from the same cmm statement+      , transitionSource edgeInfo1 == transitionSource edgeInfo2+      , CmmSource {trans_cmmNode = cmmCondBranch} <- transitionSource edgeInfo1++      --Int comparisons are invertable+      , CmmCondBranch (CmmMachOp op _args) _ _ _ <- cmmCondBranch+      , Just _ <- maybeIntComparison op+      , Just invCond <- maybeInvertCond cond1++      --Swap the last two jumps, invert the conditional jumps condition.+      = let jumps =+              case () of+                -- We are free the eliminate the jmp. So we do so.+                _ | not (mapMember target1 keep)+                    -> [JXX invCond target2]+                -- If the conditional target is unlikely we put the other+                -- target at the front.+                  | edgeWeight edgeInfo2 > edgeWeight edgeInfo1+                    -> [JXX invCond target2, JXX ALWAYS target1]+                -- Keep things as-is otherwise+                  | otherwise+                    -> [jmp1, jmp2]+        in --pprTrace "Cutable" (ppr [jmp1,jmp2] <+> text "=>" <+> ppr jumps) $+           (BasicBlock lbl1+            (dropTail 2 ins ++ jumps))+            : invert (b2:bs)+    invert (b:bs) = b : invert bs+    invert [] = []++genAtomicRMW+  :: BlockId+  -> Width+  -> AtomicMachOp+  -> LocalReg+  -> CmmExpr+  -> CmmExpr+  -> NatM (InstrBlock, Maybe BlockId)+genAtomicRMW bid width amop dst addr n = do+    Amode amode addr_code <-+        if amop `elem` [AMO_Add, AMO_Sub]+        then getAmode addr+        else getSimpleAmode addr  -- See genForeignCall for MO_Cmpxchg+    arg <- getNewRegNat format+    arg_code <- getAnyReg n+    platform <- ncgPlatform <$> getConfig++    let dst_r    = getRegisterReg platform  (CmmLocal dst)+    (code, lbl) <- op_code dst_r arg amode+    return (addr_code `appOL` arg_code arg `appOL` code, Just lbl)+  where+    -- Code for the operation+    op_code :: Reg       -- Destination reg+            -> Reg       -- Register containing argument+            -> AddrMode  -- Address of location to mutate+            -> NatM (OrdList Instr,BlockId) -- TODO: Return Maybe BlockId+    op_code dst_r arg amode = do+        case amop of+          -- In the common case where dst_r is a virtual register the+          -- final move should go away, because it's the last use of arg+          -- and the first use of dst_r.+          AMO_Add  -> return $ (toOL [ LOCK (XADD format (OpReg arg) (OpAddr amode))+                                     , MOV format (OpReg arg) (OpReg dst_r)+                                     ], bid)+          AMO_Sub  -> return $ (toOL [ NEGI format (OpReg arg)+                                     , LOCK (XADD format (OpReg arg) (OpAddr amode))+                                     , MOV format (OpReg arg) (OpReg dst_r)+                                     ], bid)+          -- In these cases we need a new block id, and have to return it so+          -- that later instruction selection can reference it.+          AMO_And  -> cmpxchg_code (\ src dst -> unitOL $ AND format src dst)+          AMO_Nand -> cmpxchg_code (\ src dst -> toOL [ AND format src dst+                                                      , NOT format dst+                                                      ])+          AMO_Or   -> cmpxchg_code (\ src dst -> unitOL $ OR format src dst)+          AMO_Xor  -> cmpxchg_code (\ src dst -> unitOL $ XOR format src dst)+      where+        -- Simulate operation that lacks a dedicated instruction using+        -- cmpxchg.+        cmpxchg_code :: (Operand -> Operand -> OrdList Instr)+                     -> NatM (OrdList Instr, BlockId)+        cmpxchg_code instrs = do+            lbl1 <- getBlockIdNat+            lbl2 <- getBlockIdNat+            tmp <- getNewRegNat format++            --Record inserted blocks+            --  We turn A -> B into A -> A' -> A'' -> B+            --  with a self loop on A'.+            addImmediateSuccessorNat bid lbl1+            addImmediateSuccessorNat lbl1 lbl2+            updateCfgNat (addWeightEdge lbl1 lbl1 0)++            return $ (toOL+                [ MOV format (OpAddr amode) (OpReg eax)+                , JXX ALWAYS lbl1+                , NEWBLOCK lbl1+                  -- Keep old value so we can return it:+                , MOV format (OpReg eax) (OpReg dst_r)+                , MOV format (OpReg eax) (OpReg tmp)+                ]+                `appOL` instrs (OpReg arg) (OpReg tmp) `appOL` toOL+                [ LOCK (CMPXCHG format (OpReg tmp) (OpAddr amode))+                , JXX NE lbl1+                -- See Note [Introducing cfg edges inside basic blocks]+                -- why this basic block is required.+                , JXX ALWAYS lbl2+                , NEWBLOCK lbl2+                ],+                lbl2)+    format = intFormat width++-- | Count trailing zeroes+genCtz :: BlockId -> Width -> LocalReg -> CmmExpr -> NatM (InstrBlock, Maybe BlockId)+genCtz bid width dst src = do+  is32Bit <- is32BitPlatform+  if is32Bit && width == W64+    then genCtz64_32 bid dst src+    else (,Nothing) <$> genCtzGeneric width dst src++-- | Count trailing zeroes+--+-- 64-bit width on 32-bit architecture+genCtz64_32+  :: BlockId+  -> LocalReg+  -> CmmExpr+  -> NatM (InstrBlock, Maybe BlockId)+genCtz64_32 bid dst src = do+  RegCode64 vcode rhi rlo <- iselExpr64 src+  let dst_r = getLocalRegReg dst+  lbl1 <- getBlockIdNat+  lbl2 <- getBlockIdNat+  tmp_r <- getNewRegNat II64++  -- New CFG Edges:+  --  bid -> lbl2+  --  bid -> lbl1 -> lbl2+  --  We also changes edges originating at bid to start at lbl2 instead.+  weights <- getCfgWeights+  updateCfgNat (addWeightEdge bid lbl1 110 .+                addWeightEdge lbl1 lbl2 110 .+                addImmediateSuccessor weights bid lbl2)++  -- The following instruction sequence corresponds to the pseudo-code+  --+  --  if (src) {+  --    dst = src.lo32 ? BSF(src.lo32) : (BSF(src.hi32) + 32);+  --  } else {+  --    dst = 64;+  --  }+  let instrs = vcode `appOL` toOL+           ([ MOV      II32 (OpReg rhi)         (OpReg tmp_r)+            , OR       II32 (OpReg rlo)         (OpReg tmp_r)+            , MOV      II32 (OpImm (ImmInt 64)) (OpReg dst_r)+            , JXX EQQ    lbl2+            , JXX ALWAYS lbl1++            , NEWBLOCK   lbl1+            , BSF     II32 (OpReg rhi)         dst_r+            , ADD     II32 (OpImm (ImmInt 32)) (OpReg dst_r)+            , BSF     II32 (OpReg rlo)         tmp_r+            , CMOV NE II32 (OpReg tmp_r)       dst_r+            , JXX ALWAYS lbl2++            , NEWBLOCK   lbl2+            ])+  return (instrs, Just lbl2)++-- | Count trailing zeroes+--+-- Generic case (width <= word size)+genCtzGeneric :: Width -> LocalReg -> CmmExpr -> NatM InstrBlock+genCtzGeneric width dst src = do+  code_src <- getAnyReg src+  config <- getConfig+  let bw = widthInBits width+  let dst_r = getLocalRegReg dst+  if ncgBmiVersion config >= Just BMI2+  then do+      src_r <- getNewRegNat (intFormat width)+      let instrs = appOL (code_src src_r) $ case width of+              W8 -> toOL+                  [ OR    II32 (OpImm (ImmInteger 0xFFFFFF00)) (OpReg src_r)+                  , TZCNT II32 (OpReg src_r) dst_r+                  ]+              W16 -> toOL+                  [ TZCNT  II16 (OpReg src_r) dst_r+                  , MOVZxL II16 (OpReg dst_r) (OpReg dst_r)+                  ]+              _ -> unitOL $ TZCNT (intFormat width) (OpReg src_r) dst_r+      return instrs+  else do+      -- The following insn sequence makes sure 'ctz 0' has a defined value.+      -- starting with Haswell, one could use the TZCNT insn instead.+      let format = if width == W8 then II16 else intFormat width+      src_r <- getNewRegNat format+      tmp_r <- getNewRegNat format+      let instrs = code_src src_r `appOL` toOL+               ([ MOVZxL  II8    (OpReg src_r)       (OpReg src_r) | width == W8 ] +++                [ BSF     format (OpReg src_r)       tmp_r+                , MOV     II32   (OpImm (ImmInt bw)) (OpReg dst_r)+                , CMOV NE format (OpReg tmp_r)       dst_r+                ]) -- NB: We don't need to zero-extend the result for the+                   -- W8/W16 cases because the 'MOV' insn already+                   -- took care of implicitly clearing the upper bits+      return instrs++++-- | Copy memory+--+-- Unroll memcpy calls if the number of bytes to copy isn't too large (cf+-- ncgInlineThresholdMemcpy).  Otherwise, call C's memcpy.+genMemCpy+  :: BlockId+  -> Int+  -> CmmExpr+  -> CmmExpr+  -> CmmExpr+  -> NatM InstrBlock+genMemCpy bid align dst src arg_n = do++  let libc_memcpy = genLibCCall bid (fsLit "memcpy") [] [dst,src,arg_n]++  case arg_n of+    CmmLit (CmmInt n _) -> do+      -- try to inline it+      mcode <- genMemCpyInlineMaybe align dst src n+      -- if it didn't inline, call the C function+      case mcode of+        Nothing -> libc_memcpy+        Just c  -> pure c++    -- not a literal size argument: call the C function+    _ -> libc_memcpy++++genMemCpyInlineMaybe+  :: Int+  -> CmmExpr+  -> CmmExpr+  -> Integer+  -> NatM (Maybe InstrBlock)+genMemCpyInlineMaybe align dst src n = do+  config <- getConfig+  let+    platform     = ncgPlatform config+    maxAlignment = wordAlignment platform+                   -- only machine word wide MOVs are supported+    effectiveAlignment = min (alignmentOf align) maxAlignment+    format = intFormat . widthFromBytes $ alignmentBytes effectiveAlignment+++  -- The size of each move, in bytes.+  let sizeBytes :: Integer+      sizeBytes = fromIntegral (formatInBytes format)++  -- The number of instructions we will generate (approx). We need 2+  -- instructions per move.+  let insns = 2 * ((n + sizeBytes - 1) `div` sizeBytes)++      go :: Reg -> Reg -> Reg -> Integer -> OrdList Instr+      go dst src tmp i+          | i >= sizeBytes =+              unitOL (MOV format (OpAddr src_addr) (OpReg tmp)) `appOL`+              unitOL (MOV format (OpReg tmp) (OpAddr dst_addr)) `appOL`+              go dst src tmp (i - sizeBytes)+          -- Deal with remaining bytes.+          | i >= 4 =  -- Will never happen on 32-bit+              unitOL (MOV II32 (OpAddr src_addr) (OpReg tmp)) `appOL`+              unitOL (MOV II32 (OpReg tmp) (OpAddr dst_addr)) `appOL`+              go dst src tmp (i - 4)+          | i >= 2 =+              unitOL (MOVZxL II16 (OpAddr src_addr) (OpReg tmp)) `appOL`+              unitOL (MOV    II16  (OpReg tmp) (OpAddr dst_addr)) `appOL`+              go dst src tmp (i - 2)+          | i >= 1 =+              unitOL (MOVZxL II8 (OpAddr src_addr) (OpReg tmp)) `appOL`+              unitOL (MOV    II8 (OpReg tmp) (OpAddr dst_addr)) `appOL`+              go dst src tmp (i - 1)+          | otherwise = nilOL+        where+          src_addr = AddrBaseIndex (EABaseReg src) EAIndexNone+                       (ImmInteger (n - i))++          dst_addr = AddrBaseIndex (EABaseReg dst) EAIndexNone+                       (ImmInteger (n - i))++  if insns > fromIntegral (ncgInlineThresholdMemcpy config)+    then pure Nothing+    else do+      code_dst <- getAnyReg dst+      dst_r <- getNewRegNat format+      code_src <- getAnyReg src+      src_r <- getNewRegNat format+      tmp_r <- getNewRegNat format+      pure $ Just $ code_dst dst_r `appOL` code_src src_r `appOL`+                      go dst_r src_r tmp_r (fromInteger n)++-- | Set memory to the given byte+--+-- Unroll memset calls if the number of bytes to copy isn't too large (cf+-- ncgInlineThresholdMemset).  Otherwise, call C's memset.+genMemSet+  :: BlockId+  -> Int+  -> CmmExpr+  -> CmmExpr+  -> CmmExpr+  -> NatM InstrBlock+genMemSet bid align dst arg_c arg_n = do++  let libc_memset = genLibCCall bid (fsLit "memset") [] [dst,arg_c,arg_n]++  case (arg_c,arg_n) of+    (CmmLit (CmmInt c _), CmmLit (CmmInt n _)) -> do+      -- try to inline it+      mcode <- genMemSetInlineMaybe align dst c n+      -- if it didn't inline, call the C function+      case mcode of+        Nothing -> libc_memset+        Just c  -> pure c++    -- not literal size arguments: call the C function+    _ -> libc_memset++genMemSetInlineMaybe+  :: Int+  -> CmmExpr+  -> Integer+  -> Integer+  -> NatM (Maybe InstrBlock)+genMemSetInlineMaybe align dst c n = do+  config <- getConfig+  let+    platform = ncgPlatform config+    maxAlignment = wordAlignment platform -- only machine word wide MOVs are supported+    effectiveAlignment = min (alignmentOf align) maxAlignment+    format = intFormat . widthFromBytes $ alignmentBytes effectiveAlignment+    c2 = c `shiftL` 8 .|. c+    c4 = c2 `shiftL` 16 .|. c2+    c8 = c4 `shiftL` 32 .|. c4++    -- The number of instructions we will generate (approx). We need 1+    -- instructions per move.+    insns = (n + sizeBytes - 1) `div` sizeBytes++    -- The size of each move, in bytes.+    sizeBytes :: Integer+    sizeBytes = fromIntegral (formatInBytes format)++    -- Depending on size returns the widest MOV instruction and its+    -- width.+    gen4 :: AddrMode -> Integer -> (InstrBlock, Integer)+    gen4 addr size+        | size >= 4 =+            (unitOL (MOV II32 (OpImm (ImmInteger c4)) (OpAddr addr)), 4)+        | size >= 2 =+            (unitOL (MOV II16 (OpImm (ImmInteger c2)) (OpAddr addr)), 2)+        | size >= 1 =+            (unitOL (MOV II8 (OpImm (ImmInteger c)) (OpAddr addr)), 1)+        | otherwise = (nilOL, 0)++    -- Generates a 64-bit wide MOV instruction from REG to MEM.+    gen8 :: AddrMode -> Reg -> InstrBlock+    gen8 addr reg8byte =+      unitOL (MOV format (OpReg reg8byte) (OpAddr addr))++    -- Unrolls memset when the widest MOV is <= 4 bytes.+    go4 :: Reg -> Integer -> InstrBlock+    go4 dst left =+      if left <= 0 then nilOL+      else curMov `appOL` go4 dst (left - curWidth)+      where+        possibleWidth = min left sizeBytes+        dst_addr = AddrBaseIndex (EABaseReg dst) EAIndexNone (ImmInteger (n - left))+        (curMov, curWidth) = gen4 dst_addr possibleWidth++    -- Unrolls memset when the widest MOV is 8 bytes (thus another Reg+    -- argument). Falls back to go4 when all 8 byte moves are+    -- exhausted.+    go8 :: Reg -> Reg -> Integer -> InstrBlock+    go8 dst reg8byte left =+      if possibleWidth >= 8 then+        let curMov = gen8 dst_addr reg8byte+        in  curMov `appOL` go8 dst reg8byte (left - 8)+      else go4 dst left+      where+        possibleWidth = min left sizeBytes         dst_addr = AddrBaseIndex (EABaseReg dst) EAIndexNone (ImmInteger (n - left))    if fromInteger insns > ncgInlineThresholdMemset config
GHC/CmmToAsm/X86/Instr.hs view
@@ -115,12 +115,9 @@          -- | X86 scalar move instruction.         ---        -- The format is the format the destination is written to. For an XMM-        -- register, using a scalar format means that we don't care about the-        -- upper bits, while using a vector format means that we care about the-        -- upper bits, even though we are only writing to the lower bits.-        ---        -- See also Note [Allocated register formats] in GHC.CmmToAsm.Reg.Linear.+        -- When used at a vector format, only moves the lower 64 bits of data;+        -- the rest of the data in the destination may either be zeroed or+        -- preserved, depending on the specific format and operands.         | MOV Format Operand Operand              -- N.B. Due to AT&T assembler quirks, when used with 'II64'              -- 'Format' immediate source and memory target operand, the source@@ -224,7 +221,7 @@         -- are  Operand Reg.          -- SSE2 floating-point division:-        | FDIV          Format Operand Operand   -- divisor, dividend(dst)+        | FDIV          Format Operand Reg   -- divisor, dividend(dst)          -- use CMP for comparisons.  ucomiss and ucomisd instructions         -- compare single/double prec floating point respectively.@@ -295,8 +292,12 @@         -- NOTE: Instructions follow the AT&T syntax         -- Constructors and deconstructors         | VBROADCAST  Format Operand Reg+        | VPBROADCAST Format Format Operand Reg -- scalar format, vector format, source, destination         | VEXTRACT    Format Imm Reg Operand         | INSERTPS    Format Imm Operand Reg+        | VINSERTPS   Format Imm Operand Reg Reg+        | PINSR       Format Format Imm Operand Reg -- scalar format, vector format, offset, scalar src, vector+        | PEXTR       Format Format Imm Reg Operand -- scalar format, vector format, offset, vector src, scalar dst          -- move operations @@ -312,35 +313,73 @@         | MOVDQU      Format Operand Operand         -- | AVX unaligned move of integer vectors         | VMOVDQU     Format Operand Operand+        -- | Alias for VMOVSS/VMOVSD, used to merge two vectors+        | VMOV_MERGE  Format Reg Reg Reg          -- logic operations         | PXOR        Format Operand Reg         | VPXOR       Format Reg Reg Reg+        | PAND        Format Operand Reg+        | PANDN       Format Operand Reg+        | POR         Format Operand Reg          -- Arithmetic         | VADD       Format Operand Reg Reg         | VSUB       Format Operand Reg Reg         | VMUL       Format Operand Reg Reg         | VDIV       Format Operand Reg Reg+        | PADD       Format Operand Reg+        | PSUB       Format Operand Reg+        | PMULL      Format Operand Reg+        | PMULUDQ    Format Operand Reg +        -- SIMD compare+        | PCMPGT     Format Operand Reg+         -- Shuffle         | SHUF       Format Imm Operand Reg         | VSHUF      Format Imm Operand Reg Reg+        | PSHUFB     Format Operand Reg+        | PSHUFLW    Format Imm Operand Reg+        | PSHUFHW    Format Imm Operand Reg         | PSHUFD     Format Imm Operand Reg         | VPSHUFD    Format Imm Operand Reg+        | BLEND      Format Imm Operand Reg+        | VBLEND     Format Imm Operand Reg Reg+        | PBLENDW    Format Imm Operand Reg          -- | Move two 32-bit floats from the high part of an xmm register         -- to the low part of another xmm register.+        --+        -- If the format is a vector format, the destination register is treated as the second source.+        -- If the format is FF32 or FF64, the destination register is not treated as a source.         | MOVHLPS    Format Reg Reg+        | VMOVHLPS   Format Reg Reg Reg+        | MOVLHPS    Format Reg Reg+        | VMOVLHPS   Format Reg Reg Reg         | UNPCKL     Format Operand Reg+        | VUNPCKL    Format Operand Reg Reg+        | UNPCKH     Format Operand Reg+        | VUNPCKH    Format Operand Reg Reg         | PUNPCKLQDQ Format Operand Reg+        | PUNPCKLDQ  Format Operand Reg+        | PUNPCKLWD  Format Operand Reg+        | PUNPCKLBW  Format Operand Reg+        | PUNPCKHQDQ Format Operand Reg+        | PUNPCKHDQ  Format Operand Reg+        | PUNPCKHWD  Format Operand Reg+        | PUNPCKHBW  Format Operand Reg+        | PACKUSWB   Format Operand Reg          -- Shift-        | PSLLDQ     Format Operand Reg-        | PSRLDQ     Format Operand Reg+        | PSLL       Format Operand Reg+        | PSLLDQ     Format Imm Reg+        | PSRL       Format Operand Reg+        | PSRLDQ     Format Imm Reg+        | PALIGNR    Format Imm Operand Reg          -- min/max-        | MINMAX  MinOrMax MinMaxType Format Operand Operand+        | MINMAX  MinOrMax MinMaxType Format Operand Reg         | VMINMAX MinOrMax MinMaxType Format Operand Reg Reg  data PrefetchVariant = NTA | Lvl0 | Lvl1 | Lvl2@@ -367,27 +406,18 @@ regUsageOfInstr :: Platform -> Instr -> RegUsage regUsageOfInstr platform instr  = case instr of--    -- Recall that MOV is always a scalar move instruction, but when the destination-    -- is an XMM register, we make the distinction between:-    ---    --  - a scalar format, meaning that from now on we no longer care about the top bits-    --    of the register, and-    --  - a vector format, meaning that we still care about what's in the high bits.-    ---    -- See Note [Allocated register formats] in GHC.CmmToAsm.Reg.Linear.-    MOV dst_fmt src dst+    MOV fmt src dst       -- MOVSS/MOVSD preserve the upper half of vector registers,       -- but only for reg-2-reg moves-      | VecFormat _ sFmt <- dst_fmt+      | VecFormat _ sFmt <- fmt       , isFloatScalarFormat sFmt       , OpReg {} <- src       , OpReg {} <- dst-      -> usageRM dst_fmt src dst+      -> usageRM fmt src dst       -- other MOV instructions zero any remaining upper part of the destination       -- (largely to avoid partial register stalls)       | otherwise-      -> usageRW dst_fmt src dst+      -> usageRW fmt src dst     MOVD fmt1 fmt2 src dst    ->       -- NB: MOVD and MOVQ always zero any remaining upper part of destination,       -- so the destination is "written" not "modified".@@ -403,7 +433,7 @@     IMUL   fmt src dst    -> usageRM fmt src dst      -- Result of IMULB will be in just in %ax-    IMUL2  II8 src       -> mkRU (mk II8 eax:use_R II8 src []) [mk II16 eax]+    IMUL2  II8 src       -> mkRU (mk II8 eax:use_R II8 src []) [mk II8 eax]     -- Result of IMUL for wider values, will be split between %dx/%edx/%rdx and     -- %ax/%eax/%rax.     IMUL2  fmt src        -> mkRU (mk fmt eax:use_R fmt src []) [mk fmt eax,mk fmt edx]@@ -460,7 +490,7 @@     CVTTSD2SIQ fmt src dst -> mkRU (use_R FF64 src []) [mk fmt dst]     CVTSI2SS   fmt src dst -> mkRU (use_R fmt src []) [mk FF32 dst]     CVTSI2SD   fmt src dst -> mkRU (use_R fmt src []) [mk FF64 dst]-    FDIV fmt     src dst  -> usageRM fmt src dst+    FDIV fmt     src dst  -> mkRU (use_R fmt src [mk fmt dst]) [mk fmt dst]     SQRT fmt src dst      -> mkRU (use_R fmt src []) [mk fmt dst]      FETCHGOT reg        -> mkRU [] [mk addrFmt reg]@@ -492,6 +522,7 @@      -- vector instructions     VBROADCAST fmt src dst   -> mkRU (use_R fmt src []) [mk fmt dst]+    VPBROADCAST sFmt vFmt src dst -> mkRU (use_R sFmt src []) [mk vFmt dst]     VEXTRACT     fmt _off src dst -> usageRW fmt (OpReg src) dst     INSERTPS     fmt (ImmInt off) src dst       -> mkRU ((use_R fmt src []) ++ [mk fmt dst | not doesNotReadDst]) [mk fmt dst]@@ -504,6 +535,12 @@             where pos = ( off `shiftR` 4 ) .&. 0b11     INSERTPS fmt _off src dst       -> mkRU ((use_R fmt src []) ++ [mk fmt dst]) [mk fmt dst]+    VINSERTPS fmt _imm src2 src1 dst+      -> mkRU (use_R fmt src2 [mk fmt src1]) [mk fmt dst]+    PINSR sFmt vFmt _off src dst+      -> mkRU (use_R sFmt src [mk vFmt dst]) [mk vFmt dst]+    PEXTR sFmt vFmt _off src dst+      -> usageRW' vFmt sFmt (OpReg src) dst      VMOVU        fmt src dst   -> usageRW fmt src dst     MOVU         fmt src dst   -> usageRW fmt src dst@@ -511,6 +548,7 @@     MOVH         fmt src dst   -> usageRM fmt src dst     MOVDQU       fmt src dst   -> usageRW fmt src dst     VMOVDQU      fmt src dst   -> usageRW fmt src dst+    VMOV_MERGE   fmt src2 src1 dst -> mkRU [mk fmt src1, mk fmt src2] [mk fmt dst]      PXOR fmt (OpReg src) dst       | src == dst@@ -524,31 +562,93 @@       | otherwise       -> mkRU [mk fmt s1, mk fmt s2] [mk fmt dst] +    PAND         fmt src dst   -> mkRU (use_R fmt src [mk fmt dst]) [mk fmt dst]+    PANDN        fmt src dst   -> mkRU (use_R fmt src [mk fmt dst]) [mk fmt dst]+    POR          fmt src dst   -> mkRU (use_R fmt src [mk fmt dst]) [mk fmt dst]+     VADD         fmt s1 s2 dst -> mkRU ((use_R fmt s1 []) ++ [mk fmt s2]) [mk fmt dst]     VSUB         fmt s1 s2 dst -> mkRU ((use_R fmt s1 []) ++ [mk fmt s2]) [mk fmt dst]     VMUL         fmt s1 s2 dst -> mkRU ((use_R fmt s1 []) ++ [mk fmt s2]) [mk fmt dst]     VDIV         fmt s1 s2 dst -> mkRU ((use_R fmt s1 []) ++ [mk fmt s2]) [mk fmt dst]+    PADD         fmt src dst   -> mkRU (use_R fmt src [mk fmt dst]) [mk fmt dst]+    PSUB         fmt src dst   -> mkRU (use_R fmt src [mk fmt dst]) [mk fmt dst]+    PMULL        fmt src dst   -> mkRU (use_R fmt src [mk fmt dst]) [mk fmt dst]+    PMULUDQ      fmt src dst   -> mkRU (use_R fmt src [mk fmt dst]) [mk fmt dst] +    PCMPGT       fmt src dst   -> mkRU (use_R fmt src [mk fmt dst]) [mk fmt dst]+     SHUF fmt _mask src dst       -> mkRU (use_R fmt src [mk fmt dst]) [mk fmt dst]     VSHUF fmt _mask src1 src2 dst       -> mkRU (use_R fmt src1 [mk fmt src2]) [mk fmt dst]+    PSHUFB fmt mask dst+      -> mkRU (use_R fmt mask [mk fmt dst]) [mk fmt dst]+    PSHUFLW fmt _mask src dst+      -> mkRU (use_R fmt src []) [mk fmt dst]+    PSHUFHW fmt _mask src dst+      -> mkRU (use_R fmt src []) [mk fmt dst]     PSHUFD fmt _mask src dst       -> mkRU (use_R fmt src []) [mk fmt dst]     VPSHUFD fmt _mask src dst       -> mkRU (use_R fmt src []) [mk fmt dst]+    BLEND fmt _mask src dst+      -> mkRU (use_R fmt src [mk fmt dst]) [mk fmt dst]+    VBLEND fmt _mask src2 src1 dst+      -> mkRU (use_R fmt src2 [mk fmt src1]) [mk fmt dst]+    PBLENDW fmt _mask src dst+      -> mkRU (use_R fmt src [mk fmt dst]) [mk fmt dst] -    PSLLDQ fmt off dst -> mkRU (use_R fmt off []) [mk fmt dst]+    PSLL   fmt off dst -> mkRU (use_R fmt off [mk fmt dst]) [mk fmt dst]+    PSLLDQ fmt _off dst -> mkRU [mk fmt dst] [mk fmt dst]+    PSRL   fmt off dst -> mkRU (use_R fmt off [mk fmt dst]) [mk fmt dst]+    PSRLDQ fmt _off dst -> mkRU [mk fmt dst] [mk fmt dst]+    PALIGNR fmt _off src dst -> mkRU (use_R fmt src [mk fmt dst]) [mk fmt dst]      MOVHLPS    fmt src dst-      -> mkRU [mk fmt src] [mk fmt dst]+      -> case fmt of+           VecFormat {} -> mkRU [mk fmt src, mk fmt dst] [mk fmt dst]+           -- MOVHLPS moves the high 64 bits of src to the low 64 bits of dst,+           -- keeping the high 64 bits of dst intact.+           -- If we only care about the lower 64 bits of the result,+           -- dst is only written to, not read.+           FF64 -> mkRU [mk (VecFormat 2 FmtDouble) src] [mk fmt dst]+           FF32 -> mkRU [mk (VecFormat 4 FmtFloat) src] [mk fmt dst]+           _ -> pprPanic "regUsage: invalid format for MOVHLPS" (ppr fmt)+    VMOVHLPS   fmt src2 src1 dst+      -> mkRU [mk fmt src1, mk fmt src2] [mk fmt dst]+    MOVLHPS    fmt src dst+      -> mkRU [mk fmt src, mk fmt dst] [mk fmt dst]+    VMOVLHPS   fmt src2 src1 dst+      -> mkRU [mk fmt src1, mk fmt src2] [mk fmt dst]     UNPCKL fmt src dst       -> mkRU (use_R fmt src [mk fmt dst]) [mk fmt dst]+    VUNPCKL fmt src2 src1 dst+      -> mkRU (use_R fmt src2 [mk fmt src1]) [mk fmt dst]+    UNPCKH fmt src dst+      -> mkRU (use_R fmt src [mk fmt dst]) [mk fmt dst]+    VUNPCKH fmt src2 src1 dst+      -> mkRU (use_R fmt src2 [mk fmt src1]) [mk fmt dst]     PUNPCKLQDQ fmt src dst       -> mkRU (use_R fmt src [mk fmt dst]) [mk fmt dst]+    PUNPCKLDQ fmt src dst+      -> mkRU (use_R fmt src [mk fmt dst]) [mk fmt dst]+    PUNPCKLWD fmt src dst+      -> mkRU (use_R fmt src [mk fmt dst]) [mk fmt dst]+    PUNPCKLBW fmt src dst+      -> mkRU (use_R fmt src [mk fmt dst]) [mk fmt dst]+    PUNPCKHQDQ fmt src dst+      -> mkRU (use_R fmt src [mk fmt dst]) [mk fmt dst]+    PUNPCKHDQ fmt src dst+      -> mkRU (use_R fmt src [mk fmt dst]) [mk fmt dst]+    PUNPCKHWD fmt src dst+      -> mkRU (use_R fmt src [mk fmt dst]) [mk fmt dst]+    PUNPCKHBW fmt src dst+      -> mkRU (use_R fmt src [mk fmt dst]) [mk fmt dst]+    PACKUSWB fmt src dst+      -> mkRU (use_R fmt src [mk fmt dst]) [mk fmt dst]      MINMAX _ _ fmt src dst-      -> usageRM fmt src dst+      -> mkRU (use_R fmt src [mk fmt dst]) [mk fmt dst]     VMINMAX _ _ fmt src1 src2 dst       -> mkRU (use_R fmt src1 [mk fmt src2]) [mk fmt dst]     _other              -> panic "regUsage: unrecognised instr"@@ -708,7 +808,7 @@     CVTTSD2SIQ fmt src dst -> CVTTSD2SIQ fmt (patchOp src) (env dst)     CVTSI2SS fmt src dst -> CVTSI2SS fmt (patchOp src) (env dst)     CVTSI2SD fmt src dst -> CVTSI2SD fmt (patchOp src) (env dst)-    FDIV fmt src dst     -> FDIV fmt (patchOp src) (patchOp dst)+    FDIV fmt src dst     -> FDIV fmt (patchOp src) (env dst)     SQRT fmt src dst    -> SQRT fmt (patchOp src) (env dst)      CALL (Left _)  _    -> instr@@ -747,10 +847,18 @@      -- vector instructions     VBROADCAST   fmt src dst   -> VBROADCAST fmt (patchOp src) (env dst)+    VPBROADCAST  fmt1 fmt2 src dst+      -> VPBROADCAST fmt1 fmt2 (patchOp src) (env dst)     VEXTRACT     fmt off src dst       -> VEXTRACT fmt off (env src) (patchOp dst)     INSERTPS    fmt off src dst       -> INSERTPS fmt off (patchOp src) (env dst)+    VINSERTPS   fmt off src2 src1 dst+      -> VINSERTPS fmt off (patchOp src2) (env src1) (env dst)+    PINSR       fmt1 fmt2 off src dst+      -> PINSR fmt1 fmt2 off (patchOp src) (env dst)+    PEXTR       fmt1 fmt2 off src dst+      -> PEXTR fmt1 fmt2 off (env src) (patchOp dst)      VMOVU      fmt src dst   -> VMOVU fmt (patchOp src) (patchOp dst)     MOVU       fmt src dst   -> MOVU  fmt (patchOp src) (patchOp dst)@@ -758,38 +866,94 @@     MOVH       fmt src dst   -> MOVH  fmt (patchOp src) (patchOp dst)     MOVDQU     fmt src dst   -> MOVDQU  fmt (patchOp src) (patchOp dst)     VMOVDQU    fmt src dst   -> VMOVDQU fmt (patchOp src) (patchOp dst)+    VMOV_MERGE fmt src2 src1 dst -> VMOV_MERGE fmt (env src2) (env src1) (env dst)      PXOR       fmt src dst   -> PXOR fmt (patchOp src) (env dst)     VPXOR      fmt s1 s2 dst -> VPXOR fmt (env s1) (env s2) (env dst)+    PAND       fmt src dst   -> PAND fmt (patchOp src) (env dst)+    PANDN      fmt src dst   -> PANDN fmt (patchOp src) (env dst)+    POR        fmt src dst   -> POR fmt (patchOp src) (env dst)      VADD       fmt s1 s2 dst -> VADD fmt (patchOp s1) (env s2) (env dst)     VSUB       fmt s1 s2 dst -> VSUB fmt (patchOp s1) (env s2) (env dst)     VMUL       fmt s1 s2 dst -> VMUL fmt (patchOp s1) (env s2) (env dst)     VDIV       fmt s1 s2 dst -> VDIV fmt (patchOp s1) (env s2) (env dst)+    PADD       fmt src dst   -> PADD fmt (patchOp src) (env dst)+    PSUB       fmt src dst   -> PSUB fmt (patchOp src) (env dst)+    PMULL      fmt src dst   -> PMULL fmt (patchOp src) (env dst)+    PMULUDQ    fmt src dst   -> PMULUDQ fmt (patchOp src) (env dst) +    PCMPGT     fmt src dst   -> PCMPGT fmt (patchOp src) (env dst)+     SHUF      fmt off src dst       -> SHUF fmt off (patchOp src) (env dst)     VSHUF      fmt off src1 src2 dst       -> VSHUF fmt off (patchOp src1) (env src2) (env dst)+    PSHUFB       fmt mask dst+      -> PSHUFB fmt (patchOp mask) (env dst)+    PSHUFLW      fmt off src dst+      -> PSHUFLW fmt off (patchOp src) (env dst)+    PSHUFHW      fmt off src dst+      -> PSHUFHW fmt off (patchOp src) (env dst)     PSHUFD       fmt off src dst       -> PSHUFD  fmt off (patchOp src) (env dst)     VPSHUFD      fmt off src dst       -> VPSHUFD fmt off (patchOp src) (env dst)+    BLEND        fmt mask src dst+      -> BLEND   fmt mask (patchOp src) (env dst)+    VBLEND       fmt mask src2 src1 dst+      -> VBLEND  fmt mask (patchOp src2) (env src1) (env dst)+    PBLENDW      fmt mask src dst+      -> PBLENDW fmt mask (patchOp src) (env dst) +    PSLL         fmt off dst+      -> PSLL    fmt (patchOp off) (env dst)     PSLLDQ       fmt off dst-      -> PSLLDQ  fmt (patchOp off) (env dst)+      -> PSLLDQ  fmt off (env dst)+    PSRL         fmt off dst+      -> PSRL    fmt (patchOp off) (env dst)     PSRLDQ       fmt off dst-      -> PSRLDQ  fmt (patchOp off) (env dst)+      -> PSRLDQ  fmt off (env dst)+    PALIGNR      fmt off src dst+      -> PALIGNR fmt off (patchOp src) (env dst)      MOVHLPS    fmt src dst       -> MOVHLPS fmt (env src) (env dst)+    VMOVHLPS   fmt src2 src1 dst+      -> VMOVHLPS fmt (env src2) (env src1) (env dst)+    MOVLHPS    fmt src dst+      -> MOVLHPS fmt (env src) (env dst)+    VMOVLHPS   fmt src2 src1 dst+      -> VMOVLHPS fmt (env src2) (env src1) (env dst)     UNPCKL fmt src dst       -> UNPCKL fmt (patchOp src) (env dst)+    VUNPCKL fmt src2 src1 dst+      -> VUNPCKL fmt (patchOp src2) (env src1) (env dst)+    UNPCKH fmt src dst+      -> UNPCKH fmt (patchOp src) (env dst)+    VUNPCKH fmt src2 src1 dst+      -> VUNPCKH fmt (patchOp src2) (env src1) (env dst)     PUNPCKLQDQ fmt src dst       -> PUNPCKLQDQ fmt (patchOp src) (env dst)+    PUNPCKLDQ fmt src dst+      -> PUNPCKLDQ fmt (patchOp src) (env dst)+    PUNPCKLWD fmt src dst+      -> PUNPCKLWD fmt (patchOp src) (env dst)+    PUNPCKLBW fmt src dst+      -> PUNPCKLBW fmt (patchOp src) (env dst)+    PUNPCKHQDQ fmt src dst+      -> PUNPCKHQDQ fmt (patchOp src) (env dst)+    PUNPCKHDQ fmt src dst+      -> PUNPCKHDQ fmt (patchOp src) (env dst)+    PUNPCKHWD fmt src dst+      -> PUNPCKHWD fmt (patchOp src) (env dst)+    PUNPCKHBW fmt src dst+      -> PUNPCKHBW fmt (patchOp src) (env dst)+    PACKUSWB fmt src dst+      -> PACKUSWB fmt (patchOp src) (env dst)      MINMAX minMax ty fmt src dst-      -> MINMAX minMax ty fmt (patchOp src) (patchOp dst)+      -> MINMAX minMax ty fmt (patchOp src) (env dst)     VMINMAX minMax ty fmt src1 src2 dst       -> VMINMAX minMax ty fmt (patchOp src1) (env src2) (env dst) 
GHC/CmmToAsm/X86/Ppr.hs view
@@ -35,7 +35,6 @@ import GHC.Cmm.Dataflow.Label import GHC.Cmm.BlockId import GHC.Cmm.CLabel-import GHC.Cmm.InitFini import GHC.Cmm.DebugBlock (pprUnwindTable)  import GHC.Types.Basic (Alignment, mkAlignment, alignmentBytes)@@ -200,12 +199,8 @@         labelInd _ = Nothing   , Just ind' <- labelInd ind   , alias `mayRedirectTo` ind'-  -- See Note [Split sections on COFF objects]-  , not $ platformOS platform == OSMinGW32 && ncgSplitSections config   = pprGloblDecl (ncgPlatform config) alias     $$ line (text ".equiv" <+> pprAsmLabel (ncgPlatform config) alias <> comma <> pprAsmLabel (ncgPlatform config) ind')-    where-      platform = ncgPlatform config  pprDatas config (align, (CmmStaticsRaw lbl dats))  = vcat (pprAlign platform align : pprLabel platform lbl : map (pprData config) dats)@@ -466,7 +461,7 @@   -- TODO: this is shady because it only works for certain instructions   VecFormat _ FmtInt8   -> text "b"   VecFormat _ FmtInt16  -> text "w"-  VecFormat _ FmtInt32  -> text "l"+  VecFormat _ FmtInt32  -> text "d"   VecFormat _ FmtInt64  -> text "q"  pprFormat_x87 :: IsLine doc => Format -> doc@@ -537,20 +532,9 @@ pprSectionAlign :: IsDoc doc => NCGConfig -> Section -> doc pprSectionAlign _config (Section (OtherSection _) _) =      panic "X86.Ppr.pprSectionAlign: unknown section"-pprSectionAlign config sec@(Section seg suffix) =+pprSectionAlign config sec@(Section seg _) =     line (pprSectionHeader config sec) $$-    coffSplitSectionComdatKey $$     pprAlignForSection (ncgPlatform config) seg-  where-    platform = ncgPlatform config-    -- See Note [Split sections on COFF objects]-    coffSplitSectionComdatKey-      | OSMinGW32 <- platformOS platform-      , ncgSplitSections config-      , Nothing <- isInitOrFiniSection seg-      = line (pprCOFFComdatKey platform suffix <> colon)-      | otherwise-      = empty  -- | Print appropriate alignment for the given section type. pprAlignForSection :: IsDoc doc => Platform -> SectionType -> doc@@ -931,7 +915,7 @@       -> pprFormatOp (text "mul") format op     FDIV format op1 op2-      -> pprFormatOpOp (text "div") format op1 op2+      -> pprFormatOpReg (text "div") format op1 op2     FMA3 format var perm op1 op2 op3       -> let mnemo = case var of@@ -1006,8 +990,22 @@      -> pprFormatOpRegReg (text "vmul") format s1 s2 dst    VDIV format s1 s2 dst      -> pprFormatOpRegReg (text "vdiv") format s1 s2 dst-   VBROADCAST format from to-     -> pprBroadcast (text "vbroadcast") format from to+   PADD format src dst+     -> pprFormatOpReg (text "padd") format src dst+   PSUB format src dst+     -> pprFormatOpReg (text "psub") format src dst+   PMULL format src dst+     -> pprFormatOpReg (text "pmull") format src dst+   PMULUDQ format src dst+     -> pprOpReg (text "pmuludq") format src dst+   PCMPGT format src dst+     -> pprFormatOpReg (text "pcmpgt") format src dst+   VBROADCAST format@(VecFormat _ sFmt) from to+     -> pprBroadcast (text "vbroadcast") (scalarFormatFormat sFmt) format from to+   VBROADCAST format _ _+     -> pprPanic "VBROADCAST: expected vector format" (ppr format)+   VPBROADCAST scalarFormat format from to+     -> pprBroadcast (text "vpbroadcast") scalarFormat format from to    VMOVU format from to      -> pprFormatOpOp (text "vmovu") format from to    MOVU format from to@@ -1028,39 +1026,103 @@         VecFormat 32 FmtInt16 -> text "vmovdqu32" -- NB: not using vmovdqu16/8, as they         VecFormat 64 FmtInt8  -> text "vmovdqu32" -- require the additional AVX512BW extension         _ -> text "vmovdqu"+   VMOV_MERGE format src2 src1 dst+     -> pprRegRegReg instr format src2 src1 dst+     where instr = case format of+             VecFormat _ FmtFloat -> text "vmovss"+             VecFormat _ FmtDouble -> text "vmovsd"+             _ -> pprPanic "invalid format for VMOV_MERGE" (ppr format)     PXOR format src dst      -> pprPXor (text "pxor") format src dst    VPXOR format s1 s2 dst      -> pprXor (text "vpxor") format s1 s2 dst+   PAND format src dst+     -> pprOpReg (text "pand") format src dst+   PANDN format src dst+     -> pprOpReg (text "pandn") format src dst+   POR format src dst+     -> pprOpReg (text "por") format src dst    VEXTRACT format offset from to      -> pprFormatImmRegOp (text "vextract") format offset from to    INSERTPS format offset addr dst      -> pprInsert (text "insertps") format offset addr dst+   VINSERTPS format offset src2 src1 dst+     -> pprImmOpRegReg (text "vinsertps") format offset src2 src1 dst+   PINSR scalarFormat vectorFormat offset src dst+     -> pprPinsr (text "pinsr") scalarFormat vectorFormat offset src dst+   PEXTR scalarFormat vectorFormat offset src dst+     -> pprPextr (text "pextr") scalarFormat vectorFormat offset src dst     SHUF format offset src dst      -> pprShuf (text "shuf" <> pprFormat format) format offset src dst    VSHUF format offset src1 src2 dst      -> pprVShuf (text "vshuf" <> pprFormat format) format offset src1 src2 dst+   PSHUFB format mask dst+     -> pprOpReg (text "pshufb") format mask dst+   PSHUFLW format offset src dst+     -> pprShuf (text "pshuflw") format offset src dst+   PSHUFHW format offset src dst+     -> pprShuf (text "pshufhw") format offset src dst    PSHUFD format offset src dst      -> pprShuf (text "pshufd") format offset src dst    VPSHUFD format offset src dst      -> pprShuf (text "vpshufd") format offset src dst+   BLEND format mask src dst+     -> pprFormatImmOpReg (text "blend") format mask src dst+   VBLEND format mask src2 src1 dst+     -> pprFormatImmOpRegReg (text "vblend") format mask src2 src1 dst+   PBLENDW format mask src dst+     -> pprShuf (text "pblendw") format mask src dst +   PSLL format offset dst+     -> pprFormatOpReg (text "psll") format offset dst    PSLLDQ format offset dst      -> pprDoubleShift (text "pslldq") format offset dst+   PSRL format offset dst+     -> pprFormatOpReg (text "psrl") format offset dst    PSRLDQ format offset dst      -> pprDoubleShift (text "psrldq") format offset dst+   PALIGNR format offset src dst+     -> pprImmOpReg (text "palignr") format offset src dst     MOVHLPS format from to      -> pprOpReg (text "movhlps") format (OpReg from) to+   VMOVHLPS format src2 src1 dst+     -> pprRegRegReg (text "vmovhlps") format src2 src1 dst+   MOVLHPS format from to+     -> pprOpReg (text "movlhps") format (OpReg from) to+   VMOVLHPS format src2 src1 dst+     -> pprRegRegReg (text "vmovlhps") format src2 src1 dst    UNPCKL format src dst      -> pprFormatOpReg (text "unpckl") format src dst+   VUNPCKL format src2 src1 dst+     -> pprFormatOpRegReg (text "vunpckl") format src2 src1 dst+   UNPCKH format src dst+     -> pprFormatOpReg (text "unpckh") format src dst+   VUNPCKH format src2 src1 dst+     -> pprFormatOpRegReg (text "vunpckh") format src2 src1 dst    PUNPCKLQDQ format from to      -> pprOpReg (text "punpcklqdq") format from to+   PUNPCKLDQ format from to+     -> pprOpReg (text "punpckldq") format from to+   PUNPCKLWD format from to+     -> pprOpReg (text "punpcklwd") format from to+   PUNPCKLBW format from to+     -> pprOpReg (text "punpcklbw") format from to+   PUNPCKHQDQ format from to+     -> pprOpReg (text "punpckhqdq") format from to+   PUNPCKHDQ format from to+     -> pprOpReg (text "punpckhdq") format from to+   PUNPCKHWD format from to+     -> pprOpReg (text "punpckhwd") format from to+   PUNPCKHBW format from to+     -> pprOpReg (text "punpckhbw") format from to+   PACKUSWB format from to+     -> pprOpReg (text "packuswb") format from to     MINMAX minMax ty fmt src dst-     -> pprMinMax False minMax ty fmt [src, dst]+     -> pprMinMax False minMax ty fmt [src, OpReg dst]    VMINMAX minMax ty fmt src1 src2 dst      -> pprMinMax True minMax ty fmt [src1, OpReg src2, OpReg dst] @@ -1217,6 +1279,17 @@            pprReg platform (archWordFormat (target32Bit platform)) reg2        ] +   pprRegRegReg :: Line doc -> Format -> Reg -> Reg -> Reg -> doc+   pprRegRegReg name format reg1 reg2 reg3+     = line $ hcat [+           pprMnemonic_ name,+           pprReg platform format reg1,+           comma,+           pprReg platform format reg2,+           comma,+           pprReg platform format reg3+       ]+    pprOpReg :: Line doc -> Format -> Operand -> Reg -> doc    pprOpReg name format op reg      = line $ hcat [@@ -1315,16 +1388,14 @@    -- Custom pretty printers    -- These instructions currently don't follow a uniform suffix pattern    -- in their names, so we have custom pretty printers for them.-   pprBroadcast :: Line doc -> Format -> Operand -> Reg -> doc-   pprBroadcast name fmt@(VecFormat _ sFmt) op dst+   pprBroadcast :: Line doc -> Format -> Format -> Operand -> Reg -> doc+   pprBroadcast name scalarFormat vectorFormat op dst      = line $ hcat [-           pprBroadcastMnemonic name fmt,-           pprOperand platform (scalarFormatFormat sFmt) op,+           pprBroadcastMnemonic name vectorFormat,+           pprOperand platform scalarFormat op,            comma,-           pprReg platform fmt dst+           pprReg platform vectorFormat dst        ]-   pprBroadcast _ fmt _ _ =-     pprPanic "pprBroadcast: expected vector format" (ppr fmt)     pprXor :: Line doc -> Format -> Reg -> Reg -> Reg -> doc    pprXor name format reg1 reg2 reg3@@ -1376,6 +1447,28 @@            pprReg platform format dst        ] +   pprPinsr :: Line doc -> Format -> Format -> Imm -> Operand -> Reg -> doc+   pprPinsr name scalarFormat vectorFormat imm src dst+     = line $ hcat [+           pprMnemonic name vectorFormat,+           pprDollImm imm,+           comma,+           pprOperand platform scalarFormat src,+           comma,+           pprReg platform vectorFormat dst+       ]++   pprPextr :: Line doc -> Format -> Format -> Imm -> Reg -> Operand -> doc+   pprPextr name scalarFormat vectorFormat imm src dst+     = line $ hcat [+           pprMnemonic name vectorFormat,+           pprDollImm imm,+           comma,+           pprReg platform vectorFormat src,+           comma,+           pprOperand platform scalarFormat dst+       ]+    pprShuf :: Line doc -> Format -> Imm -> Operand -> Reg -> doc    pprShuf name format imm1 op2 reg3      = line $ hcat [@@ -1400,13 +1493,61 @@            pprReg platform format reg4        ] -   pprDoubleShift :: Line doc -> Format -> Operand -> Reg -> doc+   pprDoubleShift :: Line doc -> Format -> Imm -> Reg -> doc    pprDoubleShift name format off reg      = line $ hcat [            pprGenMnemonic name format,-           pprOperand platform format off,+           pprDollImm off,            comma,            pprReg platform format reg+       ]++   pprImmOpReg :: Line doc -> Format -> Imm -> Operand -> Reg -> doc+   pprImmOpReg name format imm1 op2 reg3+     = line $ hcat [+           pprGenMnemonic name format,+           pprDollImm imm1,+           comma,+           pprOperand platform format op2,+           comma,+           pprReg platform format reg3+       ]++   pprFormatImmOpReg :: Line doc -> Format -> Imm -> Operand -> Reg -> doc+   pprFormatImmOpReg name format imm1 op2 reg3+     = line $ hcat [+           pprMnemonic name format,+           pprDollImm imm1,+           comma,+           pprOperand platform format op2,+           comma,+           pprReg platform format reg3+       ]++   pprImmOpRegReg :: Line doc -> Format -> Imm -> Operand -> Reg -> Reg -> doc+   pprImmOpRegReg name format imm1 op2 reg3 reg4+     = line $ hcat [+           pprGenMnemonic name format,+           pprDollImm imm1,+           comma,+           pprOperand platform format op2,+           comma,+           pprReg platform format reg3,+           comma,+           pprReg platform format reg4+       ]++   pprFormatImmOpRegReg :: Line doc -> Format -> Imm -> Operand -> Reg -> Reg -> doc+   pprFormatImmOpRegReg name format imm1 op2 reg3 reg4+     = line $ hcat [+           pprMnemonic name format,+           pprDollImm imm1,+           comma,+           pprOperand platform format op2,+           comma,+           pprReg platform format reg3,+           comma,+           pprReg platform format reg4        ]     pprMinMax :: Bool -> MinOrMax -> MinMaxType -> Format -> [Operand] -> doc
GHC/CmmToAsm/X86/RegInfo.hs view
@@ -68,4 +68,3 @@ --             ,"#afafaf","#b6b6b6","#bdbdbd","#c4c4c4","#cbcbcb" --             ,"#d2d2d2","#d9d9d9","#e0e0e0"] -
GHC/CmmToC.hs view
@@ -124,7 +124,7 @@     pprDataExterns platform lits $$     pprWordArray platform (isSecConstant section) lbl lits   where-    isSecConstant (Section t _) = case sectionProtection t of+    isSecConstant section = case sectionProtection section of       ReadOnlySection -> True       WriteProtectedSection -> True       _ -> False@@ -873,26 +873,10 @@                                 (text "MO_V_Mul")                                 (panic $ "PprC.pprMachOp_for_C: MO_V_Mul"                                       ++ "unsupported by the unregisterised backend")-        MO_VS_Quot {}     -> pprTrace "offending mop:"-                                (text "MO_VS_Quot")-                                (panic $ "PprC.pprMachOp_for_C: MO_VS_Quot"-                                      ++ "unsupported by the unregisterised backend")-        MO_VS_Rem {}      -> pprTrace "offending mop:"-                                (text "MO_VS_Rem")-                                (panic $ "PprC.pprMachOp_for_C: MO_VS_Rem"-                                      ++ "unsupported by the unregisterised backend")         MO_VS_Neg {}      -> pprTrace "offending mop:"                                 (text "MO_VS_Neg")                                 (panic $ "PprC.pprMachOp_for_C: MO_VS_Neg"                                       ++ "unsupported by the unregisterised backend")-        MO_VU_Quot {}     -> pprTrace "offending mop:"-                                (text "MO_VU_Quot")-                                (panic $ "PprC.pprMachOp_for_C: MO_VU_Quot"-                                      ++ "unsupported by the unregisterised backend")-        MO_VU_Rem {}      -> pprTrace "offending mop:"-                                (text "MO_VU_Rem")-                                (panic $ "PprC.pprMachOp_for_C: MO_VU_Rem"-                                      ++ "unsupported by the unregisterised backend")         MO_V_Broadcast {} -> pprTrace "offending mop:"                                  (text "MO_V_Broadcast")                                  (panic $ "PprC.pprMachOp_for_C: MO_V_Broadcast"@@ -1063,6 +1047,14 @@         MO_AddIntC    {} -> unsupported         MO_SubIntC    {} -> unsupported         MO_U_Mul2     {} -> unsupported+        MO_VS_Quot    {} -> unsupported+        MO_VS_Rem     {} -> unsupported+        MO_VU_Quot    {} -> unsupported+        MO_VU_Rem     {} -> unsupported+        MO_I64X2_Min     -> unsupported+        MO_I64X2_Max     -> unsupported+        MO_W64X2_Min     -> unsupported+        MO_W64X2_Max     -> unsupported         MO_Touch         -> unsupported         -- we could support prefetch via "__builtin_prefetch"         -- Not adding it for now
GHC/CmmToLlvm.hs view
@@ -271,23 +271,15 @@   -- used if we didn't provide these hints. This will generate a   -- definition of the form   ---  --   @llvm.compiler.used = appending global [42 x i8*] [i8* bitcast <var> to i8*, ...]+  --   @llvm.used = appending global [42 x i8*] [i8* bitcast <var> to i8*, ...]   --   -- Which is the LLVM way of protecting them against getting removed.-  ---  -- We used to emit @llvm.used, but it's too strong and results in-  -- SHF_GNU_RETAIN section flag in the object, which prevents linker-  -- gc-sections from working properly for LLVM backend (#26770).-  -- @llvm.compiler.used serves a similar purpose that protects the-  -- variable from being dropped by llc/opt, but it allows linker-  -- gc-sections to work. See-  -- https://llvm.org/docs/LangRef.html#the-llvm-compiler-used-global-variable   ivars <- getUsedVars   let cast x = LMBitc (LMStaticPointer (pVarLift x)) i8Ptr       ty     = LMArray (length ivars) i8Ptr       usedArray = LMStaticArray (map cast ivars) ty       sectName  = Just $ fsLit "llvm.metadata"-      lmUsedVar = LMGlobalVar (fsLit "llvm.compiler.used") ty Appending sectName Nothing Constant+      lmUsedVar = LMGlobalVar (fsLit "llvm.used") ty Appending sectName Nothing Constant       lmUsed    = LMGlobal lmUsedVar (Just usedArray)   if null ivars      then return ()
GHC/CmmToLlvm/Base.hs view
@@ -286,7 +286,7 @@   , envUniqMeta  :: UniqFM Unique MetaId   -- ^ Global metadata nodes   , envFunMap    :: LlvmEnvMap       -- ^ Global functions so far, with type   , envAliases   :: UniqSet LMString -- ^ Globals that we had to alias, see [Llvm Forward References]-  , envUsedVars  :: [LlvmVar]        -- ^ Pointers to be added to llvm.compiler.used (see @cmmUsedLlvmGens@)+  , envUsedVars  :: [LlvmVar]        -- ^ Pointers to be added to llvm.used (see @cmmUsedLlvmGens@)      -- the following get cleared for every function (see @withClearVars@)   , envVarMap    :: LlvmEnvMap       -- ^ Local variables so far, with type
GHC/CmmToLlvm/CodeGen.hs view
@@ -1,7 +1,6 @@ {-# LANGUAGE CPP #-} {-# LANGUAGE GADTs, MultiWayIf #-} {-# OPTIONS_GHC -fno-warn-type-defaults #-}-{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-}  -- | Handle conversion of CmmProc to LLVM code. module GHC.CmmToLlvm.CodeGen ( genLlvmProc ) where@@ -27,6 +26,7 @@ import GHC.Cmm.Dataflow.Label  import GHC.Data.FastString+import GHC.Data.Maybe (expectJust) import GHC.Data.OrdList  import GHC.Types.ForeignCall@@ -43,7 +43,10 @@ import Control.Monad  import qualified Data.Semigroup as Semigroup+import Data.Foldable ( toList ) import Data.List ( nub )+import qualified Data.List as List+import Data.List.NonEmpty ( NonEmpty (..), nonEmpty ) import Data.Maybe ( catMaybes )  type Atomic = Maybe MemoryOrdering@@ -55,9 +58,8 @@ -- | Top-level of the LLVM proc Code generator -- genLlvmProc :: RawCmmDecl -> LlvmM [LlvmCmmDecl]-genLlvmProc (CmmProc infos lbl live graph) = do-    let blocks = toBlockListEntryFirstFalseFallthrough graph-+genLlvmProc (CmmProc infos lbl live graph)+  | Just blocks <- nonEmpty $ toBlockListEntryFirstFalseFallthrough graph = do     (lmblocks, lmdata) <- basicBlocksCodeGen live blocks     let info = mapLookup (g_entry graph) infos         proc = CmmProc info lbl live (ListGraph lmblocks)@@ -77,9 +79,8 @@ -- | Generate code for a list of blocks that make up a complete -- procedure. The first block in the list is expected to be the entry -- point.-basicBlocksCodeGen :: LiveGlobalRegUses -> [CmmBlock]+basicBlocksCodeGen :: LiveGlobalRegUses -> NonEmpty CmmBlock                       -> LlvmM ([LlvmBasicBlock], [LlvmCmmDecl])-basicBlocksCodeGen _    []                     = panic "no entry block!" basicBlocksCodeGen live cmmBlocks   = do -- Emit the prologue        -- N.B. this must be its own block to ensure that the entry block of the@@ -97,7 +98,7 @@        let ubblock = BasicBlock ubid' [Unreachable]         -- Generate code-       (blocks, topss) <- fmap unzip $ mapM (basicBlockCodeGen ubid) cmmBlocks+       (blocks, topss) <- fmap unzip $ mapM (basicBlockCodeGen ubid) $ toList cmmBlocks         -- Compose        return (entryBlock : ubblock : blocks, prologueTops ++ concat topss)@@ -239,25 +240,12 @@     genCallSimpleCast w op dst args genCall (PrimTarget op@(MO_BSwap w)) [dst] args =     genCallSimpleCast w op dst args+genCall (PrimTarget op@(MO_Pdep w)) [dst] args =+    genCallSimpleCast w op dst args+genCall (PrimTarget op@(MO_Pext w)) [dst] args =+    genCallSimpleCast w op dst args genCall (PrimTarget op@(MO_PopCnt w)) [dst] args =     genCallSimpleCast w op dst args-{- Note [LLVM PDep/PExt intrinsics]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-Since x86 PDep/PExt instructions only exist for 32/64 bit widths-we use the 32bit variant to compute the 8/16bit primops.-To do so we extend/truncate the argument/result around the-call.--}-genCall (PrimTarget op@(MO_Pdep w)) [dst] args = do-    cfg <- getConfig-    if  llvmCgBmiVersion cfg >= Just BMI2-        then genCallMinimumTruncationCast W32 w op dst args-        else genCallSimpleCast w op dst args-genCall (PrimTarget op@(MO_Pext w)) [dst] args = do-    cfg <- getConfig-    if  llvmCgBmiVersion cfg >= Just BMI2-        then genCallMinimumTruncationCast W32 w op dst args-        else genCallSimpleCast w op dst args  genCall (PrimTarget (MO_AtomicRMW width amop)) [dst] [addr, n] = runStmtsDecls $ do     addrVar <- exprToVarW addr@@ -455,6 +443,34 @@ genCall t@(PrimTarget (MO_SubWordC w)) [dstV, dstO] [lhs, rhs] =     genCallWithOverflow t w [dstV, dstO] [lhs, rhs] +genCall (PrimTarget (MO_VS_Quot l w)) [dst] [lhs, rhs] = runStmtsDecls $ do+    lhsVar <- exprToVarW lhs+    rhsVar <- exprToVarW rhs+    result <- doExprW (LMVector l (widthToLlvmInt w)) (LlvmOp LM_MO_SDiv lhsVar rhsVar)+    (dstReg, _dstTy) <- lift $ getCmmReg (CmmLocal dst)+    statement $ Store result dstReg Nothing []++genCall (PrimTarget (MO_VS_Rem l w)) [dst] [lhs, rhs] = runStmtsDecls $ do+    lhsVar <- exprToVarW lhs+    rhsVar <- exprToVarW rhs+    result <- doExprW (LMVector l (widthToLlvmInt w)) (LlvmOp LM_MO_SRem lhsVar rhsVar)+    (dstReg, _dstTy) <- lift $ getCmmReg (CmmLocal dst)+    statement $ Store result dstReg Nothing []++genCall (PrimTarget (MO_VU_Quot l w)) [dst] [lhs, rhs] = runStmtsDecls $ do+    lhsVar <- exprToVarW lhs+    rhsVar <- exprToVarW rhs+    result <- doExprW (LMVector l (widthToLlvmInt w)) (LlvmOp LM_MO_UDiv lhsVar rhsVar)+    (dstReg, _dstTy) <- lift $ getCmmReg (CmmLocal dst)+    statement $ Store result dstReg Nothing []++genCall (PrimTarget (MO_VU_Rem l w)) [dst] [lhs, rhs] = runStmtsDecls $ do+    lhsVar <- exprToVarW lhs+    rhsVar <- exprToVarW rhs+    result <- doExprW (LMVector l (widthToLlvmInt w)) (LlvmOp LM_MO_URem lhsVar rhsVar)+    (dstReg, _dstTy) <- lift $ getCmmReg (CmmLocal dst)+    statement $ Store result dstReg Nothing []+ -- Handle all other foreign calls and prim ops. genCall target res args = do   platform <- getPlatform@@ -625,15 +641,8 @@ -- from i32 to i8 explicitly as LLVM is strict about types. genCallSimpleCast :: Width -> CallishMachOp -> CmmFormal -> [CmmActual]                   -> LlvmM StmtData-genCallSimpleCast w = genCallMinimumTruncationCast w w---- Given the minimum machine bit-width to use and the logical bit-width of the--- value range, perform a type-cast truncation and extension before and after the--- specified operation, respectively.-genCallMinimumTruncationCast :: Width -> Width -> CallishMachOp -> CmmFormal-                             -> [CmmActual] -> LlvmM StmtData-genCallMinimumTruncationCast minW specW op dst args = do-    let width   = widthToLlvmInt $ max minW specW+genCallSimpleCast specW op dst args = do+    let width   = widthToLlvmInt specW         argsW   = const width <$> args         dstType = cmmToLlvmType $ localRegType dst         signage = cmmPrimOpRetValSignage op@@ -936,10 +945,9 @@       W256 -> fsLit "llvm.cttz.i256"       W512 -> fsLit "llvm.cttz.i512"     MO_Pdep w-      -- See Note [LLVM PDep/PExt intrinsics]       | isBmi2Enabled -> case w of-          W8   -> fsLit "llvm.x86.bmi.pdep.32"-          W16  -> fsLit "llvm.x86.bmi.pdep.32"+          W8   -> fsLit "llvm.x86.bmi.pdep.8"+          W16  -> fsLit "llvm.x86.bmi.pdep.16"           W32  -> fsLit "llvm.x86.bmi.pdep.32"           W64  -> fsLit "llvm.x86.bmi.pdep.64"           W128 -> fsLit "llvm.x86.bmi.pdep.128"@@ -955,9 +963,8 @@           W512 -> fsLit "hs_pdep512"     MO_Pext w       | isBmi2Enabled -> case w of-          -- See Note [LLVM PDep/PExt intrinsics]-          W8   -> fsLit "llvm.x86.bmi.pext.32"-          W16  -> fsLit "llvm.x86.bmi.pext.32"+          W8   -> fsLit "llvm.x86.bmi.pext.8"+          W16  -> fsLit "llvm.x86.bmi.pext.16"           W32  -> fsLit "llvm.x86.bmi.pext.32"           W64  -> fsLit "llvm.x86.bmi.pext.64"           W128 -> fsLit "llvm.x86.bmi.pext.128"@@ -1024,6 +1031,15 @@     -- appropriate case of genCall.     MO_U_Mul2 {}     -> unsupported +    MO_VS_Quot {} -> unsupported+    MO_VS_Rem {}  -> unsupported+    MO_VU_Quot {} -> unsupported+    MO_VU_Rem {}  -> unsupported+    MO_I64X2_Min  -> unsupported+    MO_I64X2_Max  -> unsupported+    MO_W64X2_Min  -> unsupported+    MO_W64X2_Max  -> unsupported+     MO_ReleaseFence  -> unsupported     MO_AcquireFence  -> unsupported     MO_SeqCstFence   -> unsupported@@ -1536,13 +1552,9 @@     MO_V_Sub      _ _ -> panicOp     MO_V_Mul      _ _ -> panicOp -    MO_VS_Quot    _ _ -> panicOp-    MO_VS_Rem     _ _ -> panicOp     MO_VS_Min     _ _ -> panicOp     MO_VS_Max     _ _ -> panicOp -    MO_VU_Quot    _ _ -> panicOp-    MO_VU_Rem     _ _ -> panicOp     MO_VU_Min     _ _ -> panicOp     MO_VU_Max     _ _ -> panicOp @@ -1720,12 +1732,6 @@     MO_V_Sub l w   -> genCastBinMach (LMVector l (widthToLlvmInt w)) LM_MO_Sub     MO_V_Mul l w   -> genCastBinMach (LMVector l (widthToLlvmInt w)) LM_MO_Mul -    MO_VS_Quot l w -> genCastBinMach (LMVector l (widthToLlvmInt w)) LM_MO_SDiv-    MO_VS_Rem  l w -> genCastBinMach (LMVector l (widthToLlvmInt w)) LM_MO_SRem--    MO_VU_Quot l w -> genCastBinMach (LMVector l (widthToLlvmInt w)) LM_MO_UDiv-    MO_VU_Rem  l w -> genCastBinMach (LMVector l (widthToLlvmInt w)) LM_MO_URem-     MO_VF_Add  l w -> genCastBinMach (LMVector l (widthToLlvmFloat w)) LM_MO_FAdd     MO_VF_Sub  l w -> genCastBinMach (LMVector l (widthToLlvmFloat w)) LM_MO_FSub     MO_VF_Mul  l w -> genCastBinMach (LMVector l (widthToLlvmFloat w)) LM_MO_FMul@@ -2139,10 +2145,17 @@         --                 ]     in return (mkIntLit width i, nilOL, []) -genLit _ (CmmFloat r w)-  = return (LMLitVar $ LMFloatLit (fromRational r) (widthToLlvmFloat w),+genLit _ (CmmFloat r W32)+  = return (LMLitVar $ LMFloatLit (widenFp (fromRational r :: Float)) (widthToLlvmFloat W32),               nilOL, []) +genLit _ (CmmFloat r W64)+  = return (LMLitVar $ LMFloatLit (fromRational r :: Double) (widthToLlvmFloat W64),+              nilOL, [])++genLit _ (CmmFloat _r _w)+  = panic "genLit (CmmLit:CmmFloat), unsupported float lit"+ genLit opt (CmmVec ls)   = do llvmLits <- mapM toLlvmLit ls        return (LMLitVar $ LMVectorLit llvmLits, nilOL, [])@@ -2219,7 +2232,7 @@ -- question is never written. Therefore we skip it where we can to -- save a few lines in the output and hopefully speed compilation up a -- bit.-funPrologue :: LiveGlobalRegUses -> [CmmBlock] -> LlvmM StmtData+funPrologue :: LiveGlobalRegUses -> NonEmpty CmmBlock -> LlvmM StmtData funPrologue live cmmBlocks = do   platform <- getPlatform @@ -2265,7 +2278,7 @@    return (concatOL stmtss `snocOL` jumpToEntry, [])   where-    entryBlk : _ = cmmBlocks+    entryBlk :| _ = cmmBlocks     jumpToEntry = Branch $ blockIdToLlvm (entryLabel entryBlk)  -- | Function epilogue. Load STG variables to use as argument for call.@@ -2378,9 +2391,8 @@  -- | Returns TBAA meta data by unique getTBAAMeta :: Unique -> LlvmM [MetaAnnot]-getTBAAMeta u = do-    mi <- getUniqMeta u-    return [MetaAnnot tbaa (MetaNode i) | let Just i = mi]+getTBAAMeta u =+    List.singleton . MetaAnnot tbaa . MetaNode . expectJust <$> getUniqMeta u  -- | Returns TBAA meta data for given register getTBAARegMeta :: GlobalReg -> LlvmM [MetaAnnot]
GHC/CmmToLlvm/Data.hs view
@@ -10,6 +10,7 @@ import GHC.Prelude  import GHC.Llvm+import GHC.Llvm.Types (widenFp) import GHC.CmmToLlvm.Base import GHC.CmmToLlvm.Config @@ -74,7 +75,7 @@                 IsFiniArray -> fsLit "llvm.global_dtors"     in genGlobalLabelArray var clbls -genLlvmData (sec@(Section t _), CmmStaticsRaw lbl xs) = do+genLlvmData (sec, CmmStaticsRaw lbl xs) = do     label <- strCLabel_llvm lbl     static <- mapM genData xs     lmsec <- llvmSection sec@@ -91,7 +92,7 @@                                                     then Just 2 else Just 1                             Section Data _    -> Just $ platformWordSizeInBytes platform                             _                 -> Nothing-        const          = if sectionProtection t == ReadOnlySection+        const          = if sectionProtection sec == ReadOnlySection                             then Constant else Global         varDef         = LMGlobalVar label tyAlias link lmsec align const         globDef        = LMGlobal varDef struct@@ -193,8 +194,14 @@ genStaticLit (CmmInt i w)     = return $ LMStaticLit (LMIntLit i (LMInt $ widthInBits w)) -genStaticLit (CmmFloat r w)-    = return $ LMStaticLit (LMFloatLit (fromRational r) (widthToLlvmFloat w))+genStaticLit (CmmFloat r W32)+    = return $ LMStaticLit (LMFloatLit (widenFp (fromRational r :: Float)) (widthToLlvmFloat W32))++genStaticLit (CmmFloat r W64)+    = return $ LMStaticLit (LMFloatLit (fromRational r :: Double) (widthToLlvmFloat W64))++genStaticLit (CmmFloat _r _w)+    = panic "genStaticLit (CmmLit:CmmFloat), unsupported float lit"  genStaticLit (CmmVec ls)     = do sls <- mapM toLlvmLit ls
GHC/CmmToLlvm/Version/Bounds.hs view
@@ -16,4 +16,4 @@  -- | The (not-inclusive) upper bound  bound on the LLVM Version that is currently supported. supportedLlvmVersionUpperBound :: LlvmVersion-supportedLlvmVersionUpperBound = LlvmVersion (20 NE.:| [])+supportedLlvmVersionUpperBound = LlvmVersion (21 NE.:| [])
GHC/Core.hs view
@@ -14,9 +14,10 @@          -- * In/Out type synonyms         InId, InBind, InExpr, InAlt, InArg, InType, InKind,-               InBndr, InVar, InCoercion, InTyVar, InCoVar,+               InBndr, InVar, InCoercion, InTyVar, InCoVar, InTyCoVar,         OutId, OutBind, OutExpr, OutAlt, OutArg, OutType, OutKind,-               OutBndr, OutVar, OutCoercion, OutTyVar, OutCoVar, MOutCoercion,+               OutBndr, OutVar, OutCoercion, OutTyVar, OutCoVar,+               OutTyCoVar, MOutCoercion,          -- ** 'Expr' construction         mkLet, mkLets, mkLetNonRec, mkLetRec, mkLams,@@ -38,11 +39,11 @@         isId, cmpAltCon, cmpAlt, ltAlt,          -- ** Simple 'Expr' access functions and predicates-        bindersOf, bindersOfBinds, rhssOfBind, rhssOfAlts,+        bindersOf, bindersOfBinds, rhssOfBind, rhssOfBinds, rhssOfAlts,         foldBindersOfBindStrict, foldBindersOfBindsStrict,         collectBinders, collectTyBinders, collectTyAndValBinders,         collectNBinders, collectNValBinders_maybe,-        collectArgs, stripNArgs, collectArgsTicks, flattenBinds,+        collectArgs, collectValArgs, stripNArgs, collectArgsTicks, flattenBinds,         collectFunSimple,          exprToType,@@ -59,7 +60,7 @@         unSaturatedOk, needSaturated, boringCxtOk, boringCxtNotOk,          -- ** Predicates and deconstruction on 'Unfolding'-        unfoldingTemplate, expandUnfolding_maybe,+        expandUnfolding_maybe,         maybeUnfoldingTemplate, otherCons,         isValueUnfolding, isEvaldUnfolding, isCheapUnfolding,         isExpandableUnfolding, isConLikeUnfolding, isCompulsoryUnfolding,@@ -115,8 +116,12 @@  import Data.Data hiding (TyCon) import Data.Int+import Data.List.NonEmpty (nonEmpty)+import qualified Data.List.NonEmpty as NE import Data.Word +import Control.DeepSeq+ infixl 4 `mkApps`, `mkTyApps`, `mkVarApps`, `App`, `mkCoApps` -- Left associative, so that we can say (f `mkTyApps` xs `mkVarApps` ys) @@ -1029,6 +1034,73 @@ operationally, casts are vacuous, so this is a bit unfortunate! See #14610 for ideas how to fix this. +Note [Strict fields in Core]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~+In Core, evaluating a data constructor worker evaluates its strict fields.++In other words, let's say we have the following data type++  data T a b = MkT !a b++Now if `xs` reduces to `error "boom"`, then `MkT xs b` will throw that error.+Consequently, it is sound to seq the field before the call to the constructor,+e.g., with `case xs of xs' { __DEFAULT -> MkT xs' b }`.+Let's call this transformation "field eval insertion".++Note in particular that the data constructor application `MkT xs b` above is+*not* a value, unless `xs` is!++This has pervasive effect on the Core pipeline:++(SFC1) `exprIsHNF`/`exprIsConLike`/`exprOkForSpeculation` need to assert that the+    strict arguments of a DataCon worker are values/ok-for-spec themselves.++(SFC2) `exprIsConApp_maybe` inserts field evals in the `FloatBind`s it returns, so+    that the Simplifier, Constant-folding, the pattern-match checker, etc. all+    see the inserted field evals when they match on strict workers.++    For example,+      exprIsConApp_maybe (MkT e1 e2)+        = Just ([FloatCase e1 x], MkT, [x,e2])+    Meaning that (MkT e1 e2) is indeed a data constructor application, but if+    you want to decompose it (which is the purpose of exprIsConApp_maybe) you+    must evaluate e1 first.+    In case of case-of-known constructor, we get the rewrite+      case MkT e1 e2 of MkT xs' b' -> b'+      ==>+      case e1 of xs' { __DEFAULT -> e2 }+    which crucially retains the eval on e1.++(SFC3) The demand signature of a data constructor is strict in strict field+    position and lazy in non-strict fields. Likewise the demand *transformer*+    of a DataCon worker can stricten up demands on strict field args.+    See Note [Demand transformer for data constructors].++(SFC4) In the absence of `-fpedantic-bottoms`, it is still possible that some seqs+    are ultimately dropped or delayed due to eta-expansion.+    See Note [Dealing with bottom].++Strict field semantics is exploited and lowered in STG during EPT enforcement;+see Note [EPT enforcement lowers strict constructor worker semantics] for the+connection.++It might be tempting to think that strict fields could be implemented in terms+of unlifted fields. However, unlifted fields behave differently when the data+constructor is partially applied; see Note [exprIsHNF for function applications]+for an example.++Historical Note:+The delightfully simple description of strict field semantics is the result of+a long saga (#20749, the bits about strict data constructors in #21497, #22475),+where we tried a more lenient (but actually not) semantics first that would+allow both strict and lazy implementations of DataCon workers. This was favoured+because the "pervasive effect" throughout the compiler was deemed too large+(when it really turned out to be quite modest).+Alas, this semantics would require us to implement `exprIsHNF` in *exactly* the+same way as above, otherwise the analysis would not be conservative wrt. the+lenient semantics (which includes the strict one). It is also much harder to+explain and maintain, as it turned out.+ ************************************************************************ *                                                                      *             In/Out type synonyms@@ -1097,11 +1169,9 @@ -- -- NB: 'minimum' use Ord, and (Ord OccName) works lexicographically ---chooseOrphanAnchor local_names-  | isEmptyNameSet local_names = IsOrphan-  | otherwise                  = NotOrphan (minimum occs)-  where-    occs = map nameOccName $ nonDetEltsUniqSet local_names+chooseOrphanAnchor local_names = case nonEmpty $ nonDetEltsUniqSet local_names of+    Nothing -> IsOrphan+    Just local_names -> NotOrphan (minimum (NE.map nameOccName local_names))     -- It's OK to use nonDetEltsUFM here, see comments above  instance Binary IsOrphan where@@ -1117,6 +1187,10 @@                 n <- get bh                 return $ NotOrphan n +instance NFData IsOrphan where+  rnf IsOrphan = ()+  rnf (NotOrphan n) = rnf n+ {- Note [Orphans] ~~~~~~~~~~~~~~@@ -1267,7 +1341,7 @@  -- | The number of arguments the 'ru_fn' must be applied -- to before the rule can match on it-ruleArity :: CoreRule -> Int+ruleArity :: CoreRule -> FullArgCount ruleArity (BuiltinRule {ru_nargs = n}) = n ruleArity (Rule {ru_args = args})      = length args @@ -1287,7 +1361,8 @@ ruleIdName = ru_fn  isLocalRule :: CoreRule -> Bool-isLocalRule = ru_local+isLocalRule (BuiltinRule {})               = False+isLocalRule (Rule { ru_local = is_local }) = is_local  -- | Set the 'Name' of the 'GHC.Types.Id.Id' at the head of the rule left hand side setRuleIdName :: Name -> CoreRule -> CoreRule@@ -1513,10 +1588,6 @@ mkOtherCon :: [AltCon] -> Unfolding mkOtherCon = OtherCon --- | Retrieves the template of an unfolding: panics if none is known-unfoldingTemplate :: Unfolding -> CoreExpr-unfoldingTemplate = uf_tmpl- -- | Retrieves the template of an unfolding if possible -- maybeUnfoldingTemplate is used mainly when specialising, and we do -- want to specialise DFuns, so it's important to return a template@@ -2083,6 +2154,11 @@ rhssOfBind (NonRec _ rhs) = [rhs] rhssOfBind (Rec pairs)    = [rhs | (_,rhs) <- pairs] +rhssOfBinds :: [Bind b] -> [Expr b]+rhssOfBinds []             = []+rhssOfBinds (NonRec _ rhs : bs) = rhs : rhssOfBinds bs+rhssOfBinds (Rec pairs    : bs) = map snd pairs ++ rhssOfBinds bs+ rhssOfAlts :: [Alt b] -> [Expr b] rhssOfAlts alts = [e | Alt _ _ e <- alts] @@ -2156,6 +2232,17 @@   = go expr []   where     go (App f a) as = go f (a:as)+    go e         as = (e, as)++-- | Takes a nested application expression and returns the function+-- being applied and the arguments to which it is applied+collectValArgs :: Expr b -> (Expr b, [Arg b])+collectValArgs expr+  = go expr []+  where+    go (App f a) as+      | isValArg a  = go f (a:as)+      | otherwise   = go f as     go e         as = (e, as)  -- | Takes a nested application expression and returns the function
GHC/Core/Class.hs view
@@ -18,7 +18,12 @@         classKey, className, classATs, classATItems, classTyCon, classMethods,         classOpItems, classBigSig, classExtraBigSig, classTvsFds, classSCTheta,         classHasSCs, classAllSelIds, classSCSelId, classSCSelIds, classMinimalDef,-        classHasFds, isAbstractClass,+        classHasFds,++        -- Predicates+        -- NB: other isXXlass predicates are defined in GHC.Core.Predicate+        --     to avoid module loops+        isAbstractClass     ) where  import GHC.Prelude@@ -26,6 +31,7 @@ import {-# SOURCE #-} GHC.Core.TyCon    ( TyCon ) import {-# SOURCE #-} GHC.Core.TyCo.Rep ( Type, PredType ) import {-# SOURCE #-} GHC.Core.TyCo.Ppr ( pprType )+import GHC.Hs.Extension (GhcRn) import GHC.Types.Var import GHC.Types.Name import GHC.Types.Basic@@ -35,7 +41,7 @@ import GHC.Types.SrcLoc import GHC.Types.Var.Set import GHC.Utils.Outputable-import GHC.Data.BooleanFormula (BooleanFormula, mkTrue)+import Language.Haskell.Syntax.BooleanFormula ( BooleanFormula, mkTrue )  import qualified Data.Data as Data @@ -131,7 +137,7 @@       -- Note [Type-checking default assoc decls] in GHC.Tc.TyCl.     } -type ClassMinimalDef = BooleanFormula Name -- Required methods+type ClassMinimalDef = BooleanFormula GhcRn -- Required methods  data ClassBody   = AbstractClass
GHC/Core/Coercion.hs view
@@ -41,18 +41,15 @@         mkInstCo, mkAppCo, mkAppCos, mkTyConAppCo,         mkFunCo, mkFunCo2, mkFunCoNoFTF, mkFunResCo,         mkNakedFunCo,-        mkNakedForAllCo, mkForAllCo, mkHomoForAllCos,-        mkPhantomCo,+        mkNakedForAllCo, mkForAllCo, mkForAllVisCos, mkHomoForAllCos,+        mkPhantomCo, mkAxiomCo,         mkHoleCo, mkUnivCo, mkSubCo,         mkProofIrrelCo,-        downgradeRole, mkAxiomCo,+        downgradeRole,         mkGReflRightCo, mkGReflLeftCo, mkCoherenceLeftCo, mkCoherenceRightCo,         mkKindCo,         castCoercionKind, castCoercionKind1, castCoercionKind2, -        mkPrimEqPred, mkReprPrimEqPred, mkPrimEqPredRole,-        mkNomPrimEqPred,-         -- ** Decomposition         instNewTyCon_maybe, @@ -96,9 +93,10 @@         liftCoSubst, liftCoSubstTyVar, liftCoSubstWith, liftCoSubstWithEx,         emptyLiftingContext, extendLiftingContext, extendLiftingContextAndInScope,         liftCoSubstVarBndrUsing, isMappedByLC, extendLiftingContextCvSubst,+        updateLCSubst,          mkSubstLiftingContext, liftingContextSubst, zapLiftingContext,-        substForAllCoBndrUsingLC, lcLookupCoVar, lcInScopeSet,+        lcLookupCoVar, lcInScopeSet,          LiftCoEnv, LiftingContext(..), liftEnvSubstLeft, liftEnvSubstRight,         substRightCo, substLeftCo, swapLiftCoEnv, lcSubstLeft, lcSubstRight,@@ -123,8 +121,7 @@          multToCo, mkRuntimeRepCo, -        hasCoercionHoleTy, hasCoercionHoleCo, hasThisCoercionHoleTy,-+        hasCoercionHole,         setCoHoleType        ) where @@ -140,6 +137,7 @@ import GHC.Core.TyCo.Tidy import GHC.Core.TyCo.Compare import GHC.Core.Type+import GHC.Core.Predicate( mkNomEqPred, mkReprEqPred ) import GHC.Core.TyCon import GHC.Core.TyCon.RecWalk import GHC.Core.Coercion.Axiom@@ -168,6 +166,7 @@ import Data.Function ( on ) import Data.Char( isDigit ) import qualified Data.Monoid as Monoid+import Data.List.NonEmpty ( NonEmpty (..) ) import Control.DeepSeq  {-@@ -250,14 +249,14 @@ ppr_co_ax_branch :: (TidyEnv -> Type -> SDoc)                  -> TyCon -> CoAxBranch -> SDoc ppr_co_ax_branch ppr_rhs fam_tc branch-  = foldr1 (flip hangNotEmpty 2)-    [ pprUserForAll (mkForAllTyBinders Inferred bndrs')+  = foldr1 (flip hangNotEmpty 2) $+    pprUserForAll (mkForAllTyBinders Inferred bndrs') :|          -- See Note [Printing foralls in type family instances] in GHC.Iface.Type-    , pp_lhs <+> ppr_rhs tidy_env ee_rhs-    , vcat [ text "-- Defined" <+> pp_loc+    (pp_lhs <+> ppr_rhs tidy_env ee_rhs) :+    ( vcat [ text "-- Defined" <+> pp_loc            , ppUnless (null incomps) $ whenPprDebug $-             text "-- Incomps:" <+> vcat (map (pprCoAxBranch fam_tc) incomps) ]-    ]+             text "-- Incomps:" <+> vcat (map (pprCoAxBranch fam_tc) incomps) ] ) :+    []   where     incomps = coAxBranchIncomps branch     loc = coAxBranchSpan branch@@ -950,6 +949,15 @@   | otherwise   = mkForAllCo_NoRefl v visL visR kind_co co +-- mkForAllVisCos [tv{vis}] constructs a cast+--   forall tv. res  ~R#   forall tv{vis} res`.+-- See Note [Required foralls in Core] in GHC.Core.TyCo.Rep+mkForAllVisCos :: HasDebugCallStack => [ForAllTyBinder] -> Coercion -> Coercion+mkForAllVisCos bndrs orig_co = foldr go orig_co bndrs+  where+    go (Bndr tv vis)+      = mkForAllCo tv coreTyLamForAllTyFlag vis (mkNomReflCo (varType tv))+ -- | Make a Coercion quantified over a type/coercion variable; -- the variable has the same kind and visibility in both sides of the coercion mkHomoForAllCos :: [ForAllTyBinder] -> Coercion -> Coercion@@ -1742,7 +1750,7 @@   = mkFunCoNoFTF role mult arg_co res_co   where     arg_co = mkReflCo role (varType id)-    mult   = multToCo (varMult id)+    mult   = multToCo (idMult id)  -- mkCoCast (c :: s1 ~?r t1) (g :: (s1 ~?r t1) ~#R (s2 ~?r t2)) :: s2 ~?r t2 -- The first coercion might be lifted or unlifted; thus the ~? above@@ -2015,20 +2023,20 @@      -- Also maps coercion variables to ProofIrrelCos.  -- like liftCoSubstWith, but allows for existentially-bound types as well-liftCoSubstWithEx :: Role          -- desired role for output coercion-                  -> [TyVar]       -- universally quantified tyvars+liftCoSubstWithEx :: [TyVar]       -- universally quantified tyvars                   -> [Coercion]    -- coercions to substitute for those                   -> [TyCoVar]     -- existentially quantified tycovars                   -> [Type]        -- types and coercions to be bound to ex vars-                  -> (Type -> Coercion, [Type]) -- (lifting function, converted ex args)-liftCoSubstWithEx role univs omegas exs rhos-  = let theta = mkLiftingContext (zipEqual "liftCoSubstWithExU" univs omegas)-        psi   = extendLiftingContextEx theta (zipEqual "liftCoSubstWithExX" exs rhos)-    in (ty_co_subst psi role, substTys (lcSubstRight psi) (mkTyCoVarTys exs))+                  -> (Type -> CoercionR, [Type]) -- (lifting function, converted ex args)+                      -- Returned coercion has Representational role+liftCoSubstWithEx univs omegas exs rhos+  = let theta = mkLiftingContext (zipEqual univs omegas)+        psi   = extendLiftingContextEx theta (zipEqual exs rhos)+    in (ty_co_subst psi Representational, substTys (lcSubstRight psi) (mkTyCoVarTys exs))  liftCoSubstWith :: Role -> [TyCoVar] -> [Coercion] -> Type -> Coercion liftCoSubstWith r tvs cos ty-  = liftCoSubst r (mkLiftingContext $ zipEqual "liftCoSubstWith" tvs cos) ty+  = liftCoSubst r (mkLiftingContext $ zipEqual tvs cos) ty  -- | @liftCoSubst role lc ty@ produces a coercion (at role @role@) -- that coerces between @lc_left(ty)@ and @lc_right(ty)@, where@@ -2129,15 +2137,11 @@ zapLiftingContext :: LiftingContext -> LiftingContext zapLiftingContext (LC subst _) = LC (zapSubst subst) emptyVarEnv --- | Like 'substForAllCoBndr', but works on a lifting context-substForAllCoBndrUsingLC :: SwapFlag-                         -> (Coercion -> Coercion)-                         -> LiftingContext -> TyCoVar -> Coercion-                         -> (LiftingContext, TyCoVar, Coercion)-substForAllCoBndrUsingLC sym sco (LC subst lc_env) tv co-  = (LC subst' lc_env, tv', co')+updateLCSubst :: LiftingContext -> (Subst -> (Subst, a)) -> (LiftingContext, a)+-- Lift a Subst-update function over LiftingContext+updateLCSubst (LC subst lc_env) upd = (LC subst' lc_env, res)   where-    (subst', tv', co') = substForAllCoBndrUsing sym sco subst tv co+    (subst', res) = upd subst  -- | The \"lifting\" operation which substitutes coercions for type --   variables in a type to produce a coercion.@@ -2155,7 +2159,7 @@     go r ty                 | Just ty' <- coreView ty                             = go r ty'     go Phantom ty           = lift_phantom ty-    go r (TyVarTy tv)       = expectJust "ty_co_subst bad roles" $+    go r (TyVarTy tv)       = expectJust $                               liftCoSubstTyVar lc r tv     go r (AppTy ty1 ty2)    = mkAppCo (go r ty1) (go Nominal ty2)     go r (TyConApp tc tys)  = mkTyConAppCo r tc (zipWith go (tyConRoleListX r tc) tys)@@ -2285,7 +2289,7 @@     stuff    = fun lc old_kind     eta      = view_co stuff     k1       = coercionLKind eta-    new_var  = uniqAway (getSubstInScope subst) (setVarType old_var k1)+    new_var  = uniqAway (substInScopeSet subst) (setVarType old_var k1)      lifted   = mkGReflRightCo Nominal (TyVarTy new_var) eta                -- :: new_var ~ new_var |> eta@@ -2305,7 +2309,7 @@     stuff    = fun lc old_kind     eta      = view_co stuff     k1       = coercionLKind eta-    new_var  = uniqAway (getSubstInScope subst) (setVarType old_var k1)+    new_var  = uniqAway (substInScopeSet subst) (setVarType old_var k1)      -- old_var :: s1  ~r s2     -- eta     :: (s1' ~r s2') ~N (t1 ~r t2)@@ -2389,7 +2393,7 @@  -- | Get the 'InScopeSet' from a 'LiftingContext' lcInScopeSet :: LiftingContext -> InScopeSet-lcInScopeSet (LC subst _) = getSubstInScope subst+lcInScopeSet (LC subst _) = substInScopeSet subst  {- %************************************************************************@@ -2667,45 +2671,14 @@ -- | Makes a coercion type from two types: the types whose equality -- is proven by the relevant 'Coercion' mkCoercionType :: Role -> Type -> Type -> Type-mkCoercionType Nominal          = mkPrimEqPred-mkCoercionType Representational = mkReprPrimEqPred+mkCoercionType Nominal          = mkNomEqPred+mkCoercionType Representational = mkReprEqPred mkCoercionType Phantom          = \ty1 ty2 ->   let ki1 = typeKind ty1       ki2 = typeKind ty2   in   TyConApp eqPhantPrimTyCon [ki1, ki2, ty1, ty2] --- | Creates a primitive nominal type equality predicate.---      t1 ~# t2--- Invariant: the types are not Coercions-mkPrimEqPred :: Type -> Type -> Type-mkPrimEqPred ty1 ty2-  = mkTyConApp eqPrimTyCon [k1, k2, ty1, ty2]-  where-    k1 = typeKind ty1-    k2 = typeKind ty2---- | Creates a primitive representational type equality predicate.---      t1 ~R# t2--- Invariant: the types are not Coercions-mkReprPrimEqPred :: Type -> Type -> Type-mkReprPrimEqPred ty1  ty2-  = mkTyConApp eqReprPrimTyCon [k1, k2, ty1, ty2]-  where-    k1 = typeKind ty1-    k2 = typeKind ty2---- | Makes a lifted equality predicate at the given role-mkPrimEqPredRole :: Role -> Type -> Type -> PredType-mkPrimEqPredRole Nominal          = mkPrimEqPred-mkPrimEqPredRole Representational = mkReprPrimEqPred-mkPrimEqPredRole Phantom          = panic "mkPrimEqPredRole phantom"---- | Creates a primitive nominal type equality predicate with an explicit---   (but homogeneous) kind: (~#) k k ty1 ty2-mkNomPrimEqPred :: Kind -> Type -> Type -> Type-mkNomPrimEqPred k ty1 ty2 = mkTyConApp eqPrimTyCon [k, k, ty1, ty2]- -- | Assuming that two types are the same, ignoring coercions, find -- a nominal coercion between the types. This is useful when optimizing -- transitivity over coercion applications, where splitting two@@ -2813,39 +2786,22 @@ -}  has_co_hole_ty :: Type -> Monoid.Any-has_co_hole_co :: Coercion -> Monoid.Any-(has_co_hole_ty, _, has_co_hole_co, _)+(has_co_hole_ty, _, _, _)   = foldTyCo folder ()   where     folder = TyCoFolder { tcf_view  = noView                         , tcf_tyvar = const2 (Monoid.Any False)                         , tcf_covar = const2 (Monoid.Any False)-                        , tcf_hole  = \_ hole -> Monoid.Any (isHeteroKindCoHole hole)+                        , tcf_hole  = \_ _ -> Monoid.Any True                         , tcf_tycobinder = const2                         } --- | Is there a hetero-kind coercion hole in this type?---   (That is, a coercion hole with ch_hetero_kind=True.)--- See wrinkle (EIK2) of Note [Equalities with incompatible kinds] in GHC.Tc.Solver.Equality-hasCoercionHoleTy :: Type -> Bool-hasCoercionHoleTy = Monoid.getAny . has_co_hole_ty---- | Is there a hetero-kind coercion hole in this coercion?-hasCoercionHoleCo :: Coercion -> Bool-hasCoercionHoleCo = Monoid.getAny . has_co_hole_co--hasThisCoercionHoleTy :: Type -> CoercionHole -> Bool-hasThisCoercionHoleTy ty hole = Monoid.getAny (f ty)-  where-    (f, _, _, _) = foldTyCo folder ()--    folder = TyCoFolder { tcf_view  = noView-                        , tcf_tyvar = const2 (Monoid.Any False)-                        , tcf_covar = const2 (Monoid.Any False)-                        , tcf_hole  = \ _ h -> Monoid.Any (getUnique h == getUnique hole)-                        , tcf_tycobinder = const2-                        }+-- | Is there a coercion hole in this type?+-- See wrinkle (DE6) of Note [Defaulting equalities] in GHC.Tc.Solver.Default+hasCoercionHole :: Type -> Bool+hasCoercionHole = Monoid.getAny . has_co_hole_ty  -- | Set the type of a 'CoercionHole' setCoHoleType :: CoercionHole -> Type -> CoercionHole setCoHoleType h t = setCoHoleCoVar h (setVarType (coHoleCoVar h) t)+
GHC/Core/Coercion/Axiom.hs view
@@ -58,6 +58,7 @@ import qualified Data.Data as Data import Data.Array import Data.List ( mapAccumL )+import Control.DeepSeq  {- Note [Coercion axiom branches]@@ -558,6 +559,11 @@                           2 -> return Representational                           3 -> return Phantom                           _ -> panic ("get Role " ++ show tag)++instance NFData Role where+  rnf Nominal = ()+  rnf Representational = ()+  rnf Phantom = ()  {- ************************************************************************
GHC/Core/Coercion/Opt.hs view
@@ -208,10 +208,12 @@     in     warnPprTrace (not (isReflCo out_co) && isReflexiveCo out_co)                  "optCoercion: reflexive but not refl" details $---    assertPpr (substTyUnchecked env in_ty1 `eqType` out_ty1 &&---               substTyUnchecked env in_ty2 `eqType` out_ty2 &&---               in_role == out_role)---              (hang (text "optCoercion changed types!") 2 details) $+    -- The coercion optimiser should usually optimise+    --     co:ty~ty   -->  Refl ty+    -- But given a silly `newtype N = MkN N`, the axiom has type (N ~ N),+    -- and so that can trigger this warning (e.g. test str002).+    -- Maybe we should optimise that coercion to (Refl N), but it+    -- just doesn't seem worth the bother     out_co    | otherwise@@ -356,12 +358,12 @@             (opt_co4 env sym False Nominal co2)  opt_co4' env sym rep r (ForAllCo { fco_tcv = tv, fco_visL = visL, fco_visR = visR-                                , fco_kind = k_co, fco_body = co })-  = case optForAllCoBndr env sym tv k_co of-      (env', tv', k_co') -> mkForAllCo tv' visL' visR' k_co' $-                            opt_co4 env' sym rep r co+                                 , fco_kind = k_co, fco_body = co })+  = mkForAllCo tv' visL' visR' k_co' $+    opt_co4 env' sym rep r co      -- Use the "mk" functions to check for nested Refls   where+    !(env', tv', k_co') = optForAllCoBndr env sym tv k_co     !(visL', visR') = swapSym sym (visL, visR)  opt_co4' env sym rep r (FunCo _r afl afr cow co1 co2)@@ -687,7 +689,7 @@  ------------- opt_transList :: HasDebugCallStack => InScopeSet -> [NormalCo] -> [NormalCo] -> [NormalCo]-opt_transList is = zipWithEqual "opt_transList" (opt_trans is)+opt_transList is = zipWithEqual (opt_trans is)   -- The input lists must have identical length.  opt_trans :: HasDebugCallStack => InScopeSet -> NormalCo -> NormalCo -> NormalCo@@ -1113,7 +1115,7 @@   :: Equal (Id Int) (Id Bool) ~ False  which is bogus! This is because the type system isn't smart enough to know-that (Id Int) and (Id Bool) are Surely Apart, as they're headed by type+that (Id Int) and (Id Bool) are SurelyApart, as they're headed by type families. At the time of writing, I (Richard Eisenberg) couldn't think of a way of detecting this any more efficient than just building the optimised coercion and checking.@@ -1399,10 +1401,68 @@  -} +{- Note [Optimising ForAllCo]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+If sym=NotSwapped, optimising ForAllCo is relatively easy:+   opt env (ForAllCo tcv kco bodyco)+     = ForAllCo tcv' (opt env kco) (opt env' bodyco)+     where+       (env', tcv') = substBndr env tcv++Just apply the substitution to the kind of the binder, deal with+shadowing etc, and recurse.  Remember in (ForAllCo tcv kco bodyco)+    varKind tcv = coercionLKind kco++But if sym=Swapped, things are trickier.  Here is an identity that helps:+   Sym (ForAllCo (tv:k1) (kco:k1~k2) bodyco)+   = ForAllCo (tv:k2) (Sym kco : k2~k1)+              (Sym (bodyco[tv:->tv:k2 |> Sym kco]))++* We re-type tv:k1 to become tv:k2.+* We push Sym into kco+* We push Sym into bodyco+* BUT we must /also/ remember to replace all occurrences of+      of tv:k1 in bodyco by (tv:k2 |> Sym kco)+  This mirrors what happens in the typing rule for ForAllCo+  See Note [ForAllCo] in GHC.Core.TyCo.Rep++-} optForAllCoBndr :: LiftingContext -> SwapFlag-                -> TyCoVar -> Coercion -> (LiftingContext, TyCoVar, Coercion)-optForAllCoBndr env sym-  = substForAllCoBndrUsingLC sym (opt_co4 env sym False Nominal) env+                -> TyCoVar -> Coercion+                -> (LiftingContext, TyCoVar, Coercion)+-- See Note [Optimising ForAllCo]+optForAllCoBndr env sym tcv kco+  = (env', tcv', kco')+  where+    kco' = opt_co4 env sym False Nominal kco  -- Push sym into kco+    (env', tcv') = updateLCSubst env upd_subst++    upd_subst :: Subst -> (Subst, TyCoVar)+    upd_subst subst+      | isTyVar tcv = upd_subst_tv subst+      | otherwise   = upd_subst_cv subst++    upd_subst_tv subst+      | notSwapped sym || isReflCo kco' = (subst1, tv1)+      | otherwise                       = (subst2, tv2)+      where+        -- subst1,tv1: apply the substitution to the binder and its kind+        -- NB: varKind tv = coercionLKind kco+        (subst1, tv1) = substTyVarBndr subst tcv+        -- In the Swapped case, we re-kind the type variable, AND+        -- override the substitution for the original variable to the+        -- re-kinded one, suitably casted+        tv2    = tv1 `setTyVarKind` coercionLKind kco'+        subst2 = (extendTvSubst subst1 tcv (mkTyVarTy tv2 `CastTy` kco'))+                 `extendSubstInScope` tv2++    upd_subst_cv subst   -- ToDo: probably not right yet+      | notSwapped sym || isReflCo kco' = (subst1, cv1)+      | otherwise                       = (subst2, cv2)+      where+        (subst1, cv1) = substCoVarBndr subst tcv+        cv2    = cv1 `setTyVarKind` coercionLKind kco'+        subst2 = subst1 `extendSubstInScope` cv2   {- **********************************************************************
GHC/Core/ConLike.hs view
@@ -12,6 +12,7 @@         , conLikeConLikeName         , isVanillaConLike         , conLikeArity+        , conLikeVisArity         , conLikeFieldLabels         , conLikeConInfo         , conLikeInstOrigArgTys@@ -23,7 +24,6 @@         , conLikeFullSig         , conLikeResTy         , conLikeFieldType-        , conLikesWithFields         , conLikeIsInfix         , conLikeHasBuilder     ) where@@ -48,7 +48,6 @@  import Data.Maybe( isJust ) import qualified Data.Data as Data-import qualified Data.List as List  {- ************************************************************************@@ -114,11 +113,16 @@     gunfold _ _  = error "gunfold"     dataTypeOf _ = mkNoRepType "ConLike" --- | Number of arguments+-- | Number of value arguments conLikeArity :: ConLike -> Arity conLikeArity (RealDataCon data_con) = dataConSourceArity data_con conLikeArity (PatSynCon pat_syn)    = patSynArity pat_syn +-- | Number of visible arguments+conLikeVisArity :: ConLike -> VisArity+conLikeVisArity (RealDataCon data_con) = dataConVisArity data_con+conLikeVisArity (PatSynCon pat_syn)    = patSynVisArity pat_syn+ -- | Names of fields used for selectors conLikeFieldLabels :: ConLike -> [FieldLabel] conLikeFieldLabels (RealDataCon data_con) = dataConFieldLabels data_con@@ -149,10 +153,11 @@ -- followed by the existentially quantified type variables. For data -- constructors, the situation is slightly more complicated—see -- @Note [DataCon user type variable binders]@ in "GHC.Core.DataCon".-conLikeUserTyVarBinders :: ConLike -> [InvisTVBinder]+conLikeUserTyVarBinders :: ConLike -> [TyVarBinder] conLikeUserTyVarBinders (RealDataCon data_con) =     dataConUserTyVarBinders data_con conLikeUserTyVarBinders (PatSynCon pat_syn) =+    tyVarSpecToBinders $     patSynUnivTyVarBinders pat_syn ++ patSynExTyVarBinders pat_syn     -- The order here is because of the order in `GHC.Tc.TyCl.PatSyn`. @@ -230,15 +235,6 @@ conLikeFieldType :: ConLike -> FieldLabelString -> Type conLikeFieldType (PatSynCon ps) label = patSynFieldType ps label conLikeFieldType (RealDataCon dc) label = dataConFieldType dc label----- | The ConLikes that have *all* the given fields-conLikesWithFields :: [ConLike] -> [FieldLabelString]-                   -> ( [ConLike]   -- ConLikes containing the fields-                      , [ConLike] ) -- ConLikes not containing the fields-conLikesWithFields con_likes lbls = List.partition has_flds con_likes-  where has_flds dc = all (has_fld dc) lbls-        has_fld dc lbl = any (\ fl -> flLabel fl == lbl) (conLikeFieldLabels dc)  conLikeIsInfix :: ConLike -> Bool conLikeIsInfix (RealDataCon dc) = dataConIsInfix dc
GHC/Core/DataCon.hs view
@@ -12,7 +12,7 @@         -- * Main data types         DataCon, DataConRep(..),         SrcStrictness(..), SrcUnpackedness(..),-        HsSrcBang(..), HsBang(..), HsImplBang(..),+        HsSrcBang(..), HsImplBang(..),         StrictnessMark(..),         ConTag,         DataConEnv,@@ -25,7 +25,7 @@         FieldLabel(..), flLabel, FieldLabelString,          -- ** Type construction-        mkHsSrcBang, mkDataCon, fIRST_TAG,+        mkDataCon, fIRST_TAG,          -- ** Type deconstruction         dataConRepType, dataConInstSig, dataConFullSig,@@ -45,22 +45,24 @@         dataConInstUnivs,         dataConFieldLabels, dataConFieldType, dataConFieldType_maybe,         dataConSrcBangs,-        dataConSourceArity, dataConRepArity,+        dataConSourceArity, dataConVisArity, dataConRepArity,         dataConIsInfix,         dataConWorkId, dataConWrapId, dataConWrapId_maybe,         dataConImplicitTyThings,-        dataConRepStrictness, dataConImplBangs, dataConBoxer,+        dataConRepStrictness,+        dataConImplBangs, dataConBoxer,          splitDataProductType_maybe,          -- ** Predicates on DataCons         isNullarySrcDataCon, isNullaryRepDataCon,+        isLazyDataConRep,         isTupleDataCon, isBoxedTupleDataCon, isUnboxedTupleDataCon,-        isUnboxedSumDataCon, isCovertGadtDataCon,+        isUnboxedSumDataCon, isCovertGadtDataCon, isUnaryClassDataCon,         isVanillaDataCon, isNewDataCon, isTypeDataCon,         classDataCon, dataConCannotMatch,-        dataConUserTyVarsNeedWrapper, checkDataConTyVars,-        isBanged, isMarkedStrict, cbvFromStrictMark, eqHsBang, isSrcStrict, isSrcUnpacked,+        dataConUserTyVarBindersNeedWrapper, checkDataConTyVars,+        isBanged, isUnpacked, isMarkedStrict, cbvFromStrictMark, eqHsBang, isSrcStrict, isSrcUnpacked,         specialPromotedDc,          -- ** Promotion related functions@@ -78,7 +80,7 @@ import GHC.Core.Unify import GHC.Core.TyCon import GHC.Core.TyCo.Subst-import GHC.Core.TyCo.Compare( eqType )+import GHC.Core.TyCo.Compare( eqType, eqForAllVis ) import GHC.Core.Multiplicity import {-# SOURCE #-} GHC.Types.TyThing import GHC.Types.FieldLabel@@ -110,6 +112,7 @@ import qualified Data.Data as Data import Data.Char import Data.List( find )+import Control.DeepSeq  {- Note [Data constructor representation]@@ -460,7 +463,7 @@         --    with the set of dcUnivTyVars whose tyvars do not appear in dcEqSpec         -- So dcUserTyVarBinders is a subset of (dcUnivTyVars ++ dcExTyCoVars)         -- See Note [DataCon user type variable binders]-        dcUserTyVarBinders :: [InvisTVBinder],+        dcUserTyVarBinders :: [TyVarBinder],          dcEqSpec :: [EqSpec],   -- Equalities derived from the result type,                                 -- _as written by the programmer_.@@ -519,6 +522,18 @@                 -- Matches 1-1 with dcOrigArgTys                 -- Hence length = dataConSourceArity dataCon +        dcImplBangs :: [HsImplBang],+                -- The actual decisions made (including failures)+                -- about the original arguments; 1-1 with orig_arg_tys+                -- See Note [Bangs on data constructor arguments]++        dcStricts :: [StrictnessMark],+                -- One mark for every field of the DataCon worker;+                -- if it's empty, then all fields are lazy,+                -- otherwise 1-1 with dataConRepArgTys.+                -- See also Note [Strict fields in Core] in GHC.Core+                -- for the effect on the strictness signature+         dcFields  :: [FieldLabel],                 -- Field labels for this constructor, in the                 -- same order as the dcOrigArgTys;@@ -565,22 +580,8 @@   }  -{- Note [TyVarBinders in DataCons]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-For the TyVarBinders in a DataCon and PatSyn,-each argument flag is either Inferred or Specified, never Required.-Lifting this restriction is tracked at #18389 (DataCon) and #23704 (PatSyn).--Why do we need the TyVarBinders, rather than just the TyVars?  So that-we can construct the right type for the DataCon with its foralls-attributed the correct visibility.  That in turn governs whether you-can use visible type application at a call of the data constructor.--See also [DataCon user type variable binders] for an extended discussion on the-order in which TyVarBinders appear in a DataCon.--Note [Existential coercion variables]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+{- Note [Existential coercion variables]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ For now (Aug 2018) we can't write coercion quantifications in source Haskell, but we can in Core. Consider having: @@ -641,25 +642,42 @@ A DataCon has two different sets of type variables:  * dcUserTyVarBinders, for the type variables binders in the order in which they-  originally arose in the user-written type signature.+  originally arose in the user-written type signature, and with user-specified+  visibilities.    - They are the forall'd binders of the data con /wrapper/, which the user calls. -  - Their order *does* matter for TypeApplications, so they are full TyVarBinders,-    complete with visibilities.+  - With RequiredTypeArguments, some of the foralls may be visible, e.g.+      MkT :: forall a b. forall c -> (a, b, c) -> T a b c+    so the binders are full TyVarBinders, complete with visibilities. +  - Even if we only consider invisible foralls, the order and specificity of+    binders matter for TypeApplications.+ * dcUnivTyVars and dcExTyCoVars, for the "true underlying" (i.e. of the data   con worker) universal type variable and existential type/coercion variables,   respectively.    - They (i.e. univ ++ ex) are the forall'd variables of the data con /worker/ -  - Their order is irrelevant for the purposes of TypeApplications,-    and as a consequence, they do not come equipped with visibilities-    (that is, they are TyVars/TyCoVars instead of ForAllTyBinders).+  - They do not come equipped with visibilities:+        dcUnivTyVars :: [TyVar]     -- not [TyVarBinder]+        dcExTyCoVars :: [TyCoVar]   -- not [ForAllTyBinder]+    Instead, we treat them as having the Specified (coreTyLamForAllTyFlag)+    visibility. For example:+        wrapper type: forall {a} b. forall c -> ...+        worker type:  forall a b c. ...+    This is a design choice. Reasons:+      * Workers are never called by the user. They are part of the Core+        language where visibilities don't matter as much.+      * Consistency with type lambdas in Core. As Note [Required foralls in Core]+        in GHC.Core.TyCo.Rep explains, (/\a. e) :: (forall a. e_ty), and we need+        a coercion to cast it to (forall a -> e_ty).+    As a consequence, we may need to adjust visibilities with a cast in the+    wrapper. See Note [Flag cast in data con wrappers]. -Often (dcUnivTyVars ++ dcExTyCoVars) = dcUserTyVarBinders; but they may differ-for two reasons, coming next:+Often (dcUnivTyVars ++ dcExTyCoVars) = binderVars dcUserTyVarBinders; but they+may differ for two reasons, coming next:  --- Reason (R1): Order of quantification in GADT syntax --- @@ -821,13 +839,6 @@                                           -- after unboxing and flattening,                                           -- and *including* all evidence args -        , dcr_stricts :: [StrictnessMark]  -- 1-1 with dcr_arg_tys-                -- See also Note [Data-con worker strictness]--        , dcr_bangs :: [HsImplBang]  -- The actual decisions made (including failures)-                                     -- about the original arguments; 1-1 with orig_arg_tys-                                     -- See Note [Bangs on data constructor arguments]-     }  type DataConEnv a = UniqFM DataCon a     -- Keyed by DataCon@@ -839,14 +850,16 @@ -- Bangs on data constructor arguments as written by the user, including the -- source code for exact-printing. ----- In the AST, the SourceText is deconstructed and hidden inside--- 'Language.Haskell.Syntax.Extension.XBangTy' extension point.+-- @(HsSrcBang _ SrcUnpack SrcLazy)@ and+-- @(HsSrcBang _ SrcUnpack NoSrcStrict)@ (without StrictData) makes no sense, we+-- emit a warning (in checkValidDataCon) and treat it like+-- @(HsSrcBang _ NoSrcUnpack SrcLazy)@+--+-- In the AST, the @SourceText@ is hidden inside the extension point+-- 'Language.Haskell.Syntax.Extension.XConDeclField'. data HsSrcBang-  = HsSrcBang SourceText HsBang -- See Note [Pragma source text] in "GHC.Types.SourceText"---- | Make a 'HsSrcBang' from all parts-mkHsSrcBang :: SourceText -> SrcUnpackedness -> SrcStrictness -> HsSrcBang-mkHsSrcBang stext u s = HsSrcBang stext (HsBang u s)+  = HsSrcBang SourceText SrcUnpackedness SrcStrictness -- See Note [Pragma source text] in "GHC.Types.SourceText"+  deriving Data.Data  -- | Haskell Implementation Bang --@@ -889,49 +902,14 @@ eqSpecPair (EqSpec tv ty) = (tv, ty)  eqSpecPreds :: [EqSpec] -> ThetaType-eqSpecPreds spec = [ mkPrimEqPred (mkTyVarTy tv) ty+eqSpecPreds spec = [ mkNomEqPred (mkTyVarTy tv) ty                    | EqSpec tv ty <- spec ]  instance Outputable EqSpec where   ppr (EqSpec tv ty) = ppr (tv, ty) -{- Note [Data-con worker strictness]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-Notice that we do *not* say the worker Id is strict even if the data-constructor is declared strict-     e.g.    data T = MkT ![Int] Bool-Even though most often the evals are done by the *wrapper* $WMkT, there are-situations in which tag inference will re-insert evals around the worker.-So for all intents and purposes the *worker* MkT is strict, too!--Unfortunately, if we exposed accurate strictness of DataCon workers, we'd-see the following transformation:--  f xs = case xs of xs' { __DEFAULT -> ... case MkT xs b of x { __DEFAULT -> [x] } } -- DmdAnal: Strict in xs-  ==> { drop-seq, binder swap on xs' }-  f xs = case MkT xs b of x { __DEFAULT -> [x] } -- DmdAnal: Still strict in xs-  ==> { case-to-let }-  f xs = let x = MkT xs' b in [x] -- DmdAnal: No longer strict in xs!--I.e., we are ironically losing strictness in `xs` by dropping the eval on `xs`-and then doing case-to-let. The issue is that `exprIsHNF` currently says that-every DataCon worker app is a value. The implicit assumption is that surrounding-evals will have evaluated strict fields like `xs` before! But now that we had-just dropped the eval on `xs`, that assumption is no longer valid.--Long story short: By keeping the demand signature lazy, the Simplifier will not-drop the eval on `xs` and using `exprIsHNF` to decide case-to-let and others-remains sound.--Similarly, during demand analysis in dmdTransformDataConSig, we bump up the-field demand with `C_01`, *not* `C_11`, because the latter exposes too much-strictness that will drop the eval on `xs` above.--This issue is discussed at length in-"Failed idea: no wrappers for strict data constructors" in #21497 and #22475.--Note [Bangs on data constructor arguments]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+{- Note [Bangs on data constructor arguments]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Consider   data T = MkT !Int {-# UNPACK #-} !Int Bool @@ -957,8 +935,8 @@   the flag settings in the importing module.   Also see Note [Bangs on imported data constructors] in GHC.Types.Id.Make -* The dcr_bangs field of the dcRep field records the [HsImplBang]-  If T was defined in this module, Without -O the dcr_bangs might be+* The dcImplBangs field records the [HsImplBang]+  If T was defined in this module, Without -O the dcImplBangs might be     [HsStrict _, HsStrict _, HsLazy]   With -O it might be     [HsStrict _, HsUnpack _, HsLazy]@@ -967,6 +945,20 @@   With -XStrictData it might be     [HsStrict _, HsUnpack _, HsStrict _] +* Core passes will often need to know whether the DataCon worker or wrapper in+  an application is strict in some (lifted) field or not. This is tracked in the+  demand signature attached to a DataCon's worker resp. wrapper Id.++  So if you've got a DataCon dc, you can get the demand signature by+  `idDmdSig (dataConWorkId dc)` and make out strict args by testing with+  `isStrictDmd`. Similarly, `idDmdSig <$> dataConWrapId_maybe dc` gives+  you the demand signature of the wrapper, if it exists.++  These demand signatures are set in GHC.Types.Id.Make.mkDataConWorkId,+  computed from the single source of truth `dataConRepStrictness`, which is+  generated from `dcStricts`.+  Note that `dataConRepStrictness` lines up 1-1 with `idDmdSig (dataConWorkId dc)`.+ Note [Detecting useless UNPACK pragmas] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ We want to issue a warning when there's an UNPACK pragma in the source code,@@ -1002,7 +994,6 @@ The boolean flag is used only for this warning. See #11270 for motivation. - ************************************************************************ *                                                                      * \subsection{Instances}@@ -1034,10 +1025,7 @@     dataTypeOf _ = mkNoRepType "DataCon"  instance Outputable HsSrcBang where-    ppr (HsSrcBang _source_text bang) = ppr bang--instance Outputable HsBang where-    ppr (HsBang prag mark) = ppr prag <+> ppr mark+    ppr (HsSrcBang _ prag mark) = ppr prag <+> ppr mark  instance Outputable HsImplBang where     ppr HsLazy                  = text "Lazy"@@ -1093,6 +1081,16 @@            1 -> return SrcUnpack            _ -> return NoSrcUnpack +instance NFData SrcStrictness where+  rnf SrcLazy = ()+  rnf SrcStrict = ()+  rnf NoSrcStrict = ()++instance NFData SrcUnpackedness where+  rnf SrcNoUnpack = ()+  rnf SrcUnpack = ()+  rnf NoSrcUnpack = ()+ -- | Compare strictness annotations eqHsBang :: HsImplBang -> HsImplBang -> Bool eqHsBang HsLazy               HsLazy              = True@@ -1107,6 +1105,11 @@ isBanged (HsStrict {}) = True isBanged HsLazy        = False +isUnpacked :: HsImplBang -> Bool+isUnpacked (HsUnpack {}) = True+isUnpacked (HsStrict {}) = False+isUnpacked HsLazy        = False+ isSrcStrict :: SrcStrictness -> Bool isSrcStrict SrcStrict = True isSrcStrict _ = False@@ -1132,19 +1135,19 @@  -- | Build a new data constructor mkDataCon :: Name-          -> Bool           -- ^ Is the constructor declared infix?-          -> TyConRepName   -- ^  TyConRepName for the promoted TyCon-          -> [HsSrcBang]    -- ^ Strictness/unpack annotations, from user-          -> [FieldLabel]   -- ^ Field labels for the constructor,-                            -- if it is a record, otherwise empty-          -> [TyVar]        -- ^ Universals.-          -> [TyCoVar]      -- ^ Existentials.+          -> Bool               -- ^ Is the constructor declared infix?+          -> TyConRepName       -- ^  TyConRepName for the promoted TyCon+          -> [HsSrcBang]        -- ^ Strictness/unpack annotations, from user+          -> [HsImplBang]       -- ^ Strictness/unpack annotations, as inferred by the compiler+          -> [StrictnessMark]   -- ^ Strictness marks for the DataCon worker's fields in Core+          -> [FieldLabel]       -- ^ Field labels for the constructor,+                                -- if it is a record, otherwise empty+          -> [TyVar]            -- ^ Universals.+          -> [TyCoVar]          -- ^ Existentials.           -> ConcreteTyVars                                 -- ^ TyVars which must be instantiated with                                 -- concrete types-          -> [InvisTVBinder]    -- ^ User-written 'TyVarBinder's.-                                --   These must be Inferred/Specified.-                                --   See @Note [TyVarBinders in DataCons]@+          -> [TyVarBinder]      -- ^ User-written 'TyVarBinder's           -> [EqSpec]           -- ^ GADT equalities           -> KnotTied ThetaType -- ^ Theta-type occurring before the arguments proper           -> [KnotTied (Scaled Type)]    -- ^ Original argument types@@ -1160,7 +1163,9 @@   -- Can get the tag from the TyCon  mkDataCon name declared_infix prom_info-          arg_stricts   -- Must match orig_arg_tys 1-1+          arg_stricts  -- Must match orig_arg_tys 1-1+          impl_bangs   -- Must match orig_arg_tys 1-1+          str_marks    -- Must be empty or match dataConRepArgTys 1-1           fields           univ_tvs ex_tvs conc_tvs user_tvbs           eq_spec theta@@ -1177,6 +1182,8 @@   = con   where     is_vanilla = null ex_tvs && null eq_spec && null theta+    str_marks' | not $ any isMarkedStrict str_marks = []+               | otherwise                          = str_marks      con = MkData {dcName = name, dcUnique = nameUnique name,                   dcVanilla = is_vanilla, dcInfix = declared_infix,@@ -1189,7 +1196,8 @@                   dcStupidTheta = stupid_theta,                   dcOrigArgTys = orig_arg_tys, dcOrigResTy = orig_res_ty,                   dcRepTyCon = rep_tycon,-                  dcSrcBangs = arg_stricts,+                  dcSrcBangs = arg_stricts, dcImplBangs = impl_bangs,+                  dcStricts = str_marks',                   dcFields = fields, dcTag = tag, dcRepType = rep_ty,                   dcWorkId = work_id,                   dcRep = rep,@@ -1218,8 +1226,8 @@                  -- Hence using mkScaledFunctionTys.        -- See Note [Promoted data constructors] in GHC.Core.TyCon-    prom_tv_bndrs = [ mkNamedTyConBinder (Invisible spec) tv-                    | Bndr tv spec <- user_tvbs ]+    prom_tv_bndrs = [ mkNamedTyConBinder vis tv+                    | Bndr tv vis <- user_tvbs ]      fresh_names = freshNames (map getName user_tvbs)       -- fresh_names: make sure that the "anonymous" tyvars don't@@ -1316,9 +1324,9 @@ dataConUserTyVars (MkData { dcUserTyVarBinders = tvbs }) = binderVars tvbs  -- See Note [DataCon user type variable binders]--- | 'InvisTVBinder's for the type variables of the constructor, in the order the+-- | 'TyVarBinder's for the type variables of the constructor, in the order the -- user wrote them-dataConUserTyVarBinders :: DataCon -> [InvisTVBinder]+dataConUserTyVarBinders :: DataCon -> [TyVarBinder] dataConUserTyVarBinders = dcUserTyVarBinders  -- | Dependent (kind-level) equalities in a constructor.@@ -1405,10 +1413,18 @@ dataConSrcBangs :: DataCon -> [HsSrcBang] dataConSrcBangs = dcSrcBangs --- | Source-level arity of the data constructor+-- | Number of value arguments of the data constructor dataConSourceArity :: DataCon -> Arity dataConSourceArity (MkData { dcSourceArity = arity }) = arity +-- | Number of visible arguments of the data constructor+dataConVisArity :: DataCon -> VisArity+dataConVisArity (MkData { dcUserTyVarBinders = tvbs, dcSourceArity = arity })+  = n_of_required_ty_args + n_of_val_args+  where+    n_of_val_args         = arity+    n_of_required_ty_args = count isVisibleForAllTyBinder tvbs+ -- | Gives the number of value arguments (including zero-width coercions) -- stored by the given `DataCon`'s worker in its Core representation. This may -- differ from the number of arguments that appear in the source code; see also@@ -1432,20 +1448,25 @@ isNullaryRepDataCon :: DataCon -> Bool isNullaryRepDataCon dc = dataConRepArity dc == 0 +isLazyDataConRep :: DataCon -> Bool+-- ^ True <==> All fields are lazy+isLazyDataConRep dc = null (dcStricts dc)+ dataConRepStrictness :: DataCon -> [StrictnessMark]--- ^ Give the demands on the arguments of a--- Core constructor application (Con dc args)-dataConRepStrictness dc = case dcRep dc of-                            NoDataConRep -> [NotMarkedStrict | _ <- dataConRepArgTys dc]-                            DCR { dcr_stricts = strs } -> strs+-- ^ Give the demands on the runtime arguments of a Core DataCon worker+-- application.+-- The length of the list matches `dataConRepArgTys` (e.g., the number+-- of runtime arguments).+dataConRepStrictness dc+  | isLazyDataConRep dc+  = replicate (dataConRepArity dc) NotMarkedStrict+  | otherwise+  = dcStricts dc  dataConImplBangs :: DataCon -> [HsImplBang] -- The implementation decisions about the strictness/unpack of each -- source program argument to the data constructor-dataConImplBangs dc-  = case dcRep dc of-      NoDataConRep              -> replicate (dcSourceArity dc) HsLazy-      DCR { dcr_bangs = bangs } -> bangs+dataConImplBangs dc = dcImplBangs dc  dataConBoxer :: DataCon -> Maybe DataConBoxer dataConBoxer (MkData { dcRep = DCR { dcr_boxer = boxer } }) = Just boxer@@ -1562,7 +1583,7 @@                              dcOtherTheta = theta, dcOrigArgTys = arg_tys,                              dcOrigResTy = res_ty,                              dcStupidTheta = stupid_theta })-  = mkInvisForAllTys user_tvbs $+  = mkForAllTys user_tvbs $     mkInvisFunTys (stupid_theta ++ theta) $     mkScaledFunTys arg_tys $     res_ty@@ -1574,7 +1595,7 @@                                dcOtherTheta = theta, dcOrigArgTys = arg_tys,                                dcOrigResTy = res_ty,                                dcStupidTheta = stupid_theta })-  = mkInvisForAllTys user_tvbs $+  = mkForAllTys user_tvbs $     mkInvisFunTys (stupid_theta ++ theta) $     mkScaledFunTys arg_tys' $     res_ty@@ -1771,10 +1792,15 @@          && not (isTyVarTy ty)  -- See Note [isCovertGadtDataCon] for                                 -- an example where 'ty' is a tyvar +isUnaryClassDataCon :: DataCon -> Bool+isUnaryClassDataCon dc = isUnaryClassTyCon (dataConTyCon dc)+ {- Note [isCovertGadtDataCon] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (isCovertGadtDataCon K) returns True if K is a GADT data constructor, but-does not /look/ like it. Consider (#21447)+does not /look/ like it. It is used only to help in error message printing.++Consider (#21447)     type T :: TYPE r -> Type     data T a where { MkT :: b -> T b } Here MkT doesn't look GADT-like, but it is. If we make the kind applications@@ -1892,21 +1918,53 @@      wrapper_vars = dataConUserTyVars dc -dataConUserTyVarsNeedWrapper :: DataCon -> Bool--- Check whether the worker and wapper have the same type variables--- in the same order. If not, we need a wrapper to swizzle them.+dataConUserTyVarBindersNeedWrapper :: DataCon -> Bool+-- Check whether the worker and wrapper have the same type variables+-- in the same order and with the same visibility. If not, we need a+-- wrapper to swizzle them. -- See Note [DataCon user type variable binders], as well as -- Note [Data con wrappers and GADT syntax] for an explanation of what -- mkDataConRep is doing with this function.-dataConUserTyVarsNeedWrapper dc@(MkData { dcUnivTyVars = univ_tvs-                                        , dcExTyCoVars = ex_tvs-                                        , dcEqSpec = eq_spec })+dataConUserTyVarBindersNeedWrapper (MkData { dcUnivTyVars = univ_tvs+                                           , dcExTyCoVars = ex_tvs+                                           , dcUserTyVarBinders = user_tvbs+                                           , dcEqSpec = eq_spec })   = assert (null eq_spec || answer)  -- all GADTs should say "yes" here     answer   where-    answer = (univ_tvs ++ ex_tvs) /= dataConUserTyVars dc-              -- Worker tyvars         Wrapper tyvars+    answer = need_reorder || need_flag_cast+    need_reorder   = (univ_tvs ++ ex_tvs) /= binderVars user_tvbs+    need_flag_cast = any (not . eqForAllVis coreTyLamForAllTyFlag)+                         (binderFlags user_tvbs)+      -- See Note [Flag cast in data con wrappers] +{- Note [Flag cast in data con wrappers]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+Consider the data declaration++  data G a where+    MkG :: forall a -> a -> G a++The user-facing type of MkG has a 'Required' forall. Workers, on the other hand,+always use 'Specified' foralls (coreTyLamForAllTyFlag). So we need a wrapper:++  wrapper type: forall a -> a -> G a+  worker type:  forall a.   a -> G a++Concretely, it looks like this:++   $WMkG = /\a. \(x:a). MkG a x |> co++where 'co' is a coercion constructed by GHC.Core.Coercion.mkForAllVisCos.+The cast is added by the call to mkCoreTyLams in GHC.Types.Id.Make.mkDataConRep.++In general, wrappers may use 'Inferred', 'Specified', or 'Required' foralls.+However, we do /not/ need a cast to convert 'Inferred' to 'Specified' because they are+'eqType'-equal. Only a 'Required' forall necessitates a cast in the wrapper.++See Note [ForAllTy and type equality], Note [Comparing visibility],+and Note [Required foralls in Core].+-}  {- %************************************************************************
GHC/Core/DataCon.hs-boot view
@@ -1,7 +1,7 @@ module GHC.Core.DataCon where  import GHC.Prelude-import {-# SOURCE #-} GHC.Types.Var( Id, TyVar, TyCoVar, InvisTVBinder )+import {-# SOURCE #-} GHC.Types.Var( Id, TyVar, TyCoVar, TyVarBinder ) import {-# SOURCE #-} GHC.Types.Name( Name, NamedThing ) import {-# SOURCE #-} GHC.Core.TyCon( TyCon ) import GHC.Types.FieldLabel ( FieldLabel )@@ -19,7 +19,7 @@ dataConTyCon     :: DataCon -> TyCon dataConExTyCoVars :: DataCon -> [TyCoVar] dataConUserTyVars :: DataCon -> [TyVar]-dataConUserTyVarBinders :: DataCon -> [InvisTVBinder]+dataConUserTyVarBinders :: DataCon -> [TyVarBinder] dataConSourceArity  :: DataCon -> Arity dataConFieldLabels :: DataCon -> [FieldLabel] dataConInstOrigArgTys  :: DataCon -> [Type] -> [Scaled Type]
GHC/Core/FVs.hs view
@@ -36,7 +36,7 @@         ruleLhsFreeIds, ruleLhsFreeIdsList,         ruleRhsFreeVars, rulesRhsFreeIds, -        exprFVs,+        exprFVs, exprLocalFVs, addBndrFV, addBndrsFV,          -- * Orphan names         orphNamesOfType, orphNamesOfTypes, orphNamesOfAxiomLHS,@@ -96,23 +96,23 @@ -- | Find all locally-defined free Ids or type variables in an expression -- returning a non-deterministic set. exprFreeVars :: CoreExpr -> VarSet-exprFreeVars = fvVarSet . exprFVs+exprFreeVars = fvVarSet . exprLocalFVs  -- | Find all locally-defined free Ids or type variables in an expression -- returning a composable FV computation. See Note [FV naming conventions] in "GHC.Utils.FV" -- for why export it.-exprFVs :: CoreExpr -> FV-exprFVs = filterFV isLocalVar . expr_fvs+exprLocalFVs :: CoreExpr -> FV+exprLocalFVs = filterFV isLocalVar . exprFVs  -- | Find all locally-defined free Ids or type variables in an expression -- returning a deterministic set. exprFreeVarsDSet :: CoreExpr -> DVarSet-exprFreeVarsDSet = fvDVarSet . exprFVs+exprFreeVarsDSet = fvDVarSet . exprLocalFVs  -- | Find all locally-defined free Ids or type variables in an expression -- returning a deterministically ordered list. exprFreeVarsList :: CoreExpr -> [Var]-exprFreeVarsList = fvVarList . exprFVs+exprFreeVarsList = fvVarList . exprLocalFVs  -- | Find all locally-defined free Ids in an expression exprFreeIds :: CoreExpr -> IdSet        -- Find all locally-defined free Ids@@ -144,68 +144,65 @@ -- | Find all locally-defined free Ids or type variables in several expressions -- returning a non-deterministic set. exprsFreeVars :: [CoreExpr] -> VarSet-exprsFreeVars = fvVarSet . exprsFVs+exprsFreeVars = fvVarSet . exprsLocalFVs  -- | Find all locally-defined free Ids or type variables in several expressions -- returning a composable FV computation. See Note [FV naming conventions] in "GHC.Utils.FV" -- for why export it.-exprsFVs :: [CoreExpr] -> FV-exprsFVs exprs = mapUnionFV exprFVs exprs+exprsLocalFVs :: [CoreExpr] -> FV+exprsLocalFVs exprs = mapUnionFV exprLocalFVs exprs  -- | Find all locally-defined free Ids or type variables in several expressions -- returning a deterministically ordered list. exprsFreeVarsList :: [CoreExpr] -> [Var]-exprsFreeVarsList = fvVarList . exprsFVs+exprsFreeVarsList = fvVarList . exprsLocalFVs  -- | Find all locally defined free Ids in a binding group bindFreeVars :: CoreBind -> VarSet bindFreeVars (NonRec b r) = fvVarSet $ filterFV isLocalVar $ rhs_fvs (b,r) bindFreeVars (Rec prs)    = fvVarSet $ filterFV isLocalVar $-                                addBndrs (map fst prs)+                                addBndrsFV (map fst prs)                                      (mapUnionFV rhs_fvs prs)  -- | Finds free variables in an expression selected by a predicate exprSomeFreeVars :: InterestingVarFun   -- ^ Says which 'Var's are interesting                  -> CoreExpr                  -> VarSet-exprSomeFreeVars fv_cand e = fvVarSet $ filterFV fv_cand $ expr_fvs e+exprSomeFreeVars fv_cand e = fvVarSet $ filterFV fv_cand $ exprFVs e  -- | Finds free variables in an expression selected by a predicate -- returning a deterministically ordered list. exprSomeFreeVarsList :: InterestingVarFun -- ^ Says which 'Var's are interesting                      -> CoreExpr                      -> [Var]-exprSomeFreeVarsList fv_cand e = fvVarList $ filterFV fv_cand $ expr_fvs e+exprSomeFreeVarsList fv_cand e = fvVarList $ filterFV fv_cand $ exprFVs e  -- | Finds free variables in an expression selected by a predicate -- returning a deterministic set. exprSomeFreeVarsDSet :: InterestingVarFun -- ^ Says which 'Var's are interesting                      -> CoreExpr                      -> DVarSet-exprSomeFreeVarsDSet fv_cand e = fvDVarSet $ filterFV fv_cand $ expr_fvs e+exprSomeFreeVarsDSet fv_cand e = fvDVarSet $ filterFV fv_cand $ exprFVs e  -- | Finds free variables in several expressions selected by a predicate exprsSomeFreeVars :: InterestingVarFun  -- Says which 'Var's are interesting                   -> [CoreExpr]                   -> VarSet-exprsSomeFreeVars fv_cand es =-  fvVarSet $ filterFV fv_cand $ mapUnionFV expr_fvs es+exprsSomeFreeVars fv_cand es = fvVarSet $ filterFV fv_cand $ mapUnionFV exprFVs es  -- | Finds free variables in several expressions selected by a predicate -- returning a deterministically ordered list. exprsSomeFreeVarsList :: InterestingVarFun  -- Says which 'Var's are interesting                       -> [CoreExpr]                       -> [Var]-exprsSomeFreeVarsList fv_cand es =-  fvVarList $ filterFV fv_cand $ mapUnionFV expr_fvs es+exprsSomeFreeVarsList fv_cand es = fvVarList $ filterFV fv_cand $ mapUnionFV exprFVs es  -- | Finds free variables in several expressions selected by a predicate -- returning a deterministic set. exprsSomeFreeVarsDSet :: InterestingVarFun -- ^ Says which 'Var's are interesting                       -> [CoreExpr]                       -> DVarSet-exprsSomeFreeVarsDSet fv_cand e =-  fvDVarSet $ filterFV fv_cand $ mapUnionFV expr_fvs e+exprsSomeFreeVarsDSet fv_cand e = fvDVarSet $ filterFV fv_cand $ mapUnionFV exprFVs e  --      Comment about obsolete code -- We used to gather the free variables the RULES at a variable occurrence@@ -235,59 +232,59 @@ --                          | otherwise                    = set --      SLPJ Feb06 -addBndr :: CoreBndr -> FV -> FV-addBndr bndr fv fv_cand in_scope acc+addBndrFV :: CoreBndr -> FV -> FV+addBndrFV bndr fv fv_cand in_scope acc   = (varTypeTyCoFVs bndr `unionFV`         -- Include type variables in the binder's type         --      (not just Ids; coercion variables too!)      FV.delFV bndr fv) fv_cand in_scope acc -addBndrs :: [CoreBndr] -> FV -> FV-addBndrs bndrs fv = foldr addBndr fv bndrs+addBndrsFV :: [CoreBndr] -> FV -> FV+addBndrsFV bndrs fv = foldr addBndrFV fv bndrs -expr_fvs :: CoreExpr -> FV-expr_fvs (Type ty) fv_cand in_scope acc =+exprsFVs :: [CoreExpr] -> FV+exprsFVs exprs = mapUnionFV exprFVs exprs++exprFVs :: CoreExpr -> FV+exprFVs (Type ty) fv_cand in_scope acc =   tyCoFVsOfType ty fv_cand in_scope acc-expr_fvs (Coercion co) fv_cand in_scope acc =+exprFVs (Coercion co) fv_cand in_scope acc =   tyCoFVsOfCo co fv_cand in_scope acc-expr_fvs (Var var) fv_cand in_scope acc = FV.unitFV var fv_cand in_scope acc-expr_fvs (Lit _) fv_cand in_scope acc = emptyFV fv_cand in_scope acc-expr_fvs (Tick t expr) fv_cand in_scope acc =-  (tickish_fvs t `unionFV` expr_fvs expr) fv_cand in_scope acc-expr_fvs (App fun arg) fv_cand in_scope acc =-  (expr_fvs fun `unionFV` expr_fvs arg) fv_cand in_scope acc-expr_fvs (Lam bndr body) fv_cand in_scope acc =-  addBndr bndr (expr_fvs body) fv_cand in_scope acc-expr_fvs (Cast expr co) fv_cand in_scope acc =-  (expr_fvs expr `unionFV` tyCoFVsOfCo co) fv_cand in_scope acc+exprFVs (Var var) fv_cand in_scope acc = FV.unitFV var fv_cand in_scope acc+exprFVs (Lit _) fv_cand in_scope acc = emptyFV fv_cand in_scope acc+exprFVs (Tick t expr) fv_cand in_scope acc =+  (tickish_fvs t `unionFV` exprFVs expr) fv_cand in_scope acc+exprFVs (App fun arg) fv_cand in_scope acc =+  (exprFVs fun `unionFV` exprFVs arg) fv_cand in_scope acc+exprFVs (Lam bndr body) fv_cand in_scope acc =+  addBndrFV bndr (exprFVs body) fv_cand in_scope acc+exprFVs (Cast expr co) fv_cand in_scope acc =+  (exprFVs expr `unionFV` tyCoFVsOfCo co) fv_cand in_scope acc -expr_fvs (Case scrut bndr ty alts) fv_cand in_scope acc-  = (expr_fvs scrut `unionFV` tyCoFVsOfType ty `unionFV` addBndr bndr+exprFVs (Case scrut bndr ty alts) fv_cand in_scope acc+  = (exprFVs scrut `unionFV` tyCoFVsOfType ty `unionFV` addBndrFV bndr       (mapUnionFV alt_fvs alts)) fv_cand in_scope acc   where-    alt_fvs (Alt _ bndrs rhs) = addBndrs bndrs (expr_fvs rhs)+    alt_fvs (Alt _ bndrs rhs) = addBndrsFV bndrs (exprFVs rhs) -expr_fvs (Let (NonRec bndr rhs) body) fv_cand in_scope acc-  = (rhs_fvs (bndr, rhs) `unionFV` addBndr bndr (expr_fvs body))+exprFVs (Let (NonRec bndr rhs) body) fv_cand in_scope acc+  = (rhs_fvs (bndr, rhs) `unionFV` addBndrFV bndr (exprFVs body))       fv_cand in_scope acc -expr_fvs (Let (Rec pairs) body) fv_cand in_scope acc-  = addBndrs (map fst pairs)-             (mapUnionFV rhs_fvs pairs `unionFV` expr_fvs body)+exprFVs (Let (Rec pairs) body) fv_cand in_scope acc+  = addBndrsFV (map fst pairs)+               (mapUnionFV rhs_fvs pairs `unionFV` exprFVs body)                fv_cand in_scope acc  --------- rhs_fvs :: (Id, CoreExpr) -> FV-rhs_fvs (bndr, rhs) = expr_fvs rhs `unionFV`+rhs_fvs (bndr, rhs) = exprFVs rhs `unionFV`                       bndrRuleAndUnfoldingFVs bndr         -- Treat any RULES as extra RHSs of the binding  ----------exprs_fvs :: [CoreExpr] -> FV-exprs_fvs exprs = mapUnionFV expr_fvs exprs- tickish_fvs :: CoreTickish -> FV-tickish_fvs (Breakpoint _ _ ids _) = FV.mkFVs ids+tickish_fvs (Breakpoint _ _ ids) = FV.mkFVs ids tickish_fvs _ = emptyFV  {- **********************************************************************@@ -434,7 +431,7 @@                      -- See Note [Rule free var hack]                    , ru_bndrs = bndrs                    , ru_rhs = rhs, ru_args = args })-  = filterFV isLocalVar $ addBndrs bndrs (exprs_fvs exprs)+  = filterFV isLocalVar $ addBndrsFV bndrs (exprsFVs exprs)   where     exprs = case from of       LhsOnly   -> args@@ -653,9 +650,9 @@   = case unf of       CoreUnfolding { uf_tmpl = rhs, uf_src = src }          | isStableSource src-         -> Just (filterFV isLocalVar $ expr_fvs rhs)+         -> Just (exprLocalFVs rhs)       DFunUnfolding { df_bndrs = bndrs, df_args = args }-         -> Just (filterFV isLocalVar $ FV.delFVs (mkVarSet bndrs) $ exprs_fvs args)+         -> Just (filterFV isLocalVar $ FV.delFVs (mkVarSet bndrs) $ exprsFVs args)             -- DFuns are top level, so no fvs from types of bndrs       _other -> Nothing @@ -702,7 +699,7 @@       | isLocalVar v = (aFreeVar v `unionFVs` ty_fvs `unionFVs` mult_vars, AnnVar v)       | otherwise    = (emptyDVarSet,                 AnnVar v)       where-        mult_vars = tyCoVarsOfTypeDSet (varMult v)+        mult_vars = tyCoVarsOfTypeDSet (idMult v)         ty_fvs = dVarTypeTyCoVars v                  -- See Note [The FVAnn invariant] @@ -759,8 +756,8 @@         , AnnTick tickish expr2 )       where         expr2 = go expr-        tickishFVs (Breakpoint _ _ ids _) = mkDVarSet ids-        tickishFVs _                      = emptyDVarSet+        tickishFVs (Breakpoint _ _ ids) = mkDVarSet ids+        tickishFVs _                    = emptyDVarSet      go (Type ty)     = (tyCoVarsOfTypeDSet ty, AnnType ty)     go (Coercion co) = (tyCoVarsOfCoDSet co, AnnCoercion co)
GHC/Core/FamInstEnv.hs view
@@ -42,6 +42,7 @@ import GHC.Core.Unify import GHC.Core.Type as Type import GHC.Core.TyCo.Rep+import GHC.Core.TyCo.Tidy import GHC.Core.TyCo.Compare( eqType, eqTypes ) import GHC.Core.TyCon import GHC.Core.Coercion@@ -247,10 +248,10 @@     ppr_tc_sort = case flavor of                      SynFamilyInst             -> text "type"                      DataFamilyInst tycon-                       | isDataTyCon     tycon -> text "data"-                       | isNewTyCon      tycon -> text "newtype"-                       | isAbstractTyCon tycon -> text "data"-                       | otherwise             -> text "WEIRD" <+> ppr tycon+                       | isBoxedDataTyCon tycon -> text "data"+                       | isNewTyCon       tycon -> text "newtype"+                       | isAbstractTyCon  tycon -> text "data"+                       | otherwise              -> text "WEIRD" <+> ppr tycon      debug_stuff = vcat [ text "Coercion axiom:" <+> ppr ax                        , text "Tvs:" <+> ppr tvs@@ -487,8 +488,8 @@ apart(target, pattern) = not (unify(flatten(target), pattern))  where flatten (implemented in flattenTys, below) converts all type-family-applications into fresh variables. (See-Note [Flattening type-family applications when matching instances] in GHC.Core.Unify.)+applications into fresh variables. (See Note [Apartness and type families]+in GHC.Core.Unify.)  Note [Compatibility] ~~~~~~~~~~~~~~~~~~~~@@ -512,11 +513,11 @@ only when we can be sure that 'a' is not Int.  To achieve this, after finding a possible match within the equations, we have to-go back to all previous equations and check that, under the-substitution induced by the match, other branches are surely apart. (See-Note [Apartness].) This is similar to what happens with class-instance selection, when we need to guarantee that there is only a match and-no unifiers. The exact algorithm is different here because the+go back to all previous equations and check that, under the substitution induced+by the match, other branches are surely apart, using `tcUnifyTysFG`. (See+Note [Apartness and type families] in GHC.Core.Unify.) This is similar to what+happens with class instance selection, when we need to guarantee that there is+only a match and no unifiers. The exact algorithm is different here because the potentially-overlapping group is closed.  As another example, consider this:@@ -579,7 +580,7 @@ compatibleBranches :: CoAxBranch -> CoAxBranch -> Bool compatibleBranches (CoAxBranch { cab_lhs = lhs1, cab_rhs = rhs1 })                    (CoAxBranch { cab_lhs = lhs2, cab_rhs = rhs2 })-  = case tcUnifyTysFG alwaysBindFun commonlhs1 commonlhs2 of+  = case tcUnifyTysFG alwaysBindFam alwaysBindTv commonlhs1 commonlhs2 of       -- Here we need the cab_tvs of the two branches to be disinct.       -- See Note [CoAxBranch type variables] in GHC.Core.Coercion.Axiom.       SurelyApart     -> True@@ -610,7 +611,8 @@   -- See Note [Verifying injectivity annotation], case 1.   = let getInjArgs  = filterByList injectivity         in_scope    = mkInScopeSetList (tvs1 ++ tvs2)-    in case tcUnifyTyWithTFs True in_scope rhs1 rhs2 of -- True = two-way pre-unification+    in case tcUnifyTyForInjectivity True in_scope rhs1 rhs2 of+             -- True = two-way pre-unification        Nothing -> InjectivityAccepted          -- RHS are different, so equations are injective.          -- This is case 1A from Note [Verifying injectivity annotation]@@ -1228,22 +1230,16 @@        -> Maybe (BranchIndex, [Type], [Coercion])     go (index, branch) other       = let (CoAxBranch { cab_tvs = tpl_tvs, cab_cvs = tpl_cvs-                        , cab_lhs = tpl_lhs-                        , cab_incomps = incomps }) = branch-            in_scope = mkInScopeSet (unionVarSets $-                            map (tyCoVarsOfTypes . coAxBranchLHS) incomps)-            -- See Note [Flattening type-family applications when matching instances]-            -- in GHC.Core.Unify-            flattened_target = flattenTys in_scope target_tys+                        , cab_lhs = tpl_lhs }) = branch         in case tcMatchTys tpl_lhs target_tys of-        Just subst -- matching worked. now, check for apartness.-          |  apartnessCheck flattened_target branch-          -> -- matching worked & we're apart from all incompatible branches.+        Just subst -- Matching worked. now, check for apartness.+          |  apartnessCheck target_tys branch+          -> -- Matching worked & we're apart from all incompatible branches.              -- success              assert (all (isJust . lookupCoVar subst) tpl_cvs) $              Just (index, substTyVars subst tpl_tvs, substCoVars subst tpl_cvs) -        -- failure. keep looking+        -- Failure. keep looking         _ -> other  -- | Do an apartness check, as described in the "Closed Type Families" paper@@ -1251,15 +1247,12 @@ -- ('CoAxBranch') of a closed type family can be used to reduce a certain target -- type family application. apartnessCheck :: [Type]-  -- ^ /flattened/ target arguments. Make sure they're flattened! See-  -- Note [Flattening type-family applications when matching instances]-  -- in GHC.Core.Unify.-               -> CoAxBranch -- ^ the candidate equation we wish to use+               -> CoAxBranch -- ^ The candidate equation we wish to use                              -- Precondition: this matches the target                -> Bool       -- ^ True <=> equation can fire-apartnessCheck flattened_target (CoAxBranch { cab_incomps = incomps })+apartnessCheck target (CoAxBranch { cab_incomps = incomps })   = all (isSurelyApart-         . tcUnifyTysFG alwaysBindFun flattened_target+         . tcUnifyTysFG alwaysBindFam alwaysBindTv target          . coAxBranchLHS) incomps   where     isSurelyApart SurelyApart = True@@ -1343,7 +1336,7 @@ --      * newtypes -- returning an appropriate Representational coercion.  Specifically, if --   topNormaliseType_maybe env ty = Just (co, ty')--- then+-- then postconditions: --   (a) co :: ty ~R ty' --   (b) ty' is not a newtype, and is not a type-family or data-family redex --
GHC/Core/InstEnv.hs view
@@ -174,7 +174,7 @@ Reason for freshness: we use unification when checking for overlap etc, and that requires the tyvars to be distinct. -The invariant is checked by the ASSERT in lookupInstEnv'.+The invariant is checked by the ASSERT in instEnvMatchesAndUnifiers.  Note [Proper-match fields] ~~~~~~~~~~~~~~~~~~~~~~~~~@@ -947,11 +947,8 @@ * That info is recorded in the `cir_is_coherent` field of `OneInst`, and thence   transferred to the `ep_is_coherent` field of the `EvBind` for the dictionary. -* `GHC.HsToCore.Binds.dsHsWrapper` desugars the evidence application (f d) into-  (nospec f d) if `d` is incoherent. It has to do a dependency analysis to-  determine transitive dependencies, but we need to do that anyway.-  See Note [Desugaring non-canonical evidence] in GHC.HsToCore.Binds.-+* In the desugarer we exploit this info:+  see Note [Desugaring non-canonical evidence] in GHC.HsToCore.Expr.   See also Note [nospecId magic] in GHC.Types.Id.Make.  @@ -1247,10 +1244,14 @@                 -- Unification will break badly if the variables overlap                 -- They shouldn't because we allocate separate uniques for them                 -- See Note [Template tyvars are fresh]-        case tcUnifyTysFG instanceBindFun tpl_tys tys of+        case tcUnifyTysFG alwaysBindFam instanceBindFun tpl_tys tys of+          -- alwaysBindFam: the family-application can't be in the instance head,+          -- but it certainly can be in the Wanted constraint we are matching!+          --           -- We consider MaybeApart to be a case where the instance might           -- apply in the future. This covers an instance like C Int and           -- a target like [W] C (F a), where F is a type family.+          -- See (ATF1) in Note [Apartness and type families] in GHC.Core.Unify             SurelyApart              -> check_unifiers items               -- See Note [Infinitary substitution in lookup]             MaybeApart MARInfinite _ -> check_unifiers items@@ -1670,14 +1671,14 @@ ************************************************************************ -} -instanceBindFun :: BindFun-instanceBindFun tv _rhs_ty | isOverlappableTyVar tv = Apart+instanceBindFun :: BindTvFun+instanceBindFun tv _rhs_ty | isOverlappableTyVar tv = DontBindMe                            | otherwise              = BindMe-   -- Note [Binding when looking up instances]+   -- Note [Super skolems: binding when looking up instances]  {--Note [Binding when looking up instances]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+Note [Super skolems: binding when looking up instances]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ When looking up in the instance environment, or family-instance environment, we are careful about multiple matches, as described above in Note [Overlapping instances]@@ -1693,9 +1694,9 @@         f :: T -> Int         f (MkT x) = op [x,x] The op [x,x] means we need (Foo [a]). This `a` will never be instantiated, and-so it is a super skolem. (See the use of tcInstSuperSkolTyVarsX in+so it is a "super skolem". (See the use of tcInstSuperSkolTyVarsX in GHC.Tc.Gen.Pat.tcDataConPat.) Super skolems respond True to-isOverlappableTyVar, and the use of Apart in instanceBindFun, above, means+isOverlappableTyVar, and the use of DontBindMe in instanceBindFun, above, means that these will be treated as fresh constants in the unification algorithm during instance lookup. Without this treatment, GHC would complain, saying that the choice of instance depended on the instantiation of 'a'; but of
GHC/Core/LateCC/OverloadedCalls.hs view
@@ -25,7 +25,6 @@ import GHC.Types.SrcLoc import GHC.Types.Tickish import GHC.Types.Var-import GHC.Utils.Outputable  type OverloadedCallsCCState = Strict.Maybe SrcSpan @@ -103,7 +102,7 @@           -- check if any of the arguments v1 ... vN are dictionaries.           let             (f, xs) = collectArgs app-            resultTy = applyTypeToArgs empty (exprType f) xs+            resultTy = applyTypeToArgs (exprType f) xs            -- Recursively process the arguments first for no particular reason           args <- mapM processExpr xs
GHC/Core/LateCC/TopLevelBinds.hs view
GHC/Core/Lint.hs view
@@ -82,3780 +82,3860 @@  import GHC.Builtin.Names import GHC.Builtin.Types.Prim-import GHC.Builtin.Types ( multiplicityTy )--import GHC.Data.Bag-import GHC.Data.List.SetOps--import GHC.Utils.Monad-import GHC.Utils.Outputable as Outputable-import GHC.Utils.Panic-import GHC.Utils.Constants (debugIsOn)-import GHC.Utils.Misc-import GHC.Utils.Error-import qualified GHC.Utils.Error as Err-import GHC.Utils.Logger--import Control.Monad-import Data.Foldable      ( for_, toList )-import Data.List.NonEmpty ( NonEmpty(..), groupWith )-import Data.List          ( partition )-import Data.Maybe-import Data.IntMap.Strict ( IntMap )-import qualified Data.IntMap.Strict as IntMap ( lookup, keys, empty, fromList )-import GHC.Data.Pair-import GHC.Base (oneShot)-import GHC.Data.Unboxed--{--Note [Core Lint guarantee]-~~~~~~~~~~~~~~~~~~~~~~~~~~-Core Lint is the type-checker for Core. Using it, we get the following guarantee:--If all of:-1. Core Lint passes,-2. there are no unsafe coercions (i.e. unsafeEqualityProof),-3. all plugin-supplied coercions (i.e. PluginProv) are valid, and-4. all case-matches are complete-then running the compiled program will not seg-fault, assuming no bugs downstream-(e.g. in the code generator). This guarantee is quite powerful, in that it allows us-to decouple the safety of the resulting program from the type inference algorithm.--However, do note point (4) above. Core Lint does not check for incomplete case-matches;-see Note [Case expression invariants] in GHC.Core, invariant (4). As explained there,-an incomplete case-match might slip by Core Lint and cause trouble at runtime.--Note [GHC Formalism]-~~~~~~~~~~~~~~~~~~~~-This file implements the type-checking algorithm for System FC, the "official"-name of the Core language. Type safety of FC is heart of the claim that-executables produced by GHC do not have segmentation faults. Thus, it is-useful to be able to reason about System FC independently of reading the code.-To this purpose, there is a document core-spec.pdf built in docs/core-spec that-contains a formalism of the types and functions dealt with here. If you change-just about anything in this file or you change other types/functions throughout-the Core language (all signposted to this note), you should update that-formalism. See docs/core-spec/README for more info about how to do so.--Note [check vs lint]-~~~~~~~~~~~~~~~~~~~~-This file implements both a type checking algorithm and also general sanity-checking. For example, the "sanity checking" checks for TyConApp on the left-of an AppTy, which should never happen. These sanity checks don't really-affect any notion of type soundness. Yet, it is convenient to do the sanity-checks at the same time as the type checks. So, we use the following naming-convention:--- Functions that begin with 'lint'... are involved in type checking. These-  functions might also do some sanity checking.--- Functions that begin with 'check'... are *not* involved in type checking.-  They exist only for sanity checking.--Issues surrounding variable naming, shadowing, and such are considered *not*-to be part of type checking, as the formalism omits these details.--Summary of checks-~~~~~~~~~~~~~~~~~-Checks that a set of core bindings is well-formed.  The PprStyle and String-just control what we print in the event of an error.  The Bool value-indicates whether we have done any specialisation yet (in which case we do-some extra checks).--We check for-        (a) type errors-        (b) Out-of-scope type variables-        (c) Out-of-scope local variables-        (d) Ill-kinded types-        (e) Incorrect unsafe coercions--If we have done specialisation the we check that there are-        (a) No top-level bindings of primitive (unboxed type)--Note [Linting function types]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-All saturated applications of funTyCon are represented with the FunTy constructor.-See Note [Function type constructors and FunTy] in GHC.Builtin.Types.Prim-- We check this invariant in lintType.--Note [Linting type lets]-~~~~~~~~~~~~~~~~~~~~~~~~-In the desugarer, it's very very convenient to be able to say (in effect)-        let a = Type Bool in-        let x::a = True in <body>-That is, use a type let.  See Note [Core type and coercion invariant] in "GHC.Core".-One place it is used is in mkWwBodies; see Note [Join points and beta-redexes]-in GHC.Core.Opt.WorkWrap.Utils.  (Maybe there are other "clients" of this feature; I'm not sure).--* Hence when linting <body> we need to remember that a=Int, else we-  might reject a correct program.  So we carry a type substitution (in-  this example [a -> Bool]) and apply this substitution before-  comparing types. In effect, in Lint, type equality is always-  equality-modulo-le-subst.  This is in the le_subst field of-  LintEnv.  But nota bene:--  (SI1) The le_subst substitution is applied to types and coercions only--  (SI2) The result of that substitution is used only to check for type-        equality, to check well-typed-ness, /but is then discarded/.-        The result of substitution does not outlive the CoreLint pass.--  (SI3) The InScopeSet of le_subst includes only TyVar and CoVar binders.--* The function-        lintInTy :: Type -> LintM (Type, Kind)-  returns a substituted type.--* When we encounter a binder (like x::a) we must apply the substitution-  to the type of the binding variable.  lintBinders does this.--* Clearly we need to clone tyvar binders as we go.--* But take care (#17590)! We must also clone CoVar binders:-    let a = TYPE (ty |> cv)-    in \cv -> blah-  blindly substituting for `a` might capture `cv`.--* Alas, when cloning a coercion variable we might choose a unique-  that happens to clash with an inner Id, thus-      \cv_66 -> let wild_X7 = blah in blah-  We decide to clone `cv_66` because it's already in scope.  Fine,-  choose a new unique.  Aha, X7 looks good.  So we check the lambda-  body with le_subst of [cv_66 :-> cv_X7]--  This is all fine, even though we use the same unique as wild_X7.-  As (SI2) says, we do /not/ return a new lambda-     (\cv_X7 -> let wild_X7 = blah in ...)-  We simply use the le_subst substitution in types/coercions only, when-  checking for equality.--* We still need to check that Id occurrences are bound by some-  enclosing binding.  We do /not/ use the InScopeSet for the le_subst-  for this purpose -- it contains only TyCoVars.  Instead we have a separate-  le_ids for the in-scope Id binders.--Sigh.  We might want to explore getting rid of type-let!--Note [Bad unsafe coercion]-~~~~~~~~~~~~~~~~~~~~~~~~~~-For discussion see https://gitlab.haskell.org/ghc/ghc/wikis/bad-unsafe-coercions-Linter introduces additional rules that checks improper coercion between-different types, called bad coercions. Following coercions are forbidden:--  (a) coercions between boxed and unboxed values;-  (b) coercions between unlifted values of the different sizes, here-      active size is checked, i.e. size of the actual value but not-      the space allocated for value;-  (c) coercions between floating and integral boxed values, this check-      is not yet supported for unboxed tuples, as no semantics were-      specified for that;-  (d) coercions from / to vector type-  (e) If types are unboxed tuples then tuple (# A_1,..,A_n #) can be-      coerced to (# B_1,..,B_m #) if n=m and for each pair A_i, B_i rules-      (a-e) holds.--Note [Join points]-~~~~~~~~~~~~~~~~~~-We check the rules listed in Note [Invariants on join points] in GHC.Core. The-only one that causes any difficulty is the first: All occurrences must be tail-calls. To this end, along with the in-scope set, we remember in le_joins the-subset of in-scope Ids that are valid join ids. For example:--  join j x = ... in-  case e of-    A -> jump j y -- good-    B -> case (jump j z) of -- BAD-           C -> join h = jump j w in ... -- good-           D -> let x = jump j v in ... -- BAD--A join point remains valid in case branches, so when checking the A-branch, j is still valid. When we check the scrutinee of the inner-case, however, we set le_joins to empty, and catch the-error. Similarly, join points can occur free in RHSes of other join-points but not the RHSes of value bindings (thunks and functions).--Note [Avoiding compiler perf traps when constructing error messages.]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-It's quite common to put error messages into a where clause when it might-be triggered by multiple branches. E.g.--  checkThing x y z =-    case x of-      X -> unless (correctX x) $ failWithL errMsg-      Y -> unless (correctY y) $ failWithL errMsg-    where-      errMsg = text "My error involving:" $$ ppr x <+> ppr y--However ghc will compile this to:--  checkThink x y z =-    let errMsg = text "My error involving:" $$ ppr x <+> ppr y-    in case x of-      X -> unless (correctX x) $ failWithL errMsg-      Y -> unless (correctY y) $ failWithL errMsg--Putting the allocation of errMsg into the common non-error path.-One way to work around this is to turn errMsg into a function:--  checkThink x y z =-    case x of-      X -> unless (correctX x) $ failWithL (errMsg x y)-      Y -> unless (correctY y) $ failWithL (errMsg x y)-    where-      errMsg x y = text "My error involving:" $$ ppr x <+> ppr y--This way `errMsg` is a static function and it being defined in the common-path does not result in allocation in the hot path. This can be surprisingly-impactful. Changing `lint_app` reduced allocations for one test program I was-looking at by ~4%.--Note [MCInfo for Lint]-~~~~~~~~~~~~~~~~~~~~~~-When printing a Lint message, use the MCInfo severity so that the-message is printed on stderr rather than stdout (#13342).--************************************************************************-*                                                                      *-                 Beginning and ending passes-*                                                                      *-************************************************************************--}---- | Configuration for boilerplate operations at the end of a--- compilation pass producing Core.-data EndPassConfig = EndPassConfig-  { ep_dumpCoreSizes :: !Bool-  -- ^ Whether core bindings should be dumped with the size of what they-  -- are binding (i.e. the size of the RHS of the binding).--  , ep_lintPassResult :: !(Maybe LintPassResultConfig)-  -- ^ Whether we should lint the result of this pass.--  , ep_namePprCtx :: !NamePprCtx--  , ep_dumpFlag :: !(Maybe DumpFlag)--  , ep_prettyPass :: !SDoc--  , ep_passDetails :: !SDoc-  }--endPassIO :: Logger-          -> EndPassConfig-          -> CoreProgram -> [CoreRule]-          -> IO ()--- Used by the IO-is CorePrep too-endPassIO logger cfg binds rules-  = do { dumpPassResult logger (ep_dumpCoreSizes cfg) (ep_namePprCtx cfg) mb_flag-                        (renderWithContext defaultSDocContext (ep_prettyPass cfg))-                        (ep_passDetails cfg) binds rules-       ; for_ (ep_lintPassResult cfg) $ \lp_cfg ->-           lintPassResult logger lp_cfg binds-       }-  where-    mb_flag = case ep_dumpFlag cfg of-                Just flag | logHasDumpFlag logger flag                    -> Just flag-                          | logHasDumpFlag logger Opt_D_verbose_core2core -> Just flag-                _ -> Nothing--dumpPassResult :: Logger-               -> Bool                  -- dump core sizes?-               -> NamePprCtx-               -> Maybe DumpFlag        -- Just df => show details in a file whose-                                        --            name is specified by df-               -> String                -- Header-               -> SDoc                  -- Extra info to appear after header-               -> CoreProgram -> [CoreRule]-               -> IO ()-dumpPassResult logger dump_core_sizes name_ppr_ctx mb_flag hdr extra_info binds rules-  = do { forM_ mb_flag $ \flag -> do-           logDumpFile logger (mkDumpStyle name_ppr_ctx) flag hdr FormatCore dump_doc--         -- Report result size-         -- This has the side effect of forcing the intermediate to be evaluated-         -- if it's not already forced by a -ddump flag.-       ; Err.debugTraceMsg logger 2 size_doc-       }--  where-    size_doc = sep [text "Result size of" <+> text hdr, nest 2 (equals <+> ppr (coreBindsStats binds))]--    dump_doc  = vcat [ nest 2 extra_info-                     , size_doc-                     , blankLine-                     , if dump_core_sizes-                        then pprCoreBindingsWithSize binds-                        else pprCoreBindings         binds-                     , ppUnless (null rules) pp_rules ]-    pp_rules = vcat [ blankLine-                    , text "------ Local rules for imported ids --------"-                    , pprRules rules ]--{--************************************************************************-*                                                                      *-                 Top-level interfaces-*                                                                      *-************************************************************************--}--data LintPassResultConfig = LintPassResultConfig-  { lpr_diagOpts         :: !DiagOpts-  , lpr_platform         :: !Platform-  , lpr_makeLintFlags    :: !LintFlags-  , lpr_showLintWarnings :: !Bool-  , lpr_passPpr          :: !SDoc-  , lpr_localsInScope    :: ![Var]-  }--lintPassResult :: Logger -> LintPassResultConfig-               -> CoreProgram -> IO ()-lintPassResult logger cfg binds-  = do { let warns_and_errs = lintCoreBindings'-               (LintConfig-                { l_diagOpts = lpr_diagOpts cfg-                , l_platform = lpr_platform cfg-                , l_flags    = lpr_makeLintFlags cfg-                , l_vars     = lpr_localsInScope cfg-                })-               binds-       ; Err.showPass logger $-           "Core Linted result of " ++-           renderWithContext defaultSDocContext (lpr_passPpr cfg)-       ; displayLintResults logger-                            (lpr_showLintWarnings cfg) (lpr_passPpr cfg)-                            (pprCoreBindings binds) warns_and_errs-       }--displayLintResults :: Logger-                   -> Bool -- ^ If 'True', display linter warnings.-                           --   If 'False', ignore linter warnings.-                   -> SDoc -- ^ The source of the linted program-                   -> SDoc -- ^ The linted program, pretty-printed-                   -> WarnsAndErrs-                   -> IO ()-displayLintResults logger display_warnings pp_what pp_pgm (warns, errs)-  | not (isEmptyBag errs)-  = do { logMsg logger Err.MCInfo noSrcSpan  -- See Note [MCInfo for Lint]-           $ withPprStyle defaultDumpStyle-           (vcat [ lint_banner "errors" pp_what, Err.pprMessageBag errs-                 , text "*** Offending Program ***"-                 , pp_pgm-                 , text "*** End of Offense ***" ])-       ; Err.ghcExit logger 1 }--  | not (isEmptyBag warns)-  , log_enable_debug (logFlags logger)-  , display_warnings-  = logMsg logger Err.MCInfo noSrcSpan  -- See Note [MCInfo for Lint]-      $ withPprStyle defaultDumpStyle-        (lint_banner "warnings" pp_what $$ Err.pprMessageBag (mapBag ($$ blankLine) warns))--  | otherwise = return ()--lint_banner :: String -> SDoc -> SDoc-lint_banner string pass = text "*** Core Lint"      <+> text string-                          <+> text ": in result of" <+> pass-                          <+> text "***"---- | Type-check a 'CoreProgram'. See Note [Core Lint guarantee].-lintCoreBindings' :: LintConfig -> CoreProgram -> WarnsAndErrs---   Returns (warnings, errors)--- If you edit this function, you may need to update the GHC formalism--- See Note [GHC Formalism]-lintCoreBindings' cfg binds-  = initL cfg $-    addLoc TopLevelBindings           $-    do { -- Check that all top-level binders are distinct-         -- We do not allow  [NonRec x=1, NonRec y=x, NonRec x=2]-         -- because of glomming; see Note [Glomming] in GHC.Core.Opt.OccurAnal-         checkL (null dups) (dupVars dups)--         -- Check for External top level binders with the same M.n name-       ; checkL (null ext_dups) (dupExtVars ext_dups)--         -- Typecheck the bindings-       ; lintRecBindings TopLevel all_pairs $ \_ ->-         return () }-  where-    all_pairs = flattenBinds binds-     -- Put all the top-level binders in scope at the start-     -- This is because rewrite rules can bring something-     -- into use 'unexpectedly'; see Note [Glomming] in "GHC.Core.Opt.OccurAnal"-    binders = map fst all_pairs--    (_, dups) = removeDups compare binders--    -- ext_dups checks for names with different uniques-    -- but the same External name M.n.  We don't-    -- allow this at top level:-    --    M.n{r3}  = ...-    --    M.n{r29} = ...-    -- because they both get the same linker symbol-    ext_dups = snd $ removeDupsOn ord_ext $-               filter isExternalName $ map Var.varName binders-    ord_ext n = (nameModule n, nameOccName n)--{--************************************************************************-*                                                                      *-\subsection[lintUnfolding]{lintUnfolding}-*                                                                      *-************************************************************************--Note [Linting Unfoldings from Interfaces]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-We use this to check all top-level unfoldings that come in from interfaces-(it is very painful to catch errors otherwise).--We do not need to call lintUnfolding on unfoldings that are nested within-top-level unfoldings; they are linted when we lint the top-level unfolding;-hence the `TopLevelFlag` on `tcPragExpr` in GHC.IfaceToCore.---}--lintUnfolding :: Bool             -- ^ True <=> is a compulsory unfolding-              -> LintConfig-              -> SrcLoc-              -> CoreExpr-              -> Maybe (Bag SDoc) -- Nothing => OK--lintUnfolding is_compulsory cfg locn expr-  | isEmptyBag errs = Nothing-  | otherwise       = Just errs-  where-    (_warns, errs) = initL cfg $-                     if is_compulsory-                       -- See Note [Checking for representation polymorphism]-                     then noFixedRuntimeRepChecks linter-                     else linter-    linter = addLoc (ImportedUnfolding locn) $-             lintCoreExpr expr--lintExpr :: LintConfig-         -> CoreExpr-         -> Maybe (Bag SDoc)  -- Nothing => OK--lintExpr cfg expr-  | isEmptyBag errs = Nothing-  | otherwise       = Just errs-  where-    (_warns, errs) = initL cfg linter-    linter = addLoc TopLevelBindings $-             lintCoreExpr expr--{--************************************************************************-*                                                                      *-\subsection[lintCoreBinding]{lintCoreBinding}-*                                                                      *-************************************************************************--Check a core binding, returning the list of variables bound.--}---- Returns a UsageEnv because this function is called in lintCoreExpr for--- Let--lintRecBindings :: TopLevelFlag -> [(Id, CoreExpr)]-                -> ([LintedId] -> LintM a) -> LintM (a, [UsageEnv])-lintRecBindings top_lvl pairs thing_inside-  = lintIdBndrs top_lvl bndrs $ \ bndrs' ->-    do { ues <- zipWithM lint_pair bndrs' rhss-       ; a <- thing_inside bndrs'-       ; return (a, ues) }-  where-    (bndrs, rhss) = unzip pairs-    lint_pair bndr' rhs-      = addLoc (RhsOf bndr') $-        do { (rhs_ty, ue) <- lintRhs bndr' rhs         -- Check the rhs-           ; lintLetBind top_lvl Recursive bndr' rhs rhs_ty-           ; return ue }--lintLetBody :: LintLocInfo -> [LintedId] -> CoreExpr -> LintM (LintedType, UsageEnv)-lintLetBody loc bndrs body-  = do { (body_ty, body_ue) <- addLoc loc (lintCoreExpr body)-       ; mapM_ (lintJoinBndrType body_ty) bndrs-       ; return (body_ty, body_ue) }--lintLetBind :: TopLevelFlag -> RecFlag -> LintedId-              -> CoreExpr -> LintedType -> LintM ()--- Binder's type, and the RHS, have already been linted--- This function checks other invariants-lintLetBind top_lvl rec_flag binder rhs rhs_ty-  = do { let binder_ty = idType binder-       ; ensureEqTys binder_ty rhs_ty (mkRhsMsg binder (text "RHS") rhs_ty)--       -- If the binding is for a CoVar, the RHS should be (Coercion co)-       -- See Note [Core type and coercion invariant] in GHC.Core-       ; checkL (not (isCoVar binder) || isCoArg rhs)-                (mkLetErr binder rhs)--        -- Check the let-can-float invariant-        -- See Note [Core let-can-float invariant] in GHC.Core-       ; checkL ( isJoinId binder-               || mightBeLiftedType binder_ty-               || (isNonRec rec_flag && exprOkForSpeculation rhs)-               || isDataConWorkId binder || isDataConWrapId binder -- until #17521 is fixed-               || exprIsTickedString rhs)-           (badBndrTyMsg binder (text "unlifted"))--        -- Check that if the binder is at the top level and has type Addr#,-        -- that it is a string literal.-        -- See Note [Core top-level string literals].-       ; checkL (not (isTopLevel top_lvl && binder_ty `eqType` addrPrimTy)-                 || exprIsTickedString rhs)-           (mkTopNonLitStrMsg binder)--       ; flags <- getLintFlags--         -- Check that a join-point binder has a valid type-         -- NB: lintIdBinder has checked that it is not top-level bound-       ; case idJoinPointHood binder of-            NotJoinPoint    -> return ()-            JoinPoint arity ->  checkL (isValidJoinPointType arity binder_ty)-                                       (mkInvalidJoinPointMsg binder binder_ty)--       ; when (lf_check_inline_loop_breakers flags-               && isStableUnfolding (realIdUnfolding binder)-               && isStrongLoopBreaker (idOccInfo binder)-               && isInlinePragma (idInlinePragma binder))-              (addWarnL (text "INLINE binder is (non-rule) loop breaker:" <+> ppr binder))-              -- Only non-rule loop breakers inhibit inlining--       -- We used to check that the dmdTypeDepth of a demand signature never-       -- exceeds idArity, but that is an unnecessary complication, see-       -- Note [idArity varies independently of dmdTypeDepth] in GHC.Core.Opt.DmdAnal--       -- Check that the binder's arity is within the bounds imposed by the type-       -- and the strictness signature. See Note [Arity invariants for bindings]-       -- and Note [Trimming arity]--       ; checkL (typeArity (idType binder) >= idArity binder)-           (text "idArity" <+> ppr (idArity binder) <+>-           text "exceeds typeArity" <+>-           ppr (typeArity (idType binder)) <> colon <+>-           ppr binder)--       -- See Note [idArity varies independently of dmdTypeDepth]-       --     in GHC.Core.Opt.DmdAnal-       ; case splitDmdSig (idDmdSig binder) of-           (demands, result_info) | isDeadEndDiv result_info ->-              if (demands `lengthAtLeast` idArity binder)-              then return ()-              else pprTrace "Hack alert: lintLetBind #24623"-                       (ppr (idArity binder) $$ ppr (idDmdSig binder)) $-                   return ()---             checkL (demands `lengthAtLeast` idArity binder)---               (text "idArity" <+> ppr (idArity binder) <+>---               text "exceeds arity imposed by the strictness signature" <+>---               ppr (idDmdSig binder) <> colon <+>---               ppr binder)--           _ -> return ()--       ; addLoc (RuleOf binder) $ mapM_ (lintCoreRule binder binder_ty) (idCoreRules binder)--       ; addLoc (UnfoldingOf binder) $-         lintIdUnfolding binder binder_ty (idUnfolding binder)-       ; return () }--        -- We should check the unfolding, if any, but this is tricky because-        -- the unfolding is a SimplifiableCoreExpr. Give up for now.---- | Checks the RHS of bindings. It only differs from 'lintCoreExpr'--- in that it doesn't reject occurrences of the function 'makeStatic' when they--- appear at the top level and @lf_check_static_ptrs == AllowAtTopLevel@, and--- for join points, it skips the outer lambdas that take arguments to the--- join point.------ See Note [Checking StaticPtrs].-lintRhs :: Id -> CoreExpr -> LintM (LintedType, UsageEnv)--- NB: the Id can be Linted or not -- it's only used for---     its OccInfo and join-pointer-hood-lintRhs bndr rhs-    | JoinPoint arity <- idJoinPointHood bndr-    = lintJoinLams arity (Just bndr) rhs-    | AlwaysTailCalled arity <- tailCallInfo (idOccInfo bndr)-    = lintJoinLams arity Nothing rhs---- Allow applications of the data constructor @StaticPtr@ at the top--- but produce errors otherwise.-lintRhs _bndr rhs = fmap lf_check_static_ptrs getLintFlags >>= go-  where-    -- Allow occurrences of 'makeStatic' at the top-level but produce errors-    -- otherwise.-    go :: StaticPtrCheck -> LintM (OutType, UsageEnv)-    go AllowAtTopLevel-      | (binders0, rhs') <- collectTyBinders rhs-      , Just (fun, t, info, e) <- collectMakeStaticArgs rhs'-      = markAllJoinsBad $-        foldr-        -- imitate @lintCoreExpr (Lam ...)@-        lintLambda-        -- imitate @lintCoreExpr (App ...)@-        (do fun_ty_ue <- lintCoreExpr fun-            lintCoreArgs fun_ty_ue [Type t, info, e]-        )-        binders0-    go _ = markAllJoinsBad $ lintCoreExpr rhs---- | Lint the RHS of a join point with expected join arity of @n@ (see Note--- [Join points] in "GHC.Core").-lintJoinLams :: JoinArity -> Maybe Id -> CoreExpr -> LintM (LintedType, UsageEnv)-lintJoinLams join_arity enforce rhs-  = go join_arity rhs-  where-    go 0 expr            = lintCoreExpr expr-    go n (Lam var body)  = lintLambda var $ go (n-1) body-    go n expr | Just bndr <- enforce -- Join point with too few RHS lambdas-              = failWithL $ mkBadJoinArityMsg bndr join_arity n rhs-              | otherwise -- Future join point, not yet eta-expanded-              = markAllJoinsBad $ lintCoreExpr expr-                -- Body of lambda is not a tail position--lintIdUnfolding :: Id -> Type -> Unfolding -> LintM ()-lintIdUnfolding bndr bndr_ty uf-  | isStableUnfolding uf-  , Just rhs <- maybeUnfoldingTemplate uf-  = do { ty <- fst <$> (if isCompulsoryUnfolding uf-                        then noFixedRuntimeRepChecks $ lintRhs bndr rhs-            --               ^^^^^^^^^^^^^^^^^^^^^^^-            -- See Note [Checking for representation polymorphism]-                        else lintRhs bndr rhs)-       ; ensureEqTys bndr_ty ty (mkRhsMsg bndr (text "unfolding") ty) }-lintIdUnfolding  _ _ _-  = return ()       -- Do not Lint unstable unfoldings, because that leads-                    -- to exponential behaviour; c.f. GHC.Core.FVs.idUnfoldingVars--{- Note [Checking for INLINE loop breakers]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-It's very suspicious if a strong loop breaker is marked INLINE.--However, the desugarer generates instance methods with INLINE pragmas-that form a mutually recursive group.  Only after a round of-simplification are they unravelled.  So we suppress the test for-the desugarer.  Here is an example:-  instance Eq T where-    t1 == t2 = blah-    t1 /= t2 = not (t1 == t2)-    {-# INLINE (/=) #-}--This will generate something like-    -- From the class decl for Eq-    data Eq a = EqDict (a->a->Bool) (a->a->Bool)-    eq_sel :: Eq a -> (a->a->Bool)-    eq_sel (EqDict eq _) = eq--    -- From the instance Eq T-    $ceq :: T -> T -> Bool-    $ceq = blah--    Rec { $dfEqT :: Eq T {-# DFunId #-}-          $dfEqT = EqDict $ceq $cnoteq--          $cnoteq :: T -> T -> Bool  {-# INLINE #-}-          $cnoteq x y = not (eq_sel $dfEqT x y) }--Notice that--* `$dfEqT` and `$cnotEq` are mutually recursive.--* We do not want `$dfEqT` to be the loop breaker: it's a DFunId, and-  we want to let it "cancel" with "eq_sel" (see Note [ClassOp/DFun-  selection] in GHC.Tc.TyCl.Instance, which it can't do if it's a loop-  breaker.--So we make `$cnoteq` into the loop breaker. That means it can't-inline, despite the INLINE pragma. That's what gives rise to the-warning, which is perfectly appropriate for, say-   Rec { {-# INLINE f #-}  f = \x -> ...f.... }-We can't inline a recursive function -- it's a loop breaker.--But now we can optimise `eq_sel $dfEqT` to `$ceq`, so we get-  Rec {-    $dfEqT :: Eq T {-# DFunId #-}-    $dfEqT = EqDict $ceq $cnoteq--    $cnoteq :: T -> T -> Bool  {-# INLINE #-}-    $cnoteq x y = not ($ceq x y) }--and now the dependencies of the Rec have gone, and we can split it up to give-    NonRec {  $dfEqT :: Eq T {-# DFunId #-}-              $dfEqT = EqDict $ceq $cnoteq }--    NonRec {  $cnoteq :: T -> T -> Bool  {-# INLINE #-}-              $cnoteq x y = not ($ceq x y) }--Now $cnoteq is not a loop breaker any more, so the INLINE pragma can-take effect -- the warning turned out to be temporary.--To stop excessive warnings, this warning for INLINE loop breakers is-switched off when linting the result of the desugarer.  See-lf_check_inline_loop_breakers in GHC.Core.Lint.---Note [Checking for representation polymorphism]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-We ordinarily want to check for bad representation polymorphism. See-Note [Representation polymorphism invariants] in GHC.Core. However, we do *not*-want to do this in a compulsory unfolding. Compulsory unfoldings arise-only internally, for things like newtype wrappers, dictionaries, and-(notably) unsafeCoerce#. These might legitimately be representation-polymorphic;-indeed representation-polymorphic unfoldings are a primary reason for the-very existence of compulsory unfoldings (we can't compile code for-the original, representation-polymorphic, binding).--It is vitally important that we do representation polymorphism checks *after*-performing the unfolding, but not beforehand. This is all safe because-we will check any unfolding after it has been unfolded; checking the-unfolding beforehand is merely an optimization, and one that actively-hurts us here.--Note [Linting of runRW#]-~~~~~~~~~~~~~~~~~~~~~~~~-runRW# has some very special behavior (see Note [runRW magic] in-GHC.CoreToStg.Prep) which CoreLint must accommodate, by allowing-join points in its argument.  For example, this is fine:--    join j x = ...-    in runRW#  (\s. case v of-                       A -> j 3-                       B -> j 4)--Usually those calls to the join point 'j' would not be valid tail calls,-because they occur in a function argument.  But in the case of runRW#-they are fine, because runRW# (\s.e) behaves operationally just like e.-(runRW# is ultimately inlined in GHC.CoreToStg.Prep.)--In the case that the continuation is /not/ a lambda we simply disable this-special behaviour.  For example, this is /not/ fine:--    join j = ...-    in runRW# @r @ty (jump j)--Note [Coercions in terms]-~~~~~~~~~~~~~~~~~~~~~~~~~-The expression (Type ty) can occur only as the argument of an application,-or the RHS of a non-recursive Let.  But what about (Coercion co)?--Currently it appears in ghc-prim:GHC.Types.coercible_sel, a WiredInId whose-definition is:-   coercible_sel :: Coercible a b => (a ~R# b)-   coercible_sel d = case d of-                         MkCoercibleDict (co :: a ~# b) -> Coercion co--So this function has a (Coercion co) in the alternative of a case.--Richard says (!11908): it shouldn't appear outside of arguments, but we've been-loose about this. coercible_sel is some thin ice. Really we should be unpacking-Coercible using case, not a selector. I recall looking into this a few years-back and coming to the conclusion that the fix was worse than the disease. Don't-remember the details, but could probably recover it if we want to revisit.--So Lint current accepts (Coercion co) in arbitrary places.  There is no harm in-that: it really is a value, albeit a zero-bit value.--************************************************************************-*                                                                      *-\subsection[lintCoreExpr]{lintCoreExpr}-*                                                                      *-************************************************************************--}---- Linted things: substitution applied, and type is linted-type LintedType     = Type-type LintedKind     = Kind-type LintedCoercion = Coercion-type LintedTyCoVar  = TyCoVar-type LintedId       = Id---- | Lint an expression cast through the given coercion, returning the type--- resulting from the cast.-lintCastExpr :: CoreExpr -> LintedType -> Coercion -> LintM LintedType-lintCastExpr expr expr_ty co-  = do { co' <- lintCoercion co-       ; let (Pair from_ty to_ty, role) = coercionKindRole co'-       ; checkValueType to_ty $-         text "target of cast" <+> quotes (ppr co')-       ; lintRole co' Representational role-       ; ensureEqTys from_ty expr_ty (mkCastErr expr co' from_ty expr_ty)-       ; return to_ty }--lintCoreExpr :: CoreExpr -> LintM (LintedType, UsageEnv)--- The returned type has the substitution from the monad--- already applied to it:---      lintCoreExpr e subst = exprType (subst e)------ The returned "type" can be a kind, if the expression is (Type ty)---- If you edit this function, you may need to update the GHC formalism--- See Note [GHC Formalism]--lintCoreExpr (Var var)-  = do-      var_pair@(var_ty, _) <- lintIdOcc var 0-      -- See Note [Linting representation-polymorphic builtins]-      checkRepPolyBuiltin (Var var) [] var_ty-      --checkDataToTagPrimOpTyCon (Var var) []-      return var_pair--lintCoreExpr (Lit lit)-  = return (literalType lit, zeroUE)--lintCoreExpr (Cast expr co)-  = do (expr_ty, ue) <- markAllJoinsBad (lintCoreExpr expr)-            -- markAllJoinsBad: see Note [Join points and casts]-       to_ty <- lintCastExpr expr expr_ty co-       return (to_ty, ue)--lintCoreExpr (Tick tickish expr)-  = do case tickish of-         Breakpoint _ _ ids _ -> forM_ ids $ \id -> do-                                   checkDeadIdOcc id-                                   lookupIdInScope id-         _                    -> return ()-       markAllJoinsBadIf block_joins $ lintCoreExpr expr-  where-    block_joins = not (tickish `tickishScopesLike` SoftScope)-      -- TODO Consider whether this is the correct rule. It is consistent with-      -- the simplifier's behaviour - cost-centre-scoped ticks become part of-      -- the continuation, and thus they behave like part of an evaluation-      -- context, but soft-scoped and non-scoped ticks simply wrap the result-      -- (see Simplify.simplTick).--lintCoreExpr (Let (NonRec tv (Type ty)) body)-  | isTyVar tv-  =     -- See Note [Linting type lets]-    do  { ty' <- lintType ty-        ; lintTyBndr tv              $ \ tv' ->-    do  { addLoc (RhsOf tv) $ lintTyKind tv' ty'-                -- Now extend the substitution so we-                -- take advantage of it in the body-        ; extendTvSubstL tv ty'        $-          addLoc (BodyOfLet tv) $-          lintCoreExpr body } }--lintCoreExpr (Let (NonRec bndr rhs) body)-  | isId bndr-  = do { -- First Lint the RHS, before bringing the binder into scope-         (rhs_ty, let_ue) <- lintRhs bndr rhs--          -- See Note [Multiplicity of let binders] in Var-         -- Now lint the binder-       ; lintBinder LetBind bndr $ \bndr' ->-    do { lintLetBind NotTopLevel NonRecursive bndr' rhs rhs_ty-       ; addAliasUE bndr let_ue (lintLetBody (BodyOfLet bndr') [bndr'] body) } }--  | otherwise-  = failWithL (mkLetErr bndr rhs)       -- Not quite accurate--lintCoreExpr e@(Let (Rec pairs) body)-  = do  { -- Check that the list of pairs is non-empty-          checkL (not (null pairs)) (emptyRec e)--          -- Check that there are no duplicated binders-        ; let (_, dups) = removeDups compare bndrs-        ; checkL (null dups) (dupVars dups)--          -- Check that either all the binders are joins, or none-        ; checkL (all isJoinId bndrs || all (not . isJoinId) bndrs) $-          mkInconsistentRecMsg bndrs--          -- See Note [Multiplicity of let binders] in Var-        ; ((body_type, body_ue), ues) <--            lintRecBindings NotTopLevel pairs $ \ bndrs' ->-            lintLetBody (BodyOfLetRec bndrs') bndrs' body-        ; return (body_type, body_ue  `addUE` scaleUE ManyTy (foldr1 addUE ues)) }-  where-    bndrs = map fst pairs--lintCoreExpr e@(App _ _)-  | Var fun <- fun-  , fun `hasKey` runRWKey-    -- N.B. we may have an over-saturated application of the form:-    --   runRW (\s -> \x -> ...) y-  , ty_arg1 : ty_arg2 : arg3 : rest <- args-  = do { fun_pair1      <- lintCoreArg (idType fun, zeroUE) ty_arg1-       ; (fun_ty2, ue2) <- lintCoreArg fun_pair1            ty_arg2-         -- See Note [Linting of runRW#]-       ; let lintRunRWCont :: CoreArg -> LintM (LintedType, UsageEnv)-             lintRunRWCont expr@(Lam _ _) =-                lintJoinLams 1 (Just fun) expr-             lintRunRWCont other = markAllJoinsBad $ lintCoreExpr other-             -- TODO: Look through ticks?-       ; (arg3_ty, ue3) <- lintRunRWCont arg3-       ; app_ty <- lintValApp arg3 fun_ty2 arg3_ty ue2 ue3-       ; lintCoreArgs app_ty rest }--  | otherwise-  = do { fun_pair <- lintCoreFun fun (length args)-       ; app_pair@(app_ty, _) <- lintCoreArgs fun_pair args--       -- See Note [Linting representation-polymorphic builtins]-       ; checkRepPolyBuiltin fun args app_ty-       ; --checkDataToTagPrimOpTyCon fun args--       ; return app_pair}-  where-    skipTick t = case collectFunSimple e of-      (Var v) -> etaExpansionTick v t-      _ -> tickishFloatable t-    (fun, args, _source_ticks) = collectArgsTicks skipTick e-      -- We must look through source ticks to avoid #21152, for example:-      ---      -- reallyUnsafePtrEquality-      --   = \ @a ->-      --       (src<loc> reallyUnsafePtrEquality#)-      --         @Lifted @a @Lifted @a-      ---      -- To do this, we use `collectArgsTicks tickishFloatable` to match-      -- the eta expansion behaviour, as per Note [Eta expansion and source notes]-      -- in GHC.Core.Opt.Arity.-      -- Sadly this was not quite enough. So we now also accept things that CorePrep will allow.-      -- See Note [Ticks and mandatory eta expansion]--lintCoreExpr (Lam var expr)-  = markAllJoinsBad $-    lintLambda var $ lintCoreExpr expr--lintCoreExpr (Case scrut var alt_ty alts)-  = lintCaseExpr scrut var alt_ty alts---- This case can't happen; linting types in expressions gets routed through--- lintCoreArgs-lintCoreExpr (Type ty)-  = failWithL (text "Type found as expression" <+> ppr ty)--lintCoreExpr (Coercion co)-  -- See Note [Coercions in terms]-  = do { co' <- addLoc (InCo co) $-                lintCoercion co-       ; return (coercionType co', zeroUE) }-------------------------lintIdOcc :: Var -> Int -- Number of arguments (type or value) being passed-          -> LintM (LintedType, UsageEnv) -- returns type of the *variable*-lintIdOcc var nargs-  = addLoc (OccOf var) $-    do  { checkL (isNonCoVarId var)-                 (text "Non term variable" <+> ppr var)-                 -- See GHC.Core Note [Variable occurrences in Core]--        -- Check that the type of the occurrence is the same-        -- as the type of the binding site.  The inScopeIds are-        -- /un-substituted/, so this checks that the occurrence type-        -- is identical to the binder type.-        -- This makes things much easier for things like:-        --    /\a. \(x::Maybe a). /\a. ...(x::Maybe a)...-        -- The "::Maybe a" on the occurrence is referring to the /outer/ a.-        -- If we compared /substituted/ types we'd risk comparing-        -- (Maybe a) from the binding site with bogus (Maybe a1) from-        -- the occurrence site.  Comparing un-substituted types finesses-        -- this altogether-        ; (bndr, linted_bndr_ty) <- lookupIdInScope var-        ; let occ_ty  = idType var-              bndr_ty = idType bndr-        ; ensureEqTys occ_ty bndr_ty $-          mkBndrOccTypeMismatchMsg bndr var bndr_ty occ_ty--          -- Check for a nested occurrence of the StaticPtr constructor.-          -- See Note [Checking StaticPtrs].-        ; lf <- getLintFlags-        ; when (nargs /= 0 && lf_check_static_ptrs lf /= AllowAnywhere) $-            checkL (idName var /= makeStaticName) $-              text "Found makeStatic nested in an expression"--        ; checkDeadIdOcc var-        ; checkJoinOcc var nargs-        ; case isDataConId_maybe var of-             Nothing -> return ()-             Just dc -> checkTypeDataConOcc "expression" dc--        ; usage <- varCallSiteUsage var--        ; return (linted_bndr_ty, usage) }--lintCoreFun :: CoreExpr-            -> Int                          -- Number of arguments (type or val) being passed-            -> LintM (LintedType, UsageEnv) -- Returns type of the *function*-lintCoreFun (Var var) nargs-  = lintIdOcc var nargs--lintCoreFun (Lam var body) nargs-  -- Act like lintCoreExpr of Lam, but *don't* call markAllJoinsBad;-  -- See Note [Beta redexes]-  | nargs /= 0-  = lintLambda var $ lintCoreFun body (nargs - 1)--lintCoreFun expr nargs-  = markAllJoinsBadIf (nargs /= 0) $-      -- See Note [Join points are less general than the paper]-    lintCoreExpr expr--------------------lintLambda :: Var -> LintM (Type, UsageEnv) -> LintM (Type, UsageEnv)-lintLambda var lintBody =-    addLoc (LambdaBodyOf var) $-    lintBinder LambdaBind var $ \ var' ->-    do { (body_ty, ue) <- lintBody-       ; ue' <- checkLinearity ue var'-       ; return (mkLamType var' body_ty, ue') }--------------------checkDeadIdOcc :: Id -> LintM ()--- Occurrences of an Id should never be dead....--- except when we are checking a case pattern-checkDeadIdOcc id-  | isDeadOcc (idOccInfo id)-  = do { in_case <- inCasePat-       ; checkL in_case-                (text "Occurrence of a dead Id" <+> ppr id) }-  | otherwise-  = return ()---------------------lintJoinBndrType :: LintedType -- Type of the body-                 -> LintedId   -- Possibly a join Id-                -> LintM ()--- Checks that the return type of a join Id matches the body--- E.g. join j x = rhs in body---      The type of 'rhs' must be the same as the type of 'body'-lintJoinBndrType body_ty bndr-  | JoinPoint arity <- idJoinPointHood bndr-  , let bndr_ty = idType bndr-  , (bndrs, res) <- splitPiTys bndr_ty-  = checkL (length bndrs >= arity-            && body_ty `eqType` mkPiTys (drop arity bndrs) res) $-    hang (text "Join point returns different type than body")-       2 (vcat [ text "Join bndr:" <+> ppr bndr <+> dcolon <+> ppr (idType bndr)-               , text "Join arity:" <+> ppr arity-               , text "Body type:" <+> ppr body_ty ])-  | otherwise-  = return ()--checkJoinOcc :: Id -> JoinArity -> LintM ()--- Check that if the occurrence is a JoinId, then so is the--- binding site, and it's a valid join Id-checkJoinOcc var n_args-  | JoinPoint join_arity_occ <- idJoinPointHood var-  = do { mb_join_arity_bndr <- lookupJoinId var-       ; case mb_join_arity_bndr of {-           NotJoinPoint -> do { join_set <- getValidJoins-                              ; addErrL (text "join set " <+> ppr join_set $$-                                invalidJoinOcc var) } ;--           JoinPoint join_arity_bndr ->--    do { checkL (join_arity_bndr == join_arity_occ) $-           -- Arity differs at binding site and occurrence-         mkJoinBndrOccMismatchMsg var join_arity_bndr join_arity_occ--       ; checkL (n_args == join_arity_occ) $-           -- Arity doesn't match #args-         mkBadJumpMsg var join_arity_occ n_args } } }--  | otherwise-  = return ()--checkTypeDataConOcc :: String -> DataCon -> LintM ()--- Check that the Id is not a data constructor of a `type data` declaration--- Invariant (I1) of Note [Type data declarations] in GHC.Rename.Module-checkTypeDataConOcc what dc-  = checkL (not (isTypeDataTyCon (dataConTyCon dc))) $-    (text "type data constructor found in a" <+> text what <> colon <+> ppr dc)--{---- | Check that a use of a dataToTag# primop satisfies conditions DTT2--- and DTT3 from Note [DataToTag overview] in GHC.Tc.Instance.Class------ Ignores applications not headed by dataToTag# primops.---- Commented out because GHC.PrimopWrappers doesn't respect this condition yet.--- See wrinkle DTW7 in Note [DataToTag overview].-checkDataToTagPrimOpTyCon-  :: CoreExpr   -- ^ the function (head of the application) we are checking-  -> [CoreArg]  -- ^ The arguments to the application-  -> LintM ()-checkDataToTagPrimOpTyCon (Var fun_id) args-  | Just op <- isPrimOpId_maybe fun_id-  , op == DataToTagSmallOp || op == DataToTagLargeOp-  = case args of-      Type _levity : Type dty : _rest-        | Just (tc, _) <- splitTyConApp_maybe dty-        , isValidDTT2TyCon tc-          -> do  platform <- getPlatform-                 let  numConstrs = tyConFamilySize tc-                      isSmallOp = op == DataToTagSmallOp-                 checkL (isSmallFamily platform numConstrs == isSmallOp) $-                   text "dataToTag# primop-size/tycon-family-size mismatch"-        | otherwise -> failWithL $ text "dataToTagLarge# used at non-ADT type:"-                                   <+> ppr dty-      _ -> failWithL $ text "dataToTagLarge# needs two type arguments but has args:"-                       <+> ppr (take 2 args)--checkDataToTagPrimOpTyCon _ _ = pure ()--}---- | Check representation-polymorphic invariants in an application of a--- built-in function or newtype constructor.------ See Note [Linting representation-polymorphic builtins].-checkRepPolyBuiltin :: CoreExpr   -- ^ the function (head of the application) we are checking-                    -> [CoreArg]  -- ^ the arguments to the application-                    -> LintedType -- ^ the instantiated type of the overall application-                    -> LintM ()-checkRepPolyBuiltin (Var fun_id) args app_ty-  = do { do_rep_poly_checks <- lf_check_fixed_rep <$> getLintFlags-       ; when (do_rep_poly_checks && hasNoBinding fun_id) $-           if-             -- (2) representation-polymorphic unlifted newtypes-             | Just dc <- isDataConId_maybe fun_id-             , isNewDataCon dc-             -> if tcHasFixedRuntimeRep $ dataConTyCon dc-                then return ()-                else checkRepPolyNewtypeApp dc args app_ty--             -- (1) representation-polymorphic builtins-             | otherwise-             -> checkRepPolyBuiltinApp fun_id args-       }-checkRepPolyBuiltin _ _ _ = return ()--checkRepPolyNewtypeApp :: DataCon -> [CoreArg] -> LintedType -> LintM ()-checkRepPolyNewtypeApp nt args app_ty-  -- If the newtype is saturated, we're OK.-  | any isValArg args-  = return ()-  -- Otherwise, check we can eta-expand.-  | otherwise-  = case getRuntimeArgTys app_ty of-      (Scaled _ first_val_arg_ty, _):_-        | not $ typeHasFixedRuntimeRep first_val_arg_ty-        -> failWithL (err_msg first_val_arg_ty)-      _ -> return ()--  where--      err_msg :: Type -> SDoc-      err_msg bad_arg_ty-        = vcat [ text "Cannot eta expand unlifted newtype constructor" <+> quotes (ppr nt) <> dot-               , text "Its argument type does not have a fixed runtime representation:"-               , nest 2 $ ppr_ty_ki bad_arg_ty ]--      ppr_ty_ki :: Type -> SDoc-      ppr_ty_ki ty = bullet <+> ppr ty <+> dcolon <+> ppr (typeKind ty)--checkRepPolyBuiltinApp :: Id -> [CoreArg] -> LintM ()-checkRepPolyBuiltinApp fun_id args = checkL (null not_concs) err_msg-  where--    conc_binder_positions :: IntMap ConcreteTvOrigin-    conc_binder_positions-      = concreteTyVarPositions fun_id-      $ idDetailsConcreteTvs-      $ idDetails fun_id--    max_pos :: Int-    max_pos =-      case IntMap.keys conc_binder_positions of-        [] -> 0-        positions -> maximum positions--    not_concs :: [(SDoc, ConcreteTvOrigin)]-    not_concs =-      mapMaybe is_bad (zip [1..max_pos] (map Just args ++ repeat Nothing))-        -- NB: 1-indexed--    is_bad :: (Int, Maybe CoreArg) -> Maybe (SDoc, ConcreteTvOrigin)-    is_bad (pos, mb_arg)-      | Just conc_reason <- IntMap.lookup pos conc_binder_positions-      , Just bad_ty <- case mb_arg of-          Just (Type ki)-            | isConcreteType ki-            -> Nothing-            | otherwise-            -- Here we handle the situation in which a "must be concrete" TyVar-            -- has been instantiated with a type that is not concrete.-            -> Just $ quotes (ppr ki) <+> text "is not concrete."-          -- We expected a type argument in this position, and got something else: panic!-          Just arg ->-            pprPanic "checkRepPolyBuiltinApp: expected a type in this position" $-              vcat [ text "fun_id:" <+> ppr fun_id <+> dcolon <+> ppr (idType fun_id)-                   , text "pos:" <+> ppr pos-                   , text "arg:" <+> ppr arg ]-          Nothing ->-            -- Here we handle the situation in which a "must be concrete" TyVar-            -- has not been instantiated at all.-            case conc_reason of-              ConcreteFRR frr_orig ->-                let ty = frr_type frr_orig-                in  Just $ ppr ty <+> dcolon <+> ppr (typeKind ty)-      = Just (bad_ty, conc_reason)-      | otherwise-      = Nothing--    err_msg :: SDoc-    err_msg-      = vcat $ map ((bullet <+>) . ppr_not_conc) not_concs--    ppr_not_conc :: (SDoc, ConcreteTvOrigin) -> SDoc-    ppr_not_conc (bad_ty, conc) =-      vcat-       [ ppr_conc_orig conc-       , nest 2 bad_ty ]--    ppr_conc_orig :: ConcreteTvOrigin -> SDoc-    ppr_conc_orig (ConcreteFRR frr_orig) =-      case frr_orig of-        FixedRuntimeRepOrigin { frr_context = ctxt } ->-          hsep [ ppr ctxt, text "does not have a fixed runtime representation:" ]---- | Compute the 1-indexed positions in the outer forall'd quantified type variables--- of the type in which the concrete type variables occur.------ See Note [Representation-polymorphism checking built-ins] in GHC.Tc.Utils.Concrete.-concreteTyVarPositions :: Id -> ConcreteTyVars -> IntMap ConcreteTvOrigin-concreteTyVarPositions fun_id conc_tvs-  | isNullUFM conc_tvs-  = IntMap.empty-  | otherwise-  = case splitForAllTyCoVars (idType fun_id) of-    ([], _)  -> IntMap.empty-    (tvs, _) ->-      let positions =-            IntMap.fromList-              [ (pos, conc_orig)-              | (tv, pos) <- zip tvs [1..]-              , conc_orig <- maybeToList $ lookupNameEnv conc_tvs (tyVarName tv)-              ]-         -- Assert that we have as many positions as concrete type variables,-         -- i.e. we are not missing any concreteness information.-      in assertPpr (sizeUFM conc_tvs == length positions)-           (vcat [ text "concreteTyVarPositions: missing concreteness information"-                 , text "fun_id:" <+> ppr fun_id-                 , text "tvs:" <+> ppr tvs-                 , text "Expected # of concrete tvs:" <+> ppr (sizeUFM conc_tvs)-                 , text "  Actual # of concrete tvs:" <+> ppr (length positions) ])-           positions---- Check that the usage of var is consistent with var itself, and pop the var--- from the usage environment (this is important because of shadowing).-checkLinearity :: UsageEnv -> Var -> LintM UsageEnv-checkLinearity body_ue lam_var =-  case varMultMaybe lam_var of-    Just mult -> do-      let (lhs, body_ue') = popUE body_ue lam_var-          err_msg = text "Linearity failure in lambda:" <+> ppr lam_var-                    $$ ppr lhs <+> text "⊈" <+> ppr mult-      ensureSubUsage lhs mult err_msg-      return body_ue'-    Nothing    -> return body_ue -- A type variable--{- Note [Join points and casts]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-You might think that this should be OK:-   join j x = rhs-   in (case e of-          A   -> alt1-          B x -> (jump j x) |> co)--You might think that, since the cast is ultimately erased, the jump to-`j` should still be OK as a join point.  But no!  See #21716. Suppose--  newtype Age = MkAge Int   -- axAge :: Age ~ Int-  f :: Int -> ...           -- f strict in it's first argument--and consider the expression--  f (join j :: Bool -> Age-          j x = (rhs1 :: Age)-     in case v of-         Just x  -> (j x |> axAge :: Int)-         Nothing -> rhs2)--Then, if the Simplifier pushes the strict call into the join points-and alternatives we'll get--   join j' x = f (rhs1 :: Age)-   in case v of-      Just x  -> j' x |> axAge-      Nothing -> f rhs2--Utterly bogus.  `f` expects an `Int` and we are giving it an `Age`.-No no no.  Casts destroy the tail-call property.  Henc markAllJoinsBad-in the (Cast expr co) case of lintCoreExpr.--Note [No alternatives lint check]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-Case expressions with no alternatives are odd beasts, and it would seem-like they would worth be looking at in the linter (cf #10180). We-used to check two things:--* exprIsHNF is false: it would *seem* to be terribly wrong if-  the scrutinee was already in head normal form.--* exprIsDeadEnd is true: we should be able to see why GHC believes the-  scrutinee is diverging for sure.--It was already known that the second test was not entirely reliable.-Unfortunately (#13990), the first test turned out not to be reliable-either. Getting the checks right turns out to be somewhat complicated.--For example, suppose we have (comment 8)--  data T a where-    TInt :: T Int--  absurdTBool :: T Bool -> a-  absurdTBool v = case v of--  data Foo = Foo !(T Bool)--  absurdFoo :: Foo -> a-  absurdFoo (Foo x) = absurdTBool x--GHC initially accepts the empty case because of the GADT conditions. But then-we inline absurdTBool, getting--  absurdFoo (Foo x) = case x of--x is in normal form (because the Foo constructor is strict) but the-case is empty. To avoid this problem, GHC would have to recognize-that matching on Foo x is already absurd, which is not so easy.--More generally, we don't really know all the ways that GHC can-lose track of why an expression is bottom, so we shouldn't make too-much fuss when that happens.---Note [Beta redexes]-~~~~~~~~~~~~~~~~~~~-Consider:--  join j @x y z = ... in-  (\@x y z -> jump j @x y z) @t e1 e2--This is clearly ill-typed, since the jump is inside both an application and a-lambda, either of which is enough to disqualify it as a tail call (see Note-[Invariants on join points] in GHC.Core). However, strictly from a-lambda-calculus perspective, the term doesn't go wrong---after the two beta-reductions, the jump *is* a tail call and everything is fine.--Why would we want to allow this when we have let? One reason is that a compound-beta redex (that is, one with more than one argument) has different scoping-rules: naively reducing the above example using lets will capture any free-occurrence of y in e2. More fundamentally, type lets are tricky; many passes,-such as Float Out, tacitly assume that the incoming program's type lets have-all been dealt with by the simplifier. Thus we don't want to let-bind any types-in, say, GHC.Core.Subst.simpleOptPgm, which in some circumstances can run immediately-before Float Out.--All that said, currently GHC.Core.Subst.simpleOptPgm is the only thing using this-loophole, doing so to avoid re-traversing large functions (beta-reducing a type-lambda without introducing a type let requires a substitution). TODO: Improve-simpleOptPgm so that we can forget all this ever happened.--************************************************************************-*                                                                      *-\subsection[lintCoreArgs]{lintCoreArgs}-*                                                                      *-************************************************************************--The basic version of these functions checks that the argument is a-subtype of the required type, as one would expect.--}---- Takes the functions type and arguments as argument.--- Returns the *result* of applying the function to arguments.--- e.g. f :: Int -> Bool -> Int would return `Int` as result type.-lintCoreArgs  :: (LintedType, UsageEnv) -> [CoreArg] -> LintM (LintedType, UsageEnv)-lintCoreArgs (fun_ty, fun_ue) args = foldM lintCoreArg (fun_ty, fun_ue) args--lintCoreArg  :: (LintedType, UsageEnv) -> CoreArg -> LintM (LintedType, UsageEnv)---- Type argument-lintCoreArg (fun_ty, ue) (Type arg_ty)-  = do { checkL (not (isCoercionTy arg_ty))-                (text "Unnecessary coercion-to-type injection:"-                  <+> ppr arg_ty)-       ; arg_ty' <- lintType arg_ty-       ; res <- lintTyApp fun_ty arg_ty'-       ; return (res, ue) }---- Coercion argument-lintCoreArg (fun_ty, ue) (Coercion co)-  = do { co' <- addLoc (InCo co) $-                lintCoercion co-       ; res <- lintCoApp fun_ty co'-       ; return (res, ue) }---- Other value argument-lintCoreArg (fun_ty, fun_ue) arg-  = do { (arg_ty, arg_ue) <- markAllJoinsBad $ lintCoreExpr arg-           -- See Note [Representation polymorphism invariants] in GHC.Core-       ; flags <- getLintFlags--       ; when (lf_check_fixed_rep flags) $-         -- Only check that 'arg_ty' has a fixed RuntimeRep-         -- if 'lf_check_fixed_rep' is on.-         do { checkL (typeHasFixedRuntimeRep arg_ty)-                     (text "Argument does not have a fixed runtime representation"-                      <+> ppr arg <+> dcolon-                      <+> parens (ppr arg_ty <+> dcolon <+> ppr (typeKind arg_ty))) }--       ; lintValApp arg fun_ty arg_ty fun_ue arg_ue }--------------------lintAltBinders :: UsageEnv-               -> Var         -- Case binder-               -> LintedType     -- Scrutinee type-               -> LintedType     -- Constructor type-               -> [(Mult, OutVar)]    -- Binders-               -> LintM UsageEnv--- If you edit this function, you may need to update the GHC formalism--- See Note [GHC Formalism]-lintAltBinders rhs_ue _case_bndr scrut_ty con_ty []-  = do { ensureEqTys con_ty scrut_ty (mkBadPatMsg con_ty scrut_ty)-       ; return rhs_ue }-lintAltBinders rhs_ue case_bndr scrut_ty con_ty ((var_w, bndr):bndrs)-  | isTyVar bndr-  = do { con_ty' <- lintTyApp con_ty (mkTyVarTy bndr)-       ; lintAltBinders rhs_ue case_bndr scrut_ty con_ty'  bndrs }-  | otherwise-  = do { (con_ty', _) <- lintValApp (Var bndr) con_ty (idType bndr) zeroUE zeroUE-         -- We can pass zeroUE to lintValApp because we ignore its usage-         -- calculation and compute it in the call for checkCaseLinearity below.-       ; rhs_ue' <- checkCaseLinearity rhs_ue case_bndr var_w bndr-       ; lintAltBinders rhs_ue' case_bndr scrut_ty con_ty' bndrs }---- | Implements the case rules for linearity-checkCaseLinearity :: UsageEnv -> Var -> Mult -> Var -> LintM UsageEnv-checkCaseLinearity ue case_bndr var_w bndr = do-  ensureSubUsage lhs rhs err_msg-  lintLinearBinder (ppr bndr) (case_bndr_w `mkMultMul` var_w) (varMult bndr)-  return $ deleteUE ue bndr-  where-    lhs = bndr_usage `addUsage` (var_w `scaleUsage` case_bndr_usage)-    rhs = case_bndr_w `mkMultMul` var_w-    err_msg  = (text "Linearity failure in variable:" <+> ppr bndr-                $$ ppr lhs <+> text "⊈" <+> ppr rhs-                $$ text "Computed by:"-                <+> text "LHS:" <+> lhs_formula-                <+> text "RHS:" <+> rhs_formula)-    lhs_formula = ppr bndr_usage <+> text "+"-                                 <+> parens (ppr case_bndr_usage <+> text "*" <+> ppr var_w)-    rhs_formula = ppr case_bndr_w <+> text "*" <+> ppr var_w-    case_bndr_w = varMult case_bndr-    case_bndr_usage = lookupUE ue case_bndr-    bndr_usage = lookupUE ue bndr----------------------lintTyApp :: LintedType -> LintedType -> LintM LintedType-lintTyApp fun_ty arg_ty-  | Just (tv,body_ty) <- splitForAllTyVar_maybe fun_ty-  = do  { lintTyKind tv arg_ty-        ; in_scope <- getInScope-        -- substTy needs the set of tyvars in scope to avoid generating-        -- uniques that are already in scope.-        -- See Note [The substitution invariant] in GHC.Core.TyCo.Subst-        ; return (substTyWithInScope in_scope [tv] [arg_ty] body_ty) }--  | otherwise-  = failWithL (mkTyAppMsg fun_ty arg_ty)--------------------lintCoApp :: LintedType -> LintedCoercion -> LintM LintedType-lintCoApp fun_ty co-  | Just (cv,body_ty) <- splitForAllCoVar_maybe fun_ty-  , let co_ty = coercionType co-        cv_ty = idType cv-  , cv_ty `eqType` co_ty-  = do { in_scope <- getInScope-       ; let init_subst = mkEmptySubst in_scope-             subst = extendCvSubst init_subst cv co-       ; return (substTy subst body_ty) }--  | Just (_, _, arg_ty', res_ty') <- splitFunTy_maybe fun_ty-  , co_ty `eqType` arg_ty'-  = return (res_ty')--  | otherwise-  = failWithL (mkCoAppMsg fun_ty co)--  where-    co_ty = coercionType co----------------------- | @lintValApp arg fun_ty arg_ty@ lints an application of @fun arg@--- where @fun :: fun_ty@ and @arg :: arg_ty@, returning the type of the--- application.-lintValApp :: CoreExpr -> LintedType -> LintedType -> UsageEnv -> UsageEnv-           -> LintM (LintedType, UsageEnv)-lintValApp arg fun_ty arg_ty fun_ue arg_ue-  | Just (_, w, arg_ty', res_ty') <- splitFunTy_maybe fun_ty-  = do { ensureEqTys arg_ty' arg_ty (mkAppMsg arg_ty' arg_ty arg)-       ; let app_ue =  addUE fun_ue (scaleUE w arg_ue)-       ; return (res_ty', app_ue) }-  | otherwise-  = failWithL err2-  where-    err2 = mkNonFunAppMsg fun_ty arg_ty arg--lintTyKind :: OutTyVar -> LintedType -> LintM ()--- Both args have had substitution applied---- If you edit this function, you may need to update the GHC formalism--- See Note [GHC Formalism]-lintTyKind tyvar arg_ty-  = unless (arg_kind `eqType` tyvar_kind) $-    addErrL (mkKindErrMsg tyvar arg_ty $$ (text "Linted Arg kind:" <+> ppr arg_kind))-  where-    tyvar_kind = tyVarKind tyvar-    arg_kind = typeKind arg_ty--{--************************************************************************-*                                                                      *-\subsection[lintCoreAlts]{lintCoreAlts}-*                                                                      *-************************************************************************--}--lintCaseExpr :: CoreExpr -> Id -> Type -> [CoreAlt] -> LintM (LintedType, UsageEnv)-lintCaseExpr scrut var alt_ty alts =-  do { let e = Case scrut var alt_ty alts   -- Just for error messages--     -- Check the scrutinee-     ; (scrut_ty, scrut_ue) <- markAllJoinsBad $ lintCoreExpr scrut-          -- See Note [Join points are less general than the paper]-          -- in GHC.Core-     ; let scrut_mult = varMult var--     ; alt_ty <- addLoc (CaseTy scrut) $-                 lintValueType alt_ty-     ; var_ty <- addLoc (IdTy var) $-                 lintValueType (idType var)--     -- We used to try to check whether a case expression with no-     -- alternatives was legitimate, but this didn't work.-     -- See Note [No alternatives lint check] for details.--     -- Check that the scrutinee is not a floating-point type-     -- if there are any literal alternatives-     -- See GHC.Core Note [Case expression invariants] item (5)-     -- See Note [Rules for floating-point comparisons] in GHC.Core.Opt.ConstantFold-     ; let isLitPat (Alt (LitAlt _) _  _) = True-           isLitPat _                     = False-     ; checkL (not $ isFloatingPrimTy scrut_ty && any isLitPat alts)-         (text "Lint warning: Scrutinising floating-point expression with literal pattern in case analysis (see #9238)."-          $$ text "scrut" <+> ppr scrut)--     ; case tyConAppTyCon_maybe (idType var) of-         Just tycon-              | debugIsOn-              , isAlgTyCon tycon-              , not (isAbstractTyCon tycon)-              , null (tyConDataCons tycon)-              , not (exprIsDeadEnd scrut)-              -> pprTrace "Lint warning: case binder's type has no constructors" (ppr var <+> ppr (idType var))-                        -- This can legitimately happen for type families-                      $ return ()-         _otherwise -> return ()--        -- Don't use lintIdBndr on var, because unboxed tuple is legitimate--     ; subst <- getSubst-     ; ensureEqTys var_ty scrut_ty (mkScrutMsg var var_ty scrut_ty subst)-       -- See GHC.Core Note [Case expression invariants] item (7)--     ; lintBinder CaseBind var $ \_ ->-       do { -- Check the alternatives-          ; alt_ues <- mapM (lintCoreAlt var scrut_ty scrut_mult alt_ty) alts-          ; let case_ue = (scaleUE scrut_mult scrut_ue) `addUE` supUEs alt_ues-          ; checkCaseAlts e scrut_ty alts-          ; return (alt_ty, case_ue) } }--checkCaseAlts :: CoreExpr -> LintedType -> [CoreAlt] -> LintM ()--- a) Check that the alts are non-empty--- b1) Check that the DEFAULT comes first, if it exists--- b2) Check that the others are in increasing order--- c) Check that there's a default for infinite types--- NB: Algebraic cases are not necessarily exhaustive, because---     the simplifier correctly eliminates case that can't---     possibly match.--checkCaseAlts e ty alts =-  do { checkL (all non_deflt con_alts) (mkNonDefltMsg e)-         -- See GHC.Core Note [Case expression invariants] item (2)--     ; checkL (increasing_tag con_alts) (mkNonIncreasingAltsMsg e)-         -- See GHC.Core Note [Case expression invariants] item (3)--          -- For types Int#, Word# with an infinite (well, large!) number of-          -- possible values, there should usually be a DEFAULT case-          -- But (see Note [Empty case alternatives] in GHC.Core) it's ok to-          -- have *no* case alternatives.-          -- In effect, this is a kind of partial test. I suppose it's possible-          -- that we might *know* that 'x' was 1 or 2, in which case-          --   case x of { 1 -> e1; 2 -> e2 }-          -- would be fine.-     ; checkL (isJust maybe_deflt || not is_infinite_ty || null alts)-              (nonExhaustiveAltsMsg e) }-  where-    (con_alts, maybe_deflt) = findDefault alts--        -- Check that successive alternatives have strictly increasing tags-    increasing_tag (alt1 : rest@( alt2 : _)) = alt1 `ltAlt` alt2 && increasing_tag rest-    increasing_tag _                         = True--    non_deflt (Alt DEFAULT _ _) = False-    non_deflt _                 = True--    is_infinite_ty = case tyConAppTyCon_maybe ty of-                        Nothing    -> False-                        Just tycon -> isPrimTyCon tycon--lintAltExpr :: CoreExpr -> LintedType -> LintM UsageEnv-lintAltExpr expr ann_ty-  = do { (actual_ty, ue) <- lintCoreExpr expr-       ; ensureEqTys actual_ty ann_ty (mkCaseAltMsg expr actual_ty ann_ty)-       ; return ue }-         -- See GHC.Core Note [Case expression invariants] item (6)--lintCoreAlt :: Var              -- Case binder-            -> LintedType       -- Type of scrutinee-            -> Mult             -- Multiplicity of scrutinee-            -> LintedType       -- Type of the alternative-            -> CoreAlt-            -> LintM UsageEnv--- If you edit this function, you may need to update the GHC formalism--- See Note [GHC Formalism]-lintCoreAlt case_bndr _ scrut_mult alt_ty (Alt DEFAULT args rhs) =-  do { lintL (null args) (mkDefaultArgsMsg args)-     ; rhs_ue <- lintAltExpr rhs alt_ty-     ; let (case_bndr_usage, rhs_ue') = popUE rhs_ue case_bndr-           err_msg = text "Linearity failure in the DEFAULT clause:" <+> ppr case_bndr-                     $$ ppr case_bndr_usage <+> text "⊈" <+> ppr scrut_mult-     ; ensureSubUsage case_bndr_usage scrut_mult err_msg-     ; return rhs_ue' }--lintCoreAlt case_bndr scrut_ty _ alt_ty (Alt (LitAlt lit) args rhs)-  | litIsLifted lit-  = failWithL integerScrutinisedMsg-  | otherwise-  = do { lintL (null args) (mkDefaultArgsMsg args)-       ; ensureEqTys lit_ty scrut_ty (mkBadPatMsg lit_ty scrut_ty)-       ; rhs_ue <- lintAltExpr rhs alt_ty-       ; return (deleteUE rhs_ue case_bndr) -- No need for linearity checks-       }-  where-    lit_ty = literalType lit--lintCoreAlt case_bndr scrut_ty _scrut_mult alt_ty alt@(Alt (DataAlt con) args rhs)-  | isNewTyCon (dataConTyCon con)-  = zeroUE <$ addErrL (mkNewTyDataConAltMsg scrut_ty alt)-  | Just (tycon, tycon_arg_tys) <- splitTyConApp_maybe scrut_ty-  = addLoc (CaseAlt alt) $  do-    { checkTypeDataConOcc "pattern" con-    ; lintL (tycon == dataConTyCon con) (mkBadConMsg tycon con)--      -- Instantiate the universally quantified-      -- type variables of the data constructor-    ; let { con_payload_ty = piResultTys (dataConRepType con) tycon_arg_tys-          ; binderMult (Named _)   = ManyTy-          ; binderMult (Anon st _) = scaledMult st-          -- See Note [Validating multiplicities in a case]-          ; multiplicities = map binderMult $ fst $ splitPiTys con_payload_ty }--        -- And now bring the new binders into scope-    ; lintBinders CasePatBind args $ \ args' -> do-      {-        rhs_ue <- lintAltExpr rhs alt_ty-      ; rhs_ue' <- addLoc (CasePat alt) (lintAltBinders rhs_ue case_bndr scrut_ty con_payload_ty (zipEqual "lintCoreAlt" multiplicities  args'))-      ; return $ deleteUE rhs_ue' case_bndr-      }-   }--  | otherwise   -- Scrut-ty is wrong shape-  = zeroUE <$ addErrL (mkBadAltMsg scrut_ty alt)--{--Note [Validating multiplicities in a case]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-Suppose 'MkT :: a %m -> T m a'.-If we are validating 'case (x :: T Many a) of MkT y -> ...',-we have to substitute m := Many in the type of MkT - in particular,-y can be used Many times and that expression would still be linear in x.-We do this by looking at con_payload_ty, which is the type of the datacon-applied to the surrounding arguments.-Testcase: linear/should_compile/MultConstructor--Data constructors containing existential tyvars will then have-Named binders, which are always multiplicity Many.-Testcase: indexed-types/should_compile/GADT1--}--lintLinearBinder :: SDoc -> Mult -> Mult -> LintM ()-lintLinearBinder doc actual_usage described_usage-  = ensureSubMult actual_usage described_usage err_msg-    where-      err_msg = (text "Multiplicity of variable does not agree with its context"-                $$ doc-                $$ ppr actual_usage-                $$ text "Annotation:" <+> ppr described_usage)--{--************************************************************************-*                                                                      *-\subsection[lint-types]{Types}-*                                                                      *-************************************************************************--}---- When we lint binders, we (one at a time and in order):---  1. Lint var types or kinds (possibly substituting)---  2. Add the binder to the in scope set, and if its a coercion var,---     we may extend the substitution to reflect its (possibly) new kind-lintBinders :: BindingSite -> [Var] -> ([Var] -> LintM a) -> LintM a-lintBinders _    []         linterF = linterF []-lintBinders site (var:vars) linterF = lintBinder site var $ \var' ->-                                      lintBinders site vars $ \ vars' ->-                                      linterF (var':vars')---- If you edit this function, you may need to update the GHC formalism--- See Note [GHC Formalism]-lintBinder :: BindingSite -> Var -> (Var -> LintM a) -> LintM a-lintBinder site var linterF-  | isTyCoVar var = lintTyCoBndr var linterF-  | otherwise     = lintIdBndr NotTopLevel site var linterF--lintTyBndr :: TyVar -> (LintedTyCoVar -> LintM a) -> LintM a-lintTyBndr = lintTyCoBndr  -- We could specialise it, I guess--lintTyCoBndr :: TyCoVar -> (LintedTyCoVar -> LintM a) -> LintM a-lintTyCoBndr tcv thing_inside-  = do { subst <- getSubst-       ; tcv_type' <- lintType (varType tcv)-       ; let tcv' = uniqAway (getSubstInScope subst) $-                    setVarType tcv tcv_type'-             subst' = extendTCvSubstWithClone subst tcv tcv'--       -- See (FORALL1) and (FORALL2) in GHC.Core.Type-       ; if (isTyVar tcv)-         then -- Check that in (forall (a:ki). blah) we have ki:Type-              lintL (isLiftedTypeKind (typeKind tcv_type')) $-              hang (text "TyVar whose kind does not have kind Type:")-                 2 (ppr tcv' <+> dcolon <+> ppr tcv_type' <+> dcolon <+> ppr (typeKind tcv_type'))-         else -- Check that in (forall (cv::ty). blah),-              -- then ty looks like (t1 ~# t2)-              lintL (isCoVarType tcv_type') $-              text "CoVar with non-coercion type:" <+> pprTyVar tcv--       ; updateSubst subst' (thing_inside tcv') }--lintIdBndrs :: forall a. TopLevelFlag -> [Id] -> ([LintedId] -> LintM a) -> LintM a-lintIdBndrs top_lvl ids thing_inside-  = go ids thing_inside-  where-    go :: [Id] -> ([Id] -> LintM a) -> LintM a-    go []       thing_inside = thing_inside []-    go (id:ids) thing_inside = lintIdBndr top_lvl LetBind id  $ \id' ->-                               go ids                         $ \ids' ->-                               thing_inside (id' : ids')--lintIdBndr :: TopLevelFlag -> BindingSite-           -> InVar -> (OutVar -> LintM a) -> LintM a--- Do substitution on the type of a binder and add the var with this--- new type to the in-scope set of the second argument--- ToDo: lint its rules-lintIdBndr top_lvl bind_site id thing_inside-  = assertPpr (isId id) (ppr id) $-    do { flags <- getLintFlags-       ; checkL (not (lf_check_global_ids flags) || isLocalId id)-                (text "Non-local Id binder" <+> ppr id)-                -- See Note [Checking for global Ids]--       -- Check that if the binder is nested, it is not marked as exported-       ; checkL (not (isExportedId id) || is_top_lvl)-           (mkNonTopExportedMsg id)--       -- Check that if the binder is nested, it does not have an external name-       ; checkL (not (isExternalName (Var.varName id)) || is_top_lvl)-           (mkNonTopExternalNameMsg id)--          -- See Note [Representation polymorphism invariants] in GHC.Core-       ; lintL (isJoinId id || not (lf_check_fixed_rep flags)-                || typeHasFixedRuntimeRep id_ty) $-         text "Binder does not have a fixed runtime representation:" <+> ppr id <+> dcolon <+>-            parens (ppr id_ty <+> dcolon <+> ppr (typeKind id_ty))--       -- Check that a join-id is a not-top-level let-binding-       ; when (isJoinId id) $-         checkL (not is_top_lvl && is_let_bind) $-         mkBadJoinBindMsg id--       -- Check that the Id does not have type (t1 ~# t2) or (t1 ~R# t2);-       -- if so, it should be a CoVar, and checked by lintCoVarBndr-       ; lintL (not (isCoVarType id_ty))-               (text "Non-CoVar has coercion type" <+> ppr id <+> dcolon <+> ppr id_ty)--       -- Check that the lambda binder has no value or OtherCon unfolding.-       -- See #21496-       ; lintL (not (bind_site == LambdaBind && isEvaldUnfolding (idUnfolding id)))-                (text "Lambda binder with value or OtherCon unfolding.")--       ; linted_ty <- addLoc (IdTy id) (lintValueType id_ty)--       ; addInScopeId id linted_ty $-         thing_inside (setIdType id linted_ty) }-  where-    id_ty = idType id--    is_top_lvl = isTopLevel top_lvl-    is_let_bind = case bind_site of-                    LetBind -> True-                    _       -> False--{--%************************************************************************-%*                                                                      *-             Types-%*                                                                      *-%************************************************************************--}--lintValueType :: Type -> LintM LintedType--- Types only, not kinds--- Check the type, and apply the substitution to it--- See Note [Linting type lets]-lintValueType ty-  = addLoc (InType ty) $-    do  { ty' <- lintType ty-        ; let sk = typeKind ty'-        ; lintL (isTYPEorCONSTRAINT sk) $-          hang (text "Ill-kinded type:" <+> ppr ty)-             2 (text "has kind:" <+> ppr sk)-        ; return ty' }--checkTyCon :: TyCon -> LintM ()-checkTyCon tc-  = checkL (not (isTcTyCon tc)) (text "Found TcTyCon:" <+> ppr tc)----------------------checkTyCoVarInScope :: Subst -> TyCoVar -> LintM ()-checkTyCoVarInScope subst tcv-  = checkL (tcv `isInScope` subst) $-    hang (text "The type or coercion variable" <+> pprBndr LetBind tcv)-       2 (text "is out of scope")----------------------lintType :: Type -> LintM LintedType---- If you edit this function, you may need to update the GHC formalism--- See Note [GHC Formalism]-lintType (TyVarTy tv)-  | not (isTyVar tv)-  = failWithL (mkBadTyVarMsg tv)--  | otherwise-  = do { subst <- getSubst-       ; case lookupTyVar subst tv of-           Just linted_ty -> return linted_ty--           -- In GHCi we may lint an expression with a free-           -- type variable.  Then it won't be in the-           -- substitution, but it should be in scope-           Nothing -> do { checkTyCoVarInScope subst tv-                         ; return (TyVarTy tv) }-     }--lintType ty@(AppTy t1 t2)-  | TyConApp {} <- t1-  = failWithL $ text "TyConApp to the left of AppTy:" <+> ppr ty-  | otherwise-  = do { t1' <- lintType t1-       ; t2' <- lintType t2-       ; lint_ty_app ty (typeKind t1') [t2']-       ; return (AppTy t1' t2') }--lintType ty@(TyConApp tc tys)-  | isTypeSynonymTyCon tc || isTypeFamilyTyCon tc-  = do { report_unsat <- lf_report_unsat_syns <$> getLintFlags-       ; lintTySynFamApp report_unsat ty tc tys }--  | Just {} <- tyConAppFunTy_maybe tc tys-    -- We should never see a saturated application of funTyCon; such-    -- applications should be represented with the FunTy constructor.-    -- See Note [Linting function types]-  = failWithL (hang (text "Saturated application of" <+> quotes (ppr tc)) 2 (ppr ty))--  | otherwise  -- Data types, data families, primitive types-  = do { checkTyCon tc-       ; tys' <- mapM lintType tys-       ; lint_ty_app ty (tyConKind tc) tys'-       ; return (TyConApp tc tys') }---- arrows can related *unlifted* kinds, so this has to be separate from--- a dependent forall.-lintType ty@(FunTy af tw t1 t2)-  = do { t1' <- lintType t1-       ; t2' <- lintType t2-       ; tw' <- lintType tw-       ; lintArrow (text "type or kind" <+> quotes (ppr ty)) t1' t2' tw'-       ; let real_af = chooseFunTyFlag t1 t2-       ; unless (real_af == af) $ addErrL $-         hang (text "Bad FunTyFlag in FunTy")-            2 (vcat [ ppr ty-                    , text "FunTyFlag =" <+> ppr af-                    , text "Computed FunTyFlag =" <+> ppr real_af ])-       ; return (FunTy af tw' t1' t2') }--lintType ty@(ForAllTy (Bndr tcv vis) body_ty)-  | not (isTyCoVar tcv)-  = failWithL (text "Non-Tyvar or Non-Covar bound in type:" <+> ppr ty)-  | otherwise-  = lintTyCoBndr tcv $ \tcv' ->-    do { body_ty' <- lintType body_ty-       ; lintForAllBody tcv' body_ty'--       ; when (isCoVar tcv) $-         lintL (tcv `elemVarSet` tyCoVarsOfType body_ty) $-         text "Covar does not occur in the body:" <+> (ppr tcv $$ ppr body_ty)-         -- See GHC.Core.TyCo.Rep Note [Unused coercion variable in ForAllTy]--       ; return (ForAllTy (Bndr tcv' vis) body_ty') }--lintType ty@(LitTy l)-  = do { lintTyLit l; return ty }--lintType (CastTy ty co)-  = do { ty' <- lintType ty-       ; co' <- lintStarCoercion co-       ; let tyk = typeKind ty'-             cok = coercionLKind co'-       ; ensureEqTys tyk cok (mkCastTyErr ty co tyk cok)-       ; return (CastTy ty' co') }--lintType (CoercionTy co)-  = do { co' <- lintCoercion co-       ; return (CoercionTy co') }--------------------lintForAllBody :: LintedTyCoVar -> LintedType -> LintM ()--- Do the checks for the body of a forall-type-lintForAllBody tcv body_ty-  = do { checkValueType body_ty (text "the body of forall:" <+> ppr body_ty)--         -- For type variables, check for skolem escape-         -- See Note [Phantom type variables in kinds] in GHC.Core.Type-         -- The kind of (forall cv. th) is liftedTypeKind, so no-         -- need to check for skolem-escape in the CoVar case-       ; let body_kind = typeKind body_ty-       ; when (isTyVar tcv) $-         case occCheckExpand [tcv] body_kind of-           Just {} -> return ()-           Nothing -> failWithL $-                      hang (text "Variable escape in forall:")-                         2 (vcat [ text "tyvar:" <+> ppr tcv-                                 , text "type:" <+> ppr body_ty-                                 , text "kind:" <+> ppr body_kind ])-    }--------------------lintTySynFamApp :: Bool -> InType -> TyCon -> [InType] -> LintM LintedType--- The TyCon is a type synonym or a type family (not a data family)--- See Note [Linting type synonym applications]--- c.f. GHC.Tc.Validity.check_syn_tc_app-lintTySynFamApp report_unsat ty tc tys-  | report_unsat   -- Report unsaturated only if report_unsat is on-  , tys `lengthLessThan` tyConArity tc-  = failWithL (hang (text "Un-saturated type application") 2 (ppr ty))--  -- Deal with type synonyms-  | ExpandsSyn tenv rhs tys' <- expandSynTyCon_maybe tc tys-  , let expanded_ty = mkAppTys (substTy (mkTvSubstPrs tenv) rhs) tys'-  = do { -- Kind-check the argument types, but without reporting-         -- un-saturated type families/synonyms-         tys' <- setReportUnsat False (mapM lintType tys)--       ; when report_unsat $-         do { _ <- lintType expanded_ty-            ; return () }--       ; lint_ty_app ty (tyConKind tc) tys'-       ; return (TyConApp tc tys') }--  -- Otherwise this must be a type family-  | otherwise-  = do { tys' <- mapM lintType tys-       ; lint_ty_app ty (tyConKind tc) tys'-       ; return (TyConApp tc tys') }---------------------- Confirms that a type is really TYPE r or Constraint-checkValueType :: LintedType -> SDoc -> LintM ()-checkValueType ty doc-  = lintL (isTYPEorCONSTRAINT kind)-          (text "Non-Type-like kind when Type-like expected:" <+> ppr kind $$-           text "when checking" <+> doc)-  where-    kind = typeKind ty--------------------lintArrow :: SDoc -> LintedType -> LintedType -> LintedType -> LintM ()--- If you edit this function, you may need to update the GHC formalism--- See Note [GHC Formalism]-lintArrow what t1 t2 tw  -- Eg lintArrow "type or kind `blah'" k1 k2 kw-                         -- or lintArrow "coercion `blah'" k1 k2 kw-  = do { unless (isTYPEorCONSTRAINT k1) (report (text "argument") k1)-       ; unless (isTYPEorCONSTRAINT k2) (report (text "result")   k2)-       ; unless (isMultiplicityTy kw)         (report (text "multiplicity") kw) }-  where-    k1 = typeKind t1-    k2 = typeKind t2-    kw = typeKind tw-    report ar k = addErrL (vcat [ hang (text "Ill-kinded" <+> ar)-                                     2 (text "in" <+> what)-                                , what <+> text "kind:" <+> ppr k ])--------------------lint_ty_app :: Type -> LintedKind -> [LintedType] -> LintM ()-lint_ty_app msg_ty k tys-    -- See Note [Avoiding compiler perf traps when constructing error messages.]-  = lint_app (\msg_ty -> text "type" <+> quotes (ppr msg_ty)) msg_ty k tys-------------------lint_co_app :: Coercion -> LintedKind -> [LintedType] -> LintM ()-lint_co_app msg_ty k tys-    -- See Note [Avoiding compiler perf traps when constructing error messages.]-  = lint_app (\msg_ty -> text "coercion" <+> quotes (ppr msg_ty)) msg_ty k tys-------------------lintTyLit :: TyLit -> LintM ()-lintTyLit (NumTyLit n)-  | n >= 0    = return ()-  | otherwise = failWithL msg-    where msg = text "Negative type literal:" <+> integer n-lintTyLit (StrTyLit _) = return ()-lintTyLit (CharTyLit _) = return ()--lint_app :: Outputable msg_thing => (msg_thing -> SDoc) -> msg_thing -> LintedKind -> [LintedType] -> LintM ()--- (lint_app d fun_kind arg_tys)---    We have an application (f arg_ty1 .. arg_tyn),---    where f :: fun_kind---- If you edit this function, you may need to update the GHC formalism--- See Note [GHC Formalism]------ Being strict in the kind here avoids quite a few pointless thunks--- reducing allocations by ~5%-lint_app mk_msg msg_type !kfn arg_tys-    = do { !in_scope <- getInScope-         -- We need the in_scope set to satisfy the invariant in-         -- Note [The substitution invariant] in GHC.Core.TyCo.Subst-         -- Forcing the in scope set eagerly here reduces allocations by up to 4%.-         ; go_app in_scope kfn arg_tys-         }-  where--    -- We use explicit recursion instead of a fold here to avoid go_app becoming-    -- an allocated function closure. This reduced allocations by up to 7% for some-    -- modules.-    go_app :: InScopeSet -> LintedKind -> [Type] -> LintM ()-    go_app !in_scope !kfn ta-      | Just kfn' <- coreView kfn-      = go_app in_scope kfn' ta--    go_app _in_scope _kind [] = return ()--    go_app in_scope fun_kind@(FunTy _ _ kfa kfb) (ta:tas)-      = do { let ka = typeKind ta-           ; unless (ka `eqType` kfa) $-             addErrL (lint_app_fail_msg kfn arg_tys mk_msg msg_type (text "Fun:" <+> (ppr fun_kind $$ ppr ta <+> dcolon <+> ppr ka)))-           ; go_app in_scope kfb tas }--    go_app in_scope (ForAllTy (Bndr kv _vis) kfn) (ta:tas)-      = do { let kv_kind = varType kv-                 ka      = typeKind ta-           ; unless (ka `eqType` kv_kind) $-             addErrL (lint_app_fail_msg kfn arg_tys mk_msg msg_type (text "Forall:" <+> (ppr kv $$ ppr kv_kind $$-                                                    ppr ta <+> dcolon <+> ppr ka)))-           ; let kind' = substTy (extendTCvSubst (mkEmptySubst in_scope) kv ta) kfn-           ; go_app in_scope kind' tas }--    go_app _ kfn ta-       = failWithL (lint_app_fail_msg kfn arg_tys mk_msg msg_type (text "Not a fun:" <+> (ppr kfn $$ ppr ta)))---- This is a top level definition to ensure we pass all variables of the error message--- explicitly and don't capture them as free variables. Otherwise this binder might--- become a thunk that get's allocated in the hot code path.--- See Note [Avoiding compiler perf traps when constructing error messages.]-lint_app_fail_msg :: (Outputable a1, Outputable a2) => a1 -> a2 -> (t -> SDoc) -> t -> SDoc -> SDoc-lint_app_fail_msg kfn arg_tys mk_msg msg_type extra = vcat [ hang (text "Kind application error in") 2 (mk_msg msg_type)-                      , nest 2 (text "Function kind =" <+> ppr kfn)-                      , nest 2 (text "Arg types =" <+> ppr arg_tys)-                      , extra ]-{- *********************************************************************-*                                                                      *-        Linting rules-*                                                                      *-********************************************************************* -}--lintCoreRule :: OutVar -> LintedType -> CoreRule -> LintM ()-lintCoreRule _ _ (BuiltinRule {})-  = return ()  -- Don't bother--lintCoreRule fun fun_ty rule@(Rule { ru_name = name, ru_bndrs = bndrs-                                   , ru_args = args, ru_rhs = rhs })-  = lintBinders LambdaBind bndrs $ \ _ ->-    do { (lhs_ty, _) <- lintCoreArgs (fun_ty, zeroUE) args-       ; (rhs_ty, _) <- case idJoinPointHood fun of-                     JoinPoint join_arity-                       -> do { checkL (args `lengthIs` join_arity) $-                                mkBadJoinPointRuleMsg fun join_arity rule-                               -- See Note [Rules for join points]-                             ; lintCoreExpr rhs }-                     _ -> markAllJoinsBad $ lintCoreExpr rhs-       ; ensureEqTys lhs_ty rhs_ty $-         (rule_doc <+> vcat [ text "lhs type:" <+> ppr lhs_ty-                            , text "rhs type:" <+> ppr rhs_ty-                            , text "fun_ty:" <+> ppr fun_ty ])-       ; let bad_bndrs = filter is_bad_bndr bndrs--       ; checkL (null bad_bndrs)-                (rule_doc <+> text "unbound" <+> ppr bad_bndrs)-            -- See Note [Linting rules]-    }-  where-    rule_doc = text "Rule" <+> doubleQuotes (ftext name) <> colon--    lhs_fvs = exprsFreeVars args-    rhs_fvs = exprFreeVars rhs--    is_bad_bndr :: Var -> Bool-    -- See Note [Unbound RULE binders] in GHC.Core.Rules-    is_bad_bndr bndr = not (bndr `elemVarSet` lhs_fvs)-                    && bndr `elemVarSet` rhs_fvs-                    && isNothing (isReflCoVar_maybe bndr)---{- Note [Linting rules]-~~~~~~~~~~~~~~~~~~~~~~~-It's very bad if simplifying a rule means that one of the template-variables (ru_bndrs) that /is/ mentioned on the RHS becomes-not-mentioned in the LHS (ru_args).  How can that happen?  Well, in #10602,-SpecConstr stupidly constructed a rule like--  forall x,c1,c2.-     f (x |> c1 |> c2) = ....--But simplExpr collapses those coercions into one.  (Indeed in #10602,-it collapsed to the identity and was removed altogether.)--We don't have a great story for what to do here, but at least-this check will nail it.--NB (#11643): it's possible that a variable listed in the-binders becomes not-mentioned on both LHS and RHS.  Here's a silly-example:-   RULE forall x y. f (g x y) = g (x+1) (y-1)-And suppose worker/wrapper decides that 'x' is Absent.  Then-we'll end up with-   RULE forall x y. f ($gw y) = $gw (x+1)-This seems sufficiently obscure that there isn't enough payoff to-try to trim the forall'd binder list.--Note [Rules for join points]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~-A join point cannot be partially applied. However, the left-hand side of a rule-for a join point is effectively a *pattern*, not a piece of code, so there's an-argument to be made for allowing a situation like this:--  join $sj :: Int -> Int -> String-       $sj n m = ...-       j :: forall a. Eq a => a -> a -> String-       {-# RULES "SPEC j" jump j @ Int $dEq = jump $sj #-}-       j @a $dEq x y = ...--Applying this rule can't turn a well-typed program into an ill-typed one, so-conceivably we could allow it. But we can always eta-expand such an-"undersaturated" rule (see 'GHC.Core.Opt.Arity.etaExpandToJoinPointRule'), and in fact-the simplifier would have to in order to deal with the RHS. So we take a-conservative view and don't allow undersaturated rules for join points. See-Note [Join points and unfoldings/rules] in "GHC.Core.Opt.OccurAnal" for further discussion.--}--{--************************************************************************-*                                                                      *-         Linting coercions-*                                                                      *-************************************************************************--}--{- Note [Asymptotic efficiency]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-When linting coercions (and types actually) we return a linted-(substituted) coercion.  Then we often have to take the coercionKind of-that returned coercion. If we get long chains, that can be asymptotically-inefficient, notably in-* TransCo-* InstCo-* SelCo (cf #9233)-* LRCo--But the code is simple.  And this is only Lint.  Let's wait to see if-the bad perf bites us in practice.--A solution would be to return the kind and role of the coercion,-as well as the linted coercion.  Or perhaps even *only* the kind and role,-which is what used to happen.   But that proved tricky and error prone-(#17923), so now we return the coercion.--}----- lints a coercion, confirming that its lh kind and its rh kind are both *--- also ensures that the role is Nominal-lintStarCoercion :: InCoercion -> LintM LintedCoercion-lintStarCoercion g-  = do { g' <- lintCoercion g-       ; let Pair t1 t2 = coercionKind g'-       ; checkValueType t1 (text "the kind of the left type in" <+> ppr g)-       ; checkValueType t2 (text "the kind of the right type in" <+> ppr g)-       ; lintRole g Nominal (coercionRole g)-       ; return g' }--lintCoercion :: InCoercion -> LintM LintedCoercion--- If you edit this function, you may need to update the GHC formalism--- See Note [GHC Formalism]--lintCoercion (CoVarCo cv)-  | not (isCoVar cv)-  = failWithL (hang (text "Bad CoVarCo:" <+> ppr cv)-                  2 (text "With offending type:" <+> ppr (varType cv)))--  | otherwise-  = do { subst <- getSubst-       ; case lookupCoVar subst cv of-           Just linted_co -> return linted_co ;-           Nothing        -> do { checkTyCoVarInScope subst cv-                                ; return (CoVarCo cv) }-     }---lintCoercion (Refl ty)-  = do { ty' <- lintType ty-       ; return (Refl ty') }--lintCoercion (GRefl r ty MRefl)-  = do { ty' <- lintType ty-       ; return (GRefl r ty' MRefl) }--lintCoercion (GRefl r ty (MCo co))-  = do { ty' <- lintType ty-       ; co' <- lintCoercion co-       ; let tk = typeKind ty'-             tl = coercionLKind co'-       ; ensureEqTys tk tl $-         hang (text "GRefl coercion kind mis-match:" <+> ppr co)-            2 (vcat [ppr ty', ppr tk, ppr tl])-       ; lintRole co' Nominal (coercionRole co')-       ; return (GRefl r ty' (MCo co')) }--lintCoercion co@(TyConAppCo r tc cos)-  | Just {} <- tyConAppFunCo_maybe r tc cos-  = failWithL (hang (text "Saturated application of" <+> quotes (ppr tc))-                  2 (ppr co))-    -- All saturated TyConAppCos should be FunCos--  | Just {} <- synTyConDefn_maybe tc-  = failWithL (text "Synonym in TyConAppCo:" <+> ppr co)--  | otherwise-  = do { checkTyCon tc-       ; cos' <- mapM lintCoercion cos-       ; let (co_kinds, co_roles) = unzip (map coercionKindRole cos')-       ; lint_co_app co (tyConKind tc) (map pFst co_kinds)-       ; lint_co_app co (tyConKind tc) (map pSnd co_kinds)-       ; zipWithM_ (lintRole co) (tyConRoleListX r tc) co_roles-       ; return (TyConAppCo r tc cos') }--lintCoercion co@(AppCo co1 co2)-  | TyConAppCo {} <- co1-  = failWithL (text "TyConAppCo to the left of AppCo:" <+> ppr co)-  | Just (TyConApp {}, _) <- isReflCo_maybe co1-  = failWithL (text "Refl (TyConApp ...) to the left of AppCo:" <+> ppr co)-  | otherwise-  = do { co1' <- lintCoercion co1-       ; co2' <- lintCoercion co2-       ; let (Pair lk1 rk1, r1) = coercionKindRole co1'-             (Pair lk2 rk2, r2) = coercionKindRole co2'-       ; lint_co_app co (typeKind lk1) [lk2]-       ; lint_co_app co (typeKind rk1) [rk2]--       ; if r1 == Phantom-         then lintL (r2 == Phantom || r2 == Nominal)-                     (text "Second argument in AppCo cannot be R:" $$-                      ppr co)-         else lintRole co Nominal r2--       ; return (AppCo co1' co2') }-------------lintCoercion co@(ForAllCo { fco_tcv = tcv, fco_visL = visL, fco_visR = visR-                          , fco_kind = kind_co, fco_body = body_co })--- See Note [ForAllCo] in GHC.Core.TyCo.Rep,--- including the typing rule for ForAllCo--  | not (isTyCoVar tcv)-  = failWithL (text "Non tyco binder in ForAllCo:" <+> ppr co)--  | otherwise-  = do { kind_co' <- lintStarCoercion kind_co-       ; lintTyCoBndr tcv $ \tcv' ->-    do { body_co' <- lintCoercion body_co-       ; ensureEqTys (varType tcv') (coercionLKind kind_co') $-         text "Kind mis-match in ForallCo" <+> ppr co--       -- Assuming kind_co :: k1 ~ k2-       -- Need to check that-       --    (forall (tcv:k1). lty) and-       --    (forall (tcv:k2). rty[(tcv:k2) |> sym kind_co/tcv])-       -- are both well formed.  Easiest way is to call lintForAllBody-       -- for each; there is actually no need to do the funky substitution-       ; let (Pair lty rty, body_role) = coercionKindRole body_co'-       ; lintForAllBody tcv' lty-       ; lintForAllBody tcv' rty--       ; when (isCoVar tcv) $-         do { lintL (visL == coreTyLamForAllTyFlag && visR == coreTyLamForAllTyFlag) $-              text "Invalid visibility flags in CoVar ForAllCo" <+> ppr co-              -- See (FC7) in Note [ForAllCo] in GHC.Core.TyCo.Rep-            ; lintL (almostDevoidCoVarOfCo tcv body_co) $-              text "Covar can only appear in Refl and GRefl: " <+> ppr co-              -- See (FC6) in Note [ForAllCo] in GHC.Core.TyCo.Rep-         }--       ; when (body_role == Nominal) $-         lintL (visL `eqForAllVis` visR) $-         text "Nominal ForAllCo has mismatched visibilities: " <+> ppr co--       ; return (co { fco_tcv = tcv', fco_kind = kind_co', fco_body = body_co' }) } }--lintCoercion co@(FunCo { fco_role = r, fco_afl = afl, fco_afr = afr-                       , fco_mult = cow, fco_arg = co1, fco_res = co2 })-  = do { co1' <- lintCoercion co1-       ; co2' <- lintCoercion co2-       ; cow' <- lintCoercion cow-       ; let Pair lt1 rt1 = coercionKind co1-             Pair lt2 rt2 = coercionKind co2-             Pair ltw rtw = coercionKind cow-       ; lintL (afl == chooseFunTyFlag lt1 lt2) (bad_co_msg "afl")-       ; lintL (afr == chooseFunTyFlag rt1 rt2) (bad_co_msg "afr")-       ; lintArrow (bad_co_msg "arrowl") lt1 lt2 ltw-       ; lintArrow (bad_co_msg "arrowr") rt1 rt2 rtw-       ; lintRole co1 r (coercionRole co1)-       ; lintRole co2 r (coercionRole co2)-       ; ensureEqTys (typeKind ltw) multiplicityTy (bad_co_msg "mult-l")-       ; ensureEqTys (typeKind rtw) multiplicityTy (bad_co_msg "mult-r")-       ; let expected_mult_role = case r of-                                    Phantom -> Phantom-                                    _ -> Nominal-       ; lintRole cow expected_mult_role (coercionRole cow)-       ; return (co { fco_mult = cow', fco_arg = co1', fco_res = co2' }) }-  where-    bad_co_msg s = hang (text "Bad coercion" <+> parens (text s))-                      2 (vcat [ text "afl:" <+> ppr afl-                              , text "afr:" <+> ppr afr-                              , text "arg_co:" <+> ppr co1-                              , text "res_co:" <+> ppr co2 ])---- See Note [Bad unsafe coercion]-lintCoercion co@(UnivCo { uco_role = r, uco_prov = prov-                        , uco_lty = ty1, uco_rty = ty2, uco_deps = deps })-  = do { -- Check the role.  PhantomProv must have Phantom role, otherwise any role is fine-         case prov of-            PhantomProv -> lintRole co Phantom r-            _           -> return ()--       -- Check the to and from types-       ; ty1' <- lintType ty1-       ; ty2' <- lintType ty2--       ; let k1 = typeKind ty1'-             k2 = typeKind ty2'-       ; when (r /= Phantom && isTYPEorCONSTRAINT k1-                            && isTYPEorCONSTRAINT k2)-              (checkTypes ty1 ty2)--       -- Check the coercions on which this UnivCo depends-       ; deps' <- mapM lintCoercion deps--       ; return (co { uco_lty = ty1', uco_rty = ty2', uco_deps = deps' }) }-   where-     report s = hang (text $ "Unsafe coercion: " ++ s)-                     2 (vcat [ text "From:" <+> ppr ty1-                             , text "  To:" <+> ppr ty2])-     isUnBoxed :: PrimRep -> Bool-     isUnBoxed = not . isGcPtrRep--       -- see #9122 for discussion of these checks-     checkTypes t1 t2-       = do { checkWarnL fixed_rep_1-                         (report "left-hand type does not have a fixed runtime representation")-            ; checkWarnL fixed_rep_2-                         (report "right-hand type does not have a fixed runtime representation")-            ; when (fixed_rep_1 && fixed_rep_2) $-              do { checkWarnL (reps1 `equalLength` reps2)-                              (report "between values with different # of reps")-                 ; zipWithM_ validateCoercion reps1 reps2 }}-       where-         fixed_rep_1 = typeHasFixedRuntimeRep t1-         fixed_rep_2 = typeHasFixedRuntimeRep t2--         -- don't look at these unless lev_poly1/2 are False-         -- Otherwise, we get #13458-         reps1 = typePrimRep t1-         reps2 = typePrimRep t2--     validateCoercion :: PrimRep -> PrimRep -> LintM ()-     validateCoercion rep1 rep2-       = do { platform <- getPlatform-            ; checkWarnL (isUnBoxed rep1 == isUnBoxed rep2)-                         (report "between unboxed and boxed value")-            ; checkWarnL (TyCon.primRepSizeB platform rep1-                           == TyCon.primRepSizeB platform rep2)-                         (report "between unboxed values of different size")-            ; let fl = liftM2 (==) (TyCon.primRepIsFloat rep1)-                                   (TyCon.primRepIsFloat rep2)-            ; case fl of-                Nothing    -> addWarnL (report "between vector types")-                Just False -> addWarnL (report "between float and integral values")-                _          -> return ()-            }--lintCoercion (SymCo co)-  = do { co' <- lintCoercion co-       ; return (SymCo co') }--lintCoercion co@(TransCo co1 co2)-  = do { co1' <- lintCoercion co1-       ; co2' <- lintCoercion co2-       ; let ty1b = coercionRKind co1'-             ty2a = coercionLKind co2'-       ; ensureEqTys ty1b ty2a-               (hang (text "Trans coercion mis-match:" <+> ppr co)-                   2 (vcat [ppr (coercionKind co1'), ppr (coercionKind co2')]))-       ; lintRole co (coercionRole co1) (coercionRole co2)-       ; return (TransCo co1' co2') }--lintCoercion the_co@(SelCo cs co)-  = do { co' <- lintCoercion co-       ; let (Pair s t, co_role) = coercionKindRole co'--       ; if -- forall (both TyVar and CoVar)-            | Just _ <- splitForAllTyCoVar_maybe s-            , Just _ <- splitForAllTyCoVar_maybe t-            , SelForAll <- cs-            ,   (isForAllTy_ty s && isForAllTy_ty t)-             || (isForAllTy_co s && isForAllTy_co t)-            -> return (SelCo cs co')--            -- function-            | isFunTy s-            , isFunTy t-            , SelFun {} <- cs-            -> return (SelCo cs co')--            -- TyCon-            | Just (tc_s, tys_s) <- splitTyConApp_maybe s-            , Just (tc_t, tys_t) <- splitTyConApp_maybe t-            , tc_s == tc_t-            , SelTyCon n r0 <- cs-            , isInjectiveTyCon tc_s co_role-                -- see Note [SelCo and newtypes] in GHC.Core.TyCo.Rep-            , tys_s `equalLength` tys_t-            , tys_s `lengthExceeds` n-            -> do { lintRole the_co (tyConRole co_role tc_s n) r0-                  ; return (SelCo cs co') }--            | otherwise-            -> failWithL (hang (text "Bad SelCo:")-                             2 (ppr the_co $$ ppr s $$ ppr t)) }--lintCoercion the_co@(LRCo lr co)-  = do { co' <- lintCoercion co-       ; let Pair s t = coercionKind co'-             r        = coercionRole co'-       ; lintRole co Nominal r-       ; case (splitAppTy_maybe s, splitAppTy_maybe t) of-           (Just _, Just _) -> return (LRCo lr co')-           _ -> failWithL (hang (text "Bad LRCo:")-                              2 (ppr the_co $$ ppr s $$ ppr t)) }--lintCoercion (InstCo co arg)-  = do { co'  <- lintCoercion co-       ; arg' <- lintCoercion arg-       ; let Pair t1 t2 = coercionKind co'-             Pair s1 s2 = coercionKind arg'--       ; lintRole arg Nominal (coercionRole arg')--      ; case (splitForAllTyVar_maybe t1, splitForAllTyVar_maybe t2) of-         -- forall over tvar-         { (Just (tv1,_), Just (tv2,_))-             | typeKind s1 `eqType` tyVarKind tv1-             , typeKind s2 `eqType` tyVarKind tv2-             -> return (InstCo co' arg')-             | otherwise-             -> failWithL (text "Kind mis-match in inst coercion1" <+> ppr co)--         ; _ -> case (splitForAllCoVar_maybe t1, splitForAllCoVar_maybe t2) of-         -- forall over covar-         { (Just (cv1, _), Just (cv2, _))-             | typeKind s1 `eqType` varType cv1-             , typeKind s2 `eqType` varType cv2-             , CoercionTy _ <- s1-             , CoercionTy _ <- s2-             -> return (InstCo co' arg')-             | otherwise-             -> failWithL (text "Kind mis-match in inst coercion2" <+> ppr co)--         ; _ -> failWithL (text "Bad argument of inst") }}}--lintCoercion this_co@(AxiomCo ax cos)-  = do { cos' <- mapM lintCoercion cos-       ; let arg_kinds :: [Pair Type] = map coercionKind cos'-       ; lint_roles 0 (coAxiomRuleArgRoles ax) cos'-       ; lint_ax ax arg_kinds-       ; return (AxiomCo ax cos') }-  where-    lint_ax :: CoAxiomRule -> [Pair Type] -> LintM ()-    lint_ax (BuiltInFamRew  bif) prs-      = checkL (isJust (bifrw_proves bif prs))  bad_bif-    lint_ax (BuiltInFamInj bif) prs-      = checkL (case prs of-                  [pr] -> isJust (bifinj_proves bif pr)-                  _    -> False)-               bad_bif-    lint_ax (UnbranchedAxiom ax) prs-      = lintBranch this_co (coAxiomTyCon ax) (coAxiomSingleBranch ax) prs-    lint_ax (BranchedAxiom ax ind) prs-      = do { checkL (0 <= ind && ind < numBranches (coAxiomBranches ax))-                    (bad_ax this_co (text "index out of range"))-           ; lintBranch this_co (coAxiomTyCon ax) (coAxiomNthBranch ax ind) prs }--    bad_bif = bad_ax this_co (text "Proves returns Nothing")--    err :: forall a. String -> [SDoc] -> LintM a-    err m xs  = failWithL $-                hang (text m) 2 $ vcat (text "Rule:" <+> ppr ax : xs)--    lint_roles n (e : es) (co : cos)-      | e == coercionRole co-      = lint_roles (n+1) es cos-      | otherwise = err "Argument roles mismatch"-                        [ text "In argument:" <+> int (n+1)-                        , text "Expected:" <+> ppr e-                        , text "Found:" <+> ppr (coercionRole co) ]-    lint_roles _ [] []  = return ()-    lint_roles n [] rs  = err "Too many coercion arguments"-                            [ text "Expected:" <+> int n-                            , text "Provided:" <+> int (n + length rs) ]--    lint_roles n es []  = err "Not enough coercion arguments"-                            [ text "Expected:" <+> int (n + length es)-                            , text "Provided:" <+> int n ]---lintCoercion (KindCo co)-  = do { co' <- lintCoercion co-       ; return (KindCo co') }--lintCoercion (SubCo co')-  = do { co' <- lintCoercion co'-       ; lintRole co' Nominal (coercionRole co')-       ; return (SubCo co') }--lintCoercion (HoleCo h)-  = do { addErrL $ text "Unfilled coercion hole:" <+> ppr h-       ; lintCoercion (CoVarCo (coHoleCoVar h)) }---{--Note [Conflict checking for axiom applications]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-Consider the following type family and axiom:--type family Equal (a :: k) (b :: k) :: Bool-type instance where-  Equal a a = True-  Equal a b = False----Equal :: forall k::*. k -> k -> Bool-axEqual :: { forall k::*. forall a::k. Equal k a a ~ True-           ; forall k::*. forall a::k. forall b::k. Equal k a b ~ False }--The coercion (axEqual[1] <*> <Int> <Int) is ill-typed, and Lint should reject it.-(Recall that the index is 0-based, so this is the second branch of the axiom.)-The problem is that, on the surface, it seems that--  (axEqual[1] <*> <Int> <Int>) :: (Equal * Int Int ~ False)--and that all is OK. But, all is not OK: we want to use the first branch of the-axiom in this case, not the second. The problem is that the parameters of the-first branch can unify with the supplied coercions, thus meaning that the first-branch should be taken. See also Note [Apartness] in "GHC.Core.FamInstEnv".--For more details, see the section "Branched axiom conflict checking" in-docs/core-spec, which defines the corresponding no_conflict function used by the-Co_AxiomInstCo rule in the section "Coercion typing".--}---- | Check to make sure that an axiom application is internally consistent.--- Returns the conflicting branch, if it exists--- Note [Conflict checking for axiom applications]-lintBranch :: Coercion -> TyCon-> CoAxBranch -> [Pair Type] -> LintM ()--- defined here to avoid dependencies in GHC.Core.Coercion--- If you edit this function, you may need to update the GHC formalism--- See Note [GHC Formalism] in GHC.Core.Lint-lintBranch this_co fam_tc branch arg_kinds-  | CoAxBranch { cab_tvs = ktvs, cab_cvs = cvs } <- branch-  = do { checkL (arg_kinds `equalLength` (ktvs ++ cvs)) $-                (bad_ax this_co (text "lengths"))--       ; subst <- getSubst-       ; let empty_subst = zapSubst subst-       ; _ <- foldlM check_ki (empty_subst, empty_subst)-                              (zip (ktvs ++ cvs) arg_kinds)--       ; case check_no_conflict flattened_target incomps of-            Nothing -> return ()-            Just bad_branch -> failWithL $ bad_ax this_co $-                               text "inconsistent with" <+>-                                 pprCoAxBranch fam_tc bad_branch }-  where-    check_ki (subst_l, subst_r) (ktv, Pair s' t')-      = do { let sk' = typeKind s'-                 tk' = typeKind t'-           ; let ktv_kind_l = substTy subst_l (tyVarKind ktv)-                 ktv_kind_r = substTy subst_r (tyVarKind ktv)-           ; checkL (sk' `eqType` ktv_kind_l)-                    (bad_ax this_co (text "check_ki1" <+> vcat [ ppr this_co, ppr sk', ppr ktv, ppr ktv_kind_l ] ))-           ; checkL (tk' `eqType` ktv_kind_r)-                    (bad_ax this_co (text "check_ki2" <+> vcat [ ppr this_co, ppr tk', ppr ktv, ppr ktv_kind_r ] ))-           ; return (extendTCvSubst subst_l ktv s',-                     extendTCvSubst subst_r ktv t') }--    tvs          = coAxBranchTyVars branch-    cvs          = coAxBranchCoVars branch-    incomps      = coAxBranchIncomps branch-    (tys, cotys) = splitAtList tvs (map pFst arg_kinds)-    co_args      = map stripCoercionTy cotys-    subst        = zipTvSubst tvs tys `composeTCvSubst`-                   zipCvSubst cvs co_args-    target   = Type.substTys subst (coAxBranchLHS branch)-    in_scope = mkInScopeSet $-               unionVarSets (map (tyCoVarsOfTypes . coAxBranchLHS) incomps)-    flattened_target = flattenTys in_scope target--    check_no_conflict :: [Type] -> [CoAxBranch] -> Maybe CoAxBranch-    check_no_conflict _    [] = Nothing-    check_no_conflict flat (b@CoAxBranch { cab_lhs = lhs_incomp } : rest)-         -- See Note [Apartness] in GHC.Core.FamInstEnv-      | SurelyApart <- tcUnifyTysFG alwaysBindFun flat lhs_incomp-      = check_no_conflict flat rest-      | otherwise-      = Just b--bad_ax :: Coercion -> SDoc -> SDoc-bad_ax this_co what-    = hang (text "Bad axiom application" <+> parens what) 2 (ppr this_co)---{--************************************************************************-*                                                                      *-              Axioms-*                                                                      *-************************************************************************--}--lintAxioms :: Logger-           -> LintConfig-           -> SDoc -- ^ The source of the linted axioms-           -> [CoAxiom Branched]-           -> IO ()-lintAxioms logger cfg what axioms =-  displayLintResults logger True what (vcat $ map pprCoAxiom axioms) $-  initL cfg $-  do { mapM_ lint_axiom axioms-     ; let axiom_groups = groupWith coAxiomTyCon axioms-     ; mapM_ lint_axiom_group axiom_groups }--lint_axiom :: CoAxiom Branched -> LintM ()-lint_axiom ax@(CoAxiom { co_ax_tc = tc, co_ax_branches = branches-                       , co_ax_role = ax_role })-  = addLoc (InAxiom ax) $-    do { mapM_ (lint_branch tc) branch_list-       ; extra_checks }-  where-    branch_list = fromBranches branches--    extra_checks-      | isNewTyCon tc-      = do { CoAxBranch { cab_tvs     = ax_tvs-                        , cab_eta_tvs = eta_tvs-                        , cab_cvs     = cvs-                        , cab_roles   = roles-                        , cab_lhs     = lhs_tys }-              <- case branch_list of-               [branch] -> return branch-               _        -> failWithL (text "multi-branch axiom with newtype")--           -- The LHS of the axiom is (N lhs_tys)-           -- We expect it to be      (N ax_tvs)-           ; lintL (mkTyVarTys ax_tvs `eqTypes` lhs_tys)-                   (text "Newtype axiom LHS does not match newtype definition")-           ; lintL (null cvs)-                   (text "Newtype axiom binds coercion variables")-           ; lintL (null eta_tvs)  -- See Note [Eta reduction for data families]-                                   -- which is not about newtype axioms-                   (text "Newtype axiom has eta-tvs")-           ; lintL (ax_role == Representational)-                   (text "Newtype axiom role not representational")-           ; lintL (roles `equalLength` ax_tvs)-                   (text "Newtype axiom roles list is the wrong length." $$-                    text "roles:" <+> sep (map ppr roles))-           ; lintL (roles == takeList roles (tyConRoles tc))-                   (vcat [ text "Newtype axiom roles do not match newtype tycon's."-                         , text "axiom roles:" <+> sep (map ppr roles)-                         , text "tycon roles:" <+> sep (map ppr (tyConRoles tc)) ])-           }--      | isFamilyTyCon tc-      = do { if | isTypeFamilyTyCon tc-                  -> lintL (ax_role == Nominal)-                           (text "type family axiom is not nominal")--                | isDataFamilyTyCon tc-                  -> lintL (ax_role == Representational)-                           (text "data family axiom is not representational")--                | otherwise-                  -> addErrL (text "A family TyCon is neither a type family nor a data family:" <+> ppr tc)--           ; mapM_ (lint_family_branch tc) branch_list }--      | otherwise-      = addErrL (text "Axiom tycon is neither a newtype nor a family.")--lint_branch :: TyCon -> CoAxBranch -> LintM ()-lint_branch ax_tc (CoAxBranch { cab_tvs = tvs, cab_cvs = cvs-                              , cab_lhs = lhs_args, cab_rhs = rhs })-  = lintBinders LambdaBind (tvs ++ cvs) $ \_ ->-    do { let lhs = mkTyConApp ax_tc lhs_args-       ; lhs' <- lintType lhs-       ; rhs' <- lintType rhs-       ; let lhs_kind = typeKind lhs'-             rhs_kind = typeKind rhs'-       ; lintL (not (lhs_kind `typesAreApart` rhs_kind)) $-         hang (text "Inhomogeneous axiom")-            2 (text "lhs:" <+> ppr lhs <+> dcolon <+> ppr lhs_kind $$-               text "rhs:" <+> ppr rhs <+> dcolon <+> ppr rhs_kind) }-         -- Type and Constraint are not Apart, so this test allows-         -- the newtype axiom for a single-method class.  Indeed the-         -- whole reason Type and Constraint are not Apart is to allow-         -- such axioms!---- these checks do not apply to newtype axioms-lint_family_branch :: TyCon -> CoAxBranch -> LintM ()-lint_family_branch fam_tc br@(CoAxBranch { cab_tvs     = tvs-                                         , cab_eta_tvs = eta_tvs-                                         , cab_cvs     = cvs-                                         , cab_roles   = roles-                                         , cab_lhs     = lhs-                                         , cab_incomps = incomps })-  = do { lintL (isDataFamilyTyCon fam_tc || null eta_tvs)-               (text "Type family axiom has eta-tvs")-       ; lintL (all (`elemVarSet` tyCoVarsOfTypes lhs) tvs)-               (text "Quantified variable in family axiom unused in LHS")-       ; lintL (all isTyFamFree lhs)-               (text "Type family application on LHS of family axiom")-       ; lintL (all (== Nominal) roles)-               (text "Non-nominal role in family axiom" $$-                text "roles:" <+> sep (map ppr roles))-       ; lintL (null cvs)-               (text "Coercion variables bound in family axiom")-       ; forM_ incomps $ \ br' ->-           lintL (not (compatibleBranches br br')) $-           hang (text "Incorrect incompatible branches:")-              2 (vcat [text "Branch:"       <+> ppr br,-                       text "Bogus incomp:" <+> ppr br']) }--lint_axiom_group :: NonEmpty (CoAxiom Branched) -> LintM ()-lint_axiom_group (_  :| []) = return ()-lint_axiom_group (ax :| axs)-  = do { lintL (isOpenFamilyTyCon tc)-               (text "Non-open-family with multiple axioms")-       ; let all_pairs = [ (ax1, ax2) | ax1 <- all_axs-                                      , ax2 <- all_axs ]-       ; mapM_ (lint_axiom_pair tc) all_pairs }-  where-    all_axs = ax : axs-    tc      = coAxiomTyCon ax--lint_axiom_pair :: TyCon -> (CoAxiom Branched, CoAxiom Branched) -> LintM ()-lint_axiom_pair tc (ax1, ax2)-  | Just br1@(CoAxBranch { cab_tvs = tvs1-                         , cab_lhs = lhs1-                         , cab_rhs = rhs1 }) <- coAxiomSingleBranch_maybe ax1-  , Just br2@(CoAxBranch { cab_tvs = tvs2-                         , cab_lhs = lhs2-                         , cab_rhs = rhs2 }) <- coAxiomSingleBranch_maybe ax2-  = lintL (compatibleBranches br1 br2) $-    vcat [ hsep [ text "Axioms", ppr ax1, text "and", ppr ax2-                , text "are incompatible" ]-         , text "tvs1 =" <+> pprTyVars tvs1-         , text "lhs1 =" <+> ppr (mkTyConApp tc lhs1)-         , text "rhs1 =" <+> ppr rhs1-         , text "tvs2 =" <+> pprTyVars tvs2-         , text "lhs2 =" <+> ppr (mkTyConApp tc lhs2)-         , text "rhs2 =" <+> ppr rhs2 ]--  | otherwise-  = addErrL (text "Open type family axiom has more than one branch: either" <+>-             ppr ax1 <+> text "or" <+> ppr ax2)--{--************************************************************************-*                                                                      *-\subsection[lint-monad]{The Lint monad}-*                                                                      *-************************************************************************--}---- If you edit this type, you may need to update the GHC formalism--- See Note [GHC Formalism]-data LintEnv-  = LE { le_flags :: LintFlags       -- Linting the result of this pass-       , le_loc   :: [LintLocInfo]   -- Locations--       , le_subst :: Subst  -- Current TyCo substitution-                               --    See Note [Linting type lets]-            -- /Only/ substitutes for type variables;-            --        but might clone CoVars-            -- We also use le_subst to keep track of-            -- in-scope TyVars and CoVars (but not Ids)-            -- Range of the Subst is LintedType/LintedCo--       , le_ids   :: VarEnv (Id, LintedType)    -- In-scope Ids-            -- Used to check that occurrences have an enclosing binder.-            -- The Id is /pre-substitution/, used to check that-            -- the occurrence has an identical type to the binder-            -- The LintedType is used to return the type of the occurrence,-            -- without having to lint it again.--       , le_joins :: IdSet     -- Join points in scope that are valid-                               -- A subset of the InScopeSet in le_subst-                               -- See Note [Join points]--       , le_ue_aliases :: NameEnv UsageEnv -- Assigns usage environments to the-                                           -- alias-like binders, as found in-                                           -- non-recursive lets.--       , le_platform   :: Platform         -- ^ Target platform-       , le_diagOpts   :: DiagOpts         -- ^ Target platform-       }--data LintFlags-  = LF { lf_check_global_ids           :: Bool -- See Note [Checking for global Ids]-       , lf_check_inline_loop_breakers :: Bool -- See Note [Checking for INLINE loop breakers]-       , lf_check_static_ptrs :: StaticPtrCheck -- ^ See Note [Checking StaticPtrs]-       , lf_report_unsat_syns :: Bool -- ^ See Note [Linting type synonym applications]-       , lf_check_linearity :: Bool -- ^ See Note [Linting linearity]-       , lf_check_fixed_rep :: Bool -- See Note [Checking for representation polymorphism]-    }---- See Note [Checking StaticPtrs]-data StaticPtrCheck-    = AllowAnywhere-        -- ^ Allow 'makeStatic' to occur anywhere.-    | AllowAtTopLevel-        -- ^ Allow 'makeStatic' calls at the top-level only.-    | RejectEverywhere-        -- ^ Reject any 'makeStatic' occurrence.-  deriving Eq--newtype LintM a =-   LintM' { unLintM ::-            LintEnv ->-            WarnsAndErrs ->           -- Warning and error messages so far-            LResult a } -- Result and messages (if any)---pattern LintM :: (LintEnv -> WarnsAndErrs -> LResult a) -> LintM a--- See Note [The one-shot state monad trick] in GHC.Utils.Monad-pattern LintM m <- LintM' m-  where-    LintM m = LintM' (oneShot $ \env -> oneShot $ \we -> m env we)-    -- LintM m = LintM' (oneShot $ oneShot m)-{-# COMPLETE LintM #-}--instance Functor (LintM) where-  fmap f (LintM m) = LintM $ \e w -> mapLResult f (m e w)--type WarnsAndErrs = (Bag SDoc, Bag SDoc)---- Using a unboxed tuple here reduced allocations for a lint heavy--- file by ~6%. Using MaybeUB reduced them further by another ~12%.-type LResult a = (# MaybeUB a, WarnsAndErrs #)--pattern LResult :: MaybeUB a -> WarnsAndErrs -> LResult a-pattern LResult m w = (# m, w #)-{-# COMPLETE LResult #-}--mapLResult :: (a1 -> a2) -> LResult a1 -> LResult a2-mapLResult f (LResult r w) = LResult (fmapMaybeUB f r) w---- Just for testing.-fromBoxedLResult :: (Maybe a, WarnsAndErrs) -> LResult a-fromBoxedLResult (Just x, errs) = LResult (JustUB x) errs-fromBoxedLResult (Nothing,errs) = LResult NothingUB errs--{- Note [Checking for global Ids]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-Before CoreTidy, all locally-bound Ids must be LocalIds, even-top-level ones. See Note [Exported LocalIds] and #9857.--Note [Checking StaticPtrs]-~~~~~~~~~~~~~~~~~~~~~~~~~~-See Note [Grand plan for static forms] in GHC.Iface.Tidy.StaticPtrTable for an overview.--Every occurrence of the function 'makeStatic' should be moved to the-top level by the FloatOut pass.  It's vital that we don't have nested-'makeStatic' occurrences after CorePrep, because we populate the Static-Pointer Table from the top-level bindings. See SimplCore Note [Grand-plan for static forms].--The linter checks that no occurrence is left behind, nested within an-expression. The check is enabled only after the FloatOut, CorePrep,-and CoreTidy passes and only if the module uses the StaticPointers-language extension. Checking more often doesn't help since the condition-doesn't hold until after the first FloatOut pass.--Note [Type substitution]-~~~~~~~~~~~~~~~~~~~~~~~~-Why do we need a type substitution?  Consider-        /\(a:*). \(x:a). /\(a:*). id a x-This is ill typed, because (renaming variables) it is really-        /\(a:*). \(x:a). /\(b:*). id b x-Hence, when checking an application, we can't naively compare x's type-(at its binding site) with its expected type (at a use site).  So we-rename type binders as we go, maintaining a substitution.--The same substitution also supports let-type, current expressed as-        (/\(a:*). body) ty-Here we substitute 'ty' for 'a' in 'body', on the fly.--Note [Linting type synonym applications]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-When linting a type-synonym, or type-family, application-  S ty1 .. tyn-we behave as follows (#15057, #T15664):--* If lf_report_unsat_syns = True, and S has arity < n,-  complain about an unsaturated type synonym or type family--* Switch off lf_report_unsat_syns, and lint ty1 .. tyn.--  Reason: catch out of scope variables or other ill-kinded gubbins,-  even if S discards that argument entirely. E.g. (#15012):-     type FakeOut a = Int-     type family TF a-     type instance TF Int = FakeOut a-  Here 'a' is out of scope; but if we expand FakeOut, we conceal-  that out-of-scope error.--  Reason for switching off lf_report_unsat_syns: with-  LiberalTypeSynonyms, GHC allows unsaturated synonyms provided they-  are saturated when the type is expanded. Example-     type T f = f Int-     type S a = a -> a-     type Z = T S-  In Z's RHS, S appears unsaturated, but it is saturated when T is expanded.--* If lf_report_unsat_syns is on, expand the synonym application and-  lint the result.  Reason: want to check that synonyms are saturated-  when the type is expanded.--Note [Linting linearity]-~~~~~~~~~~~~~~~~~~~~~~~~-Lint ignores linearity unless `-dlinear-core-lint` is set.  For why, see below.--But first, "ignore linearity" specifically means two things. When ignoring linearity:-* In `ensureEqTypes`, use `eqTypeIgnoringMultiplicity`-* In `ensureSubMult`, do nothing--But why make `-dcore-lint` ignore linearity?  Because optimisation passes are-not (yet) guaranteed to maintain linearity.  They should do so semantically (GHC-is careful not to duplicate computation) but it is much harder to ensure that-the statically-checkable constraints of Linear Core are maintained. The current-Linear Core is described in the wiki at:-https://gitlab.haskell.org/ghc/ghc/-/wikis/linear-types/implementation.--Here are some examples of how the optimiser can break linearity checking.  Other-examples are documented in the linear-type implementation wiki page-[https://gitlab.haskell.org/ghc/ghc/-/wikis/linear-types/implementation#core-to-core-passes]--* EXAMPLE 1: the binder swap transformation-    Consider--      data T = MkT {-# UNPACK #-} !Int--    The wrapper for MkT is--      $wMkT :: Int %1 -> T-      $wMkT n = case %1 n of-        I# n' -> MkT n'--    This introduces, in particular, a `case %1` (this is not actual Haskell or-    Core syntax), where the `%1` means that the `case` expression consumes its-    scrutinee linearly.--    Now, `case %1` interacts with the binder swap optimisation in a non-trivial-    way. Take a slightly modified version of the code for $wMkT:--      case %1 x of z {-        I# n' -> (x, n')-      }--    Binder-swap changes this to--      case %1 x of z {-        I# n' -> let x = z in (x, n')-      }--    This is rejected by `-dlinear-core-lint` because 1/ n' must be used linearly-    2/ `-dlinear-core-lint` recognises a use of `z` as a use of `n'`. So it sees-    two uses of n' where there should be a single one.--* EXAMPLE 2: letrec-    Some optimisations can create a letrec which uses a variable-    linearly, e.g.--      letrec f True = f False-             f False = x-      in f True--    uses 'x' linearly, but this is not seen by the linter, which considers,-    conservatively, that a letrec always has multiplicity Many (in particular-    that every captured free variable must have multiplicity Many). This issue-    is discussed in ticket #18694.--* EXAMPLE 3: rewrite rules-    Ignoring linearity means in particular that `a -> b` and `a %1 -> b` must be-    treated the same by rewrite rules (see also Note [Rewrite rules ignore-    multiplicities in FunTy] in GHC.Core.Unify). Consider--      m :: Bool -> A-      m' :: (Bool -> Bool) -> A-      {- RULES "ex" forall f. m (f True) = m' f -}--      f :: Bool %1 -> A-      x = m (f True)--    The rule "ex" must match . So the linter must accept `m' f`.--* EXAMPLE 4: eta-reduction-   Eta-expansion can change linear functions into unrestricted functions--     f :: A %1 -> B--     g :: A %Many -> B-     g = \x -> f x--   Eta-reduction undoes this and produces:--     g :: A %Many -> B-     g = f--Historical note: In the original linear-types implementation, we had tried to-make every optimisation pass produce code that passes `-dlinear-core-lint`. It-had proved very difficult. We kept finding corner case after corner-case. Furthermore, to attempt to achieve that goal we ended up restricting-transformations when `-dlinear-core-lint` couldn't typecheck the result.--In the future, we may be able to lint the linearity of the output of-Core-to-Core passes (#19165). But this shouldn't be done at the expense of-producing efficient code. Therefore we lay the following principle.--PRINCIPLE: The type system bends to the optimisation, not the other way around.--There is a useful discussion at https://gitlab.haskell.org/ghc/ghc/-/issues/22123--Note [Linting representation-polymorphic builtins]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-As described in Note [Representation-polymorphism checking built-ins], on-top of the two main representation-polymorphism invariants described in the-Note [Representation polymorphism invariants], we must perform additional-representation-polymorphism checks on builtin functions which don't have a-binding, for example to ensure that we don't run afoul of the-representation-polymorphism invariants when eta-expanding.--There are two situations:--  1. Builtins which have skolem type variables which must be instantiated to-     concrete types, such as the RuntimeRep type argument r to the catch# primop.--  2. Representation-polymorphic unlifted newtypes, which must always be instantiated-     at a fixed runtime representation.--For 1, consider for example 'coerce':--  coerce :: forall {r} (a :: TYPE r) (b :: TYPE r). Coercible a b => a -> b--We store in the IdDetails of the coerce Id that the first binder, r, must always-be instantiated to a concrete type. We thus check this in Core Lint: whenever we-see an application of the form--  coerce @{rep1} ...--we ensure that 'rep1' is concrete. This is done in the function "checkRepPolyBuiltinApp".-Moreover, not instantiating these type variables at all is also an error, as-we would again not be able to perform eta-expansion. (This is a bit more theoretical,-as in user programs the typechecker will insert these type applications when-instantiating, but it can still arise when constructing Core expressions).--For 2, whenever we have an unlifted newtype such as--  type RR :: Type -> RuntimeRep-  type family RR a--  type F :: forall (a :: Type) -> TYPE (RR a)-  type family F a--  type N :: forall (a :: Type) -> TYPE (RR a)-  newtype N a = MkN (F a)--and an unsaturated occurrence--  MkN @ty -- NB: no value argument!--we check that the (instantiated) argument type has a fixed runtime representation.-This is done in the function "checkRepPolyNewtypeApp".--}--instance Applicative LintM where-      pure x = LintM $ \ _ errs -> LResult (JustUB x) errs-                                   --(Just x, errs)-      (<*>) = ap--instance Monad LintM where-  m >>= k  = LintM (\ env errs ->-                       let res = unLintM m env errs in-                         case res of-                           LResult (JustUB r) errs' -> unLintM (k r) env errs'-                           LResult NothingUB errs' -> LResult NothingUB errs'-                    )-                          --  LError errs'-> LError errs')-                      --  let (res, errs') = unLintM m env errs in-                          --  Just r -> unLintM (k r) env errs'-                          --  Nothing -> (Nothing, errs'))--instance MonadFail LintM where-    fail err = failWithL (text err)--getPlatform :: LintM Platform-getPlatform = LintM (\ e errs -> (LResult (JustUB $ le_platform e) errs))--data LintLocInfo-  = RhsOf Id            -- The variable bound-  | OccOf Id            -- Occurrence of id-  | LambdaBodyOf Id     -- The lambda-binder-  | RuleOf Id           -- Rules attached to a binder-  | UnfoldingOf Id      -- Unfolding of a binder-  | BodyOfLet Id        -- The let-bound variable-  | BodyOfLetRec [Id]   -- The binders of the let-  | CaseAlt CoreAlt     -- Case alternative-  | CasePat CoreAlt     -- The *pattern* of the case alternative-  | CaseTy CoreExpr     -- The type field of a case expression-                        -- with this scrutinee-  | IdTy Id             -- The type field of an Id binder-  | AnExpr CoreExpr     -- Some expression-  | ImportedUnfolding SrcLoc -- Some imported unfolding (ToDo: say which)-  | TopLevelBindings-  | InType Type         -- Inside a type-  | InCo   Coercion     -- Inside a coercion-  | InAxiom (CoAxiom Branched)   -- Inside a CoAxiom--data LintConfig = LintConfig-  { l_diagOpts   :: !DiagOpts         -- ^ Diagnostics opts-  , l_platform   :: !Platform         -- ^ Target platform-  , l_flags      :: !LintFlags        -- ^ Linting the result of this pass-  , l_vars       :: ![Var]            -- ^ 'Id's that should be treated as being in scope-  }--initL :: LintConfig-      -> LintM a            -- ^ Action to run-      -> WarnsAndErrs-initL cfg m-  = case unLintM m env (emptyBag, emptyBag) of-      LResult (JustUB _) errs -> errs-      LResult NothingUB errs@(_, e) | not (isEmptyBag e) -> errs-                                    | otherwise -> pprPanic ("Bug in Lint: a failure occurred " ++-                                                      "without reporting an error message") empty-  where-    (tcvs, ids) = partition isTyCoVar $ l_vars cfg-    env = LE { le_flags = l_flags cfg-             , le_subst = mkEmptySubst (mkInScopeSetList tcvs)-             , le_ids   = mkVarEnv [(id, (id,idType id)) | id <- ids]-             , le_joins = emptyVarSet-             , le_loc = []-             , le_ue_aliases = emptyNameEnv-             , le_platform = l_platform cfg-             , le_diagOpts = l_diagOpts cfg-             }--setReportUnsat :: Bool -> LintM a -> LintM a--- Switch off lf_report_unsat_syns-setReportUnsat ru thing_inside-  = LintM $ \ env errs ->-    let env' = env { le_flags = (le_flags env) { lf_report_unsat_syns = ru } }-    in unLintM thing_inside env' errs---- See Note [Checking for representation polymorphism]-noFixedRuntimeRepChecks :: LintM a -> LintM a-noFixedRuntimeRepChecks thing_inside-  = LintM $ \env errs ->-    let env' = env { le_flags = (le_flags env) { lf_check_fixed_rep = False } }-    in unLintM thing_inside env' errs--getLintFlags :: LintM LintFlags-getLintFlags = LintM $ \ env errs -> fromBoxedLResult (Just (le_flags env), errs)--checkL :: Bool -> SDoc -> LintM ()-checkL True  _   = return ()-checkL False msg = failWithL msg---- like checkL, but relevant to type checking-lintL :: Bool -> SDoc -> LintM ()-lintL = checkL--checkWarnL :: Bool -> SDoc -> LintM ()-checkWarnL True   _  = return ()-checkWarnL False msg = addWarnL msg--failWithL :: SDoc -> LintM a-failWithL msg = LintM $ \ env (warns,errs) ->-                fromBoxedLResult (Nothing, (warns, addMsg True env errs msg))--addErrL :: SDoc -> LintM ()-addErrL msg = LintM $ \ env (warns,errs) ->-              fromBoxedLResult (Just (), (warns, addMsg True env errs msg))--addWarnL :: SDoc -> LintM ()-addWarnL msg = LintM $ \ env (warns,errs) ->-              fromBoxedLResult (Just (), (addMsg False env warns msg, errs))--addMsg :: Bool -> LintEnv ->  Bag SDoc -> SDoc -> Bag SDoc-addMsg is_error env msgs msg-  = assertPpr (notNull loc_msgs) msg $-    msgs `snocBag` mk_msg msg-  where-   loc_msgs :: [(SrcLoc, SDoc)]  -- Innermost first-   loc_msgs = map dumpLoc (le_loc env)--   cxt_doc = vcat [ vcat $ reverse $ map snd loc_msgs-                  , text "Substitution:" <+> ppr (le_subst env) ]-   context | is_error  = cxt_doc-           | otherwise = whenPprDebug cxt_doc-     -- Print voluminous info for Lint errors-     -- but not for warnings--   msg_span = case [ span | (loc,_) <- loc_msgs-                          , let span = srcLocSpan loc-                          , isGoodSrcSpan span ] of-               []    -> noSrcSpan-               (s:_) -> s-   !diag_opts = le_diagOpts env-   mk_msg msg = mkLocMessage (mkMCDiagnostic diag_opts WarningWithoutFlag Nothing) msg_span-                             (msg $$ context)--addLoc :: LintLocInfo -> LintM a -> LintM a-addLoc extra_loc m-  = LintM $ \ env errs ->-    unLintM m (env { le_loc = extra_loc : le_loc env }) errs--inCasePat :: LintM Bool         -- A slight hack; see the unique call site-inCasePat = LintM $ \ env errs -> fromBoxedLResult (Just (is_case_pat env), errs)-  where-    is_case_pat (LE { le_loc = CasePat {} : _ }) = True-    is_case_pat _other                           = False--addInScopeId :: Id -> LintedType -> LintM a -> LintM a-addInScopeId id linted_ty m-  = LintM $ \ env@(LE { le_ids = id_set, le_joins = join_set, le_ue_aliases = aliases }) errs ->-    unLintM m (env { le_ids   = extendVarEnv id_set id (id, linted_ty)-                   , le_joins = add_joins join_set-                   , le_ue_aliases = delFromNameEnv aliases (idName id) }) errs-                   -- When shadowing an alias, we need to make sure the Id is no longer-                   -- classified as such. E.g. in-                   -- let x = <e1> in case x of x { _DEFAULT -> <e2> }-                   -- Occurrences of 'x' in e2 shouldn't count as occurrences of e1.-  where-    add_joins join_set-      | isJoinId id = extendVarSet join_set id -- Overwrite with new arity-      | otherwise   = delVarSet    join_set id -- Remove any existing binding--getInScopeIds :: LintM (VarEnv (Id,LintedType))-getInScopeIds = LintM (\env errs -> fromBoxedLResult (Just (le_ids env), errs))--extendTvSubstL :: TyVar -> Type -> LintM a -> LintM a-extendTvSubstL tv ty m-  = LintM $ \ env errs ->-    unLintM m (env { le_subst = Type.extendTvSubst (le_subst env) tv ty }) errs--updateSubst :: Subst -> LintM a -> LintM a-updateSubst subst' m-  = LintM $ \ env errs -> unLintM m (env { le_subst = subst' }) errs--markAllJoinsBad :: LintM a -> LintM a-markAllJoinsBad m-  = LintM $ \ env errs -> unLintM m (env { le_joins = emptyVarSet }) errs--markAllJoinsBadIf :: Bool -> LintM a -> LintM a-markAllJoinsBadIf True  m = markAllJoinsBad m-markAllJoinsBadIf False m = m--getValidJoins :: LintM IdSet-getValidJoins = LintM (\ env errs -> fromBoxedLResult (Just (le_joins env), errs))--getSubst :: LintM Subst-getSubst = LintM (\ env errs -> fromBoxedLResult (Just (le_subst env), errs))--getUEAliases :: LintM (NameEnv UsageEnv)-getUEAliases = LintM (\ env errs -> fromBoxedLResult (Just (le_ue_aliases env), errs))--getInScope :: LintM InScopeSet-getInScope = LintM (\ env errs -> fromBoxedLResult (Just (getSubstInScope $ le_subst env), errs))--lookupIdInScope :: Id -> LintM (Id, LintedType)-lookupIdInScope id_occ-  = do { in_scope_ids <- getInScopeIds-       ; case lookupVarEnv in_scope_ids id_occ of-           Just (id_bndr, linted_ty)-             -> do { checkL (not (bad_global id_bndr)) $ global_in_scope id_bndr-                   ; return (id_bndr, linted_ty) }-           Nothing -> do { checkL (not is_local) local_out_of_scope-                         ; return (id_occ, idType id_occ) } }-                      -- We don't bother to lint the type-                      -- of global (i.e. imported) Ids-  where-    is_local = mustHaveLocalBinding id_occ-    local_out_of_scope = text "Out of scope:" <+> pprBndr LetBind id_occ-    global_in_scope id_bndr = hang (text "Occurrence is GlobalId, but binding is LocalId")-                                 2 $ vcat [hang (text "occurrence:") 2 $ pprBndr LetBind id_occ-                                          ,hang (text "binder    :") 2 $ pprBndr LetBind id_bndr-                                          ]-    bad_global id_bnd = isGlobalId id_occ-                     && isLocalId id_bnd-                     && not (isWiredIn id_occ)-       -- 'bad_global' checks for the case where an /occurrence/ is-       -- a GlobalId, but there is an enclosing binding fora a LocalId.-       -- NB: the in-scope variables are mostly LocalIds, checked by lintIdBndr,-       --     but GHCi adds GlobalIds from the interactive context.  These-       --     are fine; hence the test (isLocalId id == isLocalId v)-       -- NB: when compiling Control.Exception.Base, things like absentError-       --     are defined locally, but appear in expressions as (global)-       --     wired-in Ids after worker/wrapper-       --     So we simply disable the test in this case--lookupJoinId :: Id -> LintM JoinPointHood--- Look up an Id which should be a join point, valid here--- If so, return its arity, if not return Nothing-lookupJoinId id-  = do { join_set <- getValidJoins-       ; case lookupVarSet join_set id of-            Just id' -> return (idJoinPointHood id')-            Nothing  -> return NotJoinPoint }--addAliasUE :: Id -> UsageEnv -> LintM a -> LintM a-addAliasUE id ue thing_inside = LintM $ \ env errs ->-  let new_ue_aliases =-        extendNameEnv (le_ue_aliases env) (getName id) ue-  in-    unLintM thing_inside (env { le_ue_aliases = new_ue_aliases }) errs--varCallSiteUsage :: Id -> LintM UsageEnv-varCallSiteUsage id =-  do m <- getUEAliases-     return $ case lookupNameEnv m (getName id) of-         Nothing    -> singleUsageUE id-         Just id_ue -> id_ue--ensureEqTys :: LintedType -> LintedType -> SDoc -> LintM ()--- check ty2 is subtype of ty1 (ie, has same structure but usage--- annotations need only be consistent, not equal)--- Assumes ty1,ty2 are have already had the substitution applied-{-# INLINE ensureEqTys #-} -- See Note [INLINE ensureEqTys]-ensureEqTys ty1 ty2 msg-  = do { flags <- getLintFlags-       ; lintL (eq_type flags ty1 ty2) msg }--eq_type :: LintFlags -> Type -> Type -> Bool--- When `-dlinear-core-lint` is off, then consider `a -> b` and `a %1 -> b` to--- be equal. See Note [Linting linearity].-eq_type flags ty1 ty2 | lf_check_linearity flags = eqType                     ty1 ty2-                      | otherwise                = eqTypeIgnoringMultiplicity ty1 ty2--{- Note [INLINE ensureEqTys]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~-To make Lint fast, we want to avoid allocating a thunk for <msg> in-      ensureEqTypes ty1 ty2 <msg>-because the test almost always succeeds, and <msg> isn't needed.-So we INLINE `ensureEqTys`.  This actually make a difference of-1-2% when compiling programs with -dcore-lint.--}--ensureSubUsage :: Usage -> Mult -> SDoc -> LintM ()-ensureSubUsage Bottom     _              _ = return ()-ensureSubUsage Zero       described_mult err_msg = ensureSubMult ManyTy described_mult err_msg-ensureSubUsage (MUsage m) described_mult err_msg = ensureSubMult m described_mult err_msg--ensureSubMult :: Mult -> Mult -> SDoc -> LintM ()-ensureSubMult actual_mult described_mult err_msg = do-    flags <- getLintFlags-    when (lf_check_linearity flags) $-      unless (deepSubMult actual_mult described_mult) $-        addErrL err_msg-  where-    -- Check for submultiplicity using the following rules:-    -- 1. x*y <= z when x <= z and y <= z.-    --    This rule follows from the fact that x*y = sup{x,y} for any-    --    multiplicities x,y.-    -- 2. x <= y*z when x <= y or x <= z.-    --    This rule is not complete: when x = y*z, we cannot-    --    change y*z <= y*z to y*z <= y or y*z <= z.-    --    However, we eliminate products on the LHS in step 1.-    -- 3. One <= x and x <= Many for any x, as checked by 'submult'.-    -- 4. x <= x.-    -- Otherwise, we fail.-    deepSubMult :: Mult -> Mult -> Bool-    deepSubMult m n-      | Just (m1, m2) <- isMultMul m = deepSubMult m1 n  && deepSubMult m2 n-      | Just (n1, n2) <- isMultMul n = deepSubMult m  n1 || deepSubMult m  n2-      | Submult <- m `submult` n = True-      | otherwise = m `eqType` n--lintRole :: Outputable thing-          => thing     -- where the role appeared-          -> Role      -- expected-          -> Role      -- actual-          -> LintM ()-lintRole co r1 r2-  = lintL (r1 == r2)-          (text "Role incompatibility: expected" <+> ppr r1 <> comma <+>-           text "got" <+> ppr r2 $$-           text "in" <+> ppr co)--{--************************************************************************-*                                                                      *-\subsection{Error messages}-*                                                                      *-************************************************************************--}--dumpLoc :: LintLocInfo -> (SrcLoc, SDoc)--dumpLoc (RhsOf v)-  = (getSrcLoc v, text "In the RHS of" <+> pp_binders [v])--dumpLoc (OccOf v)-  = (getSrcLoc v, text "In an occurrence of" <+> pp_binder v)--dumpLoc (LambdaBodyOf b)-  = (getSrcLoc b, text "In the body of lambda with binder" <+> pp_binder b)--dumpLoc (RuleOf b)-  = (getSrcLoc b, text "In a rule attached to" <+> pp_binder b)--dumpLoc (UnfoldingOf b)-  = (getSrcLoc b, text "In the unfolding of" <+> pp_binder b)--dumpLoc (BodyOfLet b)-  = (noSrcLoc, text "In the body of a let with binder" <+> pp_binder b)--dumpLoc (BodyOfLetRec [])-  = (noSrcLoc, text "In body of a letrec with no binders")--dumpLoc (BodyOfLetRec bs@(b:_))-  = ( getSrcLoc b, text "In the body of a letrec with binders" <+> pp_binders bs)--dumpLoc (AnExpr e)-  = (noSrcLoc, text "In the expression:" <+> ppr e)--dumpLoc (CaseAlt (Alt con args _))-  = (noSrcLoc, text "In a case alternative:" <+> parens (ppr con <+> pp_binders args))--dumpLoc (CasePat (Alt con args _))-  = (noSrcLoc, text "In the pattern of a case alternative:" <+> parens (ppr con <+> pp_binders args))--dumpLoc (CaseTy scrut)-  = (noSrcLoc, hang (text "In the result-type of a case with scrutinee:")-                  2 (ppr scrut))--dumpLoc (IdTy b)-  = (getSrcLoc b, text "In the type of a binder:" <+> ppr b)--dumpLoc (ImportedUnfolding locn)-  = (locn, text "In an imported unfolding")-dumpLoc TopLevelBindings-  = (noSrcLoc, Outputable.empty)-dumpLoc (InType ty)-  = (noSrcLoc, text "In the type" <+> quotes (ppr ty))-dumpLoc (InCo co)-  = (noSrcLoc, text "In the coercion" <+> quotes (ppr co))-dumpLoc (InAxiom ax)-  = (getSrcLoc ax, hang (text "In the coercion axiom")-                      2 (pprCoAxiom ax))--pp_binders :: [Var] -> SDoc-pp_binders bs = sep (punctuate comma (map pp_binder bs))--pp_binder :: Var -> SDoc-pp_binder b | isId b    = hsep [ppr b, dcolon, ppr (idType b)]-            | otherwise = hsep [ppr b, dcolon, ppr (tyVarKind b)]-----------------------------------------------------------      Messages for case expressions--mkDefaultArgsMsg :: [Var] -> SDoc-mkDefaultArgsMsg args-  = hang (text "DEFAULT case with binders")-         4 (ppr args)--mkCaseAltMsg :: CoreExpr -> Type -> Type -> SDoc-mkCaseAltMsg e ty1 ty2-  = hang (text "Type of case alternatives not the same as the annotation on case:")-         4 (vcat [ text "Actual type:" <+> ppr ty1,-                   text "Annotation on case:" <+> ppr ty2,-                   text "Alt Rhs:" <+> ppr e ])--mkScrutMsg :: Id -> Type -> Type -> Subst -> SDoc-mkScrutMsg var var_ty scrut_ty subst-  = vcat [text "Result binder in case doesn't match scrutinee:" <+> ppr var,-          text "Result binder type:" <+> ppr var_ty,--(idType var),-          text "Scrutinee type:" <+> ppr scrut_ty,-     hsep [text "Current TCv subst", ppr subst]]--mkNonDefltMsg, mkNonIncreasingAltsMsg :: CoreExpr -> SDoc-mkNonDefltMsg e-  = hang (text "Case expression with DEFAULT not at the beginning") 4 (ppr e)-mkNonIncreasingAltsMsg e-  = hang (text "Case expression with badly-ordered alternatives") 4 (ppr e)--nonExhaustiveAltsMsg :: CoreExpr -> SDoc-nonExhaustiveAltsMsg e-  = hang (text "Case expression with non-exhaustive alternatives") 4 (ppr e)--mkBadConMsg :: TyCon -> DataCon -> SDoc-mkBadConMsg tycon datacon-  = vcat [-        text "In a case alternative, data constructor isn't in scrutinee type:",-        text "Scrutinee type constructor:" <+> ppr tycon,-        text "Data con:" <+> ppr datacon-    ]--mkBadPatMsg :: Type -> Type -> SDoc-mkBadPatMsg con_result_ty scrut_ty-  = vcat [-        text "In a case alternative, pattern result type doesn't match scrutinee type:",-        text "Pattern result type:" <+> ppr con_result_ty,-        text "Scrutinee type:" <+> ppr scrut_ty-    ]--integerScrutinisedMsg :: SDoc-integerScrutinisedMsg-  = text "In a LitAlt, the literal is lifted (probably Integer)"--mkBadAltMsg :: Type -> CoreAlt -> SDoc-mkBadAltMsg scrut_ty alt-  = vcat [ text "Data alternative when scrutinee is not a tycon application",-           text "Scrutinee type:" <+> ppr scrut_ty,-           text "Alternative:" <+> pprCoreAlt alt ]--mkNewTyDataConAltMsg :: Type -> CoreAlt -> SDoc-mkNewTyDataConAltMsg scrut_ty alt-  = vcat [ text "Data alternative for newtype datacon",-           text "Scrutinee type:" <+> ppr scrut_ty,-           text "Alternative:" <+> pprCoreAlt alt ]------------------------------------------------------------      Other error messages--mkAppMsg :: Type -> Type -> CoreExpr -> SDoc-mkAppMsg expected_arg_ty actual_arg_ty arg-  = vcat [text "Argument value doesn't match argument type:",-              hang (text "Expected arg type:") 4 (ppr expected_arg_ty),-              hang (text "Actual arg type:") 4 (ppr actual_arg_ty),-              hang (text "Arg:") 4 (ppr arg)]--mkNonFunAppMsg :: Type -> Type -> CoreExpr -> SDoc-mkNonFunAppMsg fun_ty arg_ty arg-  = vcat [text "Non-function type in function position",-              hang (text "Fun type:") 4 (ppr fun_ty),-              hang (text "Arg type:") 4 (ppr arg_ty),-              hang (text "Arg:") 4 (ppr arg)]--mkLetErr :: TyVar -> CoreExpr -> SDoc-mkLetErr bndr rhs-  = vcat [text "Bad `let' binding:",-          hang (text "Variable:")-                 4 (ppr bndr <+> dcolon <+> ppr (varType bndr)),-          hang (text "Rhs:")-                 4 (ppr rhs)]--mkTyAppMsg :: Type -> Type -> SDoc-mkTyAppMsg ty arg_ty-  = vcat [text "Illegal type application:",-              hang (text "Function type:")-                 4 (ppr ty <+> dcolon <+> ppr (typeKind ty)),-              hang (text "Type argument:")-                 4 (ppr arg_ty <+> dcolon <+> ppr (typeKind arg_ty))]--mkCoAppMsg :: Type -> Coercion -> SDoc-mkCoAppMsg fun_ty co-  = vcat [ text "Illegal coercion application:"-         , hang (text "Function type:")-              4 (ppr fun_ty)-         , hang (text "Coercion argument:")-              4 (ppr co <+> dcolon <+> ppr (coercionType co))]--emptyRec :: CoreExpr -> SDoc-emptyRec e = hang (text "Empty Rec binding:") 2 (ppr e)--mkRhsMsg :: Id -> SDoc -> Type -> SDoc-mkRhsMsg binder what ty-  = vcat-    [hsep [text "The type of this binder doesn't match the type of its" <+> what <> colon,-            ppr binder],-     hsep [text "Binder's type:", ppr (idType binder)],-     hsep [text "Rhs type:", ppr ty]]--badBndrTyMsg :: Id -> SDoc -> SDoc-badBndrTyMsg binder what-  = vcat [ text "The type of this binder is" <+> what <> colon <+> ppr binder-         , text "Binder's type:" <+> ppr (idType binder) ]--mkNonTopExportedMsg :: Id -> SDoc-mkNonTopExportedMsg binder-  = hsep [text "Non-top-level binder is marked as exported:", ppr binder]--mkNonTopExternalNameMsg :: Id -> SDoc-mkNonTopExternalNameMsg binder-  = hsep [text "Non-top-level binder has an external name:", ppr binder]--mkTopNonLitStrMsg :: Id -> SDoc-mkTopNonLitStrMsg binder-  = hsep [text "Top-level Addr# binder has a non-literal rhs:", ppr binder]--mkKindErrMsg :: TyVar -> Type -> SDoc-mkKindErrMsg tyvar arg_ty-  = vcat [text "Kinds don't match in type application:",-          hang (text "Type variable:")-                 4 (ppr tyvar <+> dcolon <+> ppr (tyVarKind tyvar)),-          hang (text "Arg type:")-                 4 (ppr arg_ty <+> dcolon <+> ppr (typeKind arg_ty))]--mkCastErr :: CoreExpr -> Coercion -> Type -> Type -> SDoc-mkCastErr expr = mk_cast_err "expression" "type" (ppr expr)--mkCastTyErr :: Type -> Coercion -> Kind -> Kind -> SDoc-mkCastTyErr ty = mk_cast_err "type" "kind" (ppr ty)--mk_cast_err :: String -- ^ What sort of casted thing this is-                      --   (\"expression\" or \"type\").-            -> String -- ^ What sort of coercion is being used-                      --   (\"type\" or \"kind\").-            -> SDoc   -- ^ The thing being casted.-            -> Coercion -> Type -> Type -> SDoc-mk_cast_err thing_str co_str pp_thing co from_ty thing_ty-  = vcat [from_msg <+> text "of Cast differs from" <+> co_msg-            <+> text "of" <+> enclosed_msg,-          from_msg <> colon <+> ppr from_ty,-          text (capitalise co_str) <+> text "of" <+> enclosed_msg <> colon-            <+> ppr thing_ty,-          text "Actual" <+> enclosed_msg <> colon <+> pp_thing,-          text "Coercion used in cast:" <+> ppr co-         ]-  where-    co_msg, from_msg, enclosed_msg :: SDoc-    co_msg       = text co_str-    from_msg     = text "From-" <> co_msg-    enclosed_msg = text "enclosed" <+> text thing_str--mkBadTyVarMsg :: Var -> SDoc-mkBadTyVarMsg tv-  = text "Non-tyvar used in TyVarTy:"-      <+> ppr tv <+> dcolon <+> ppr (varType tv)--mkBadJoinBindMsg :: Var -> SDoc-mkBadJoinBindMsg var-  = vcat [ text "Bad join point binding:" <+> ppr var-         , text "Join points can be bound only by a non-top-level let" ]--mkInvalidJoinPointMsg :: Var -> Type -> SDoc-mkInvalidJoinPointMsg var ty-  = hang (text "Join point has invalid type:")-        2 (ppr var <+> dcolon <+> ppr ty)--mkBadJoinArityMsg :: Var -> Int -> Int -> CoreExpr -> SDoc-mkBadJoinArityMsg var ar n rhs-  = vcat [ text "Join point has too few lambdas",-           text "Join var:" <+> ppr var,-           text "Join arity:" <+> ppr ar,-           text "Number of lambdas:" <+> ppr (ar - n),-           text "Rhs = " <+> ppr rhs-           ]--invalidJoinOcc :: Var -> SDoc-invalidJoinOcc var-  = vcat [ text "Invalid occurrence of a join variable:" <+> ppr var-         , text "The binder is either not a join point, or not valid here" ]--mkBadJumpMsg :: Var -> Int -> Int -> SDoc-mkBadJumpMsg var ar nargs-  = vcat [ text "Join point invoked with wrong number of arguments",-           text "Join var:" <+> ppr var,-           text "Join arity:" <+> ppr ar,-           text "Number of arguments:" <+> int nargs ]--mkInconsistentRecMsg :: [Var] -> SDoc-mkInconsistentRecMsg bndrs-  = vcat [ text "Recursive let binders mix values and join points",-           text "Binders:" <+> hsep (map ppr_with_details bndrs) ]-  where-    ppr_with_details bndr = ppr bndr <> ppr (idDetails bndr)--mkJoinBndrOccMismatchMsg :: Var -> JoinArity -> JoinArity -> SDoc-mkJoinBndrOccMismatchMsg bndr join_arity_bndr join_arity_occ-  = vcat [ text "Mismatch in join point arity between binder and occurrence"-         , text "Var:" <+> ppr bndr-         , text "Arity at binding site:" <+> ppr join_arity_bndr-         , text "Arity at occurrence:  " <+> ppr join_arity_occ ]--mkBndrOccTypeMismatchMsg :: Var -> Var -> LintedType -> LintedType -> SDoc-mkBndrOccTypeMismatchMsg bndr var bndr_ty var_ty-  = vcat [ text "Mismatch in type between binder and occurrence"-         , text "Binder:" <+> ppr bndr <+> dcolon <+> ppr bndr_ty-         , text "Occurrence:" <+> ppr var <+> dcolon <+> ppr var_ty-         , text "  Before subst:" <+> ppr (idType var) ]++import GHC.Data.Bag+import GHC.Data.List.SetOps++import GHC.Utils.Monad+import GHC.Utils.Outputable as Outputable+import GHC.Utils.Panic+import GHC.Utils.Constants (debugIsOn)+import GHC.Utils.Misc+import GHC.Utils.Error+import qualified GHC.Utils.Error as Err+import GHC.Utils.Logger++import GHC.Data.Pair+import GHC.Base (oneShot)+import GHC.Data.Unboxed++import Control.Monad+import Data.Foldable      ( for_, toList )+import Data.List.NonEmpty ( NonEmpty(..), groupWith, nonEmpty )+import Data.Maybe+import Data.IntMap.Strict ( IntMap )+import qualified Data.IntMap.Strict as IntMap ( lookup, keys, empty, fromList )++{-+Note [Core Lint guarantee]+~~~~~~~~~~~~~~~~~~~~~~~~~~+Core Lint is the type-checker for Core. Using it, we get the following guarantee:++If all of:+1. Core Lint passes,+2. there are no unsafe coercions (i.e. unsafeEqualityProof),+3. all plugin-supplied coercions (i.e. PluginProv) are valid, and+4. all case-matches are complete+then running the compiled program will not seg-fault, assuming no bugs downstream+(e.g. in the code generator). This guarantee is quite powerful, in that it allows us+to decouple the safety of the resulting program from the type inference algorithm.++However, do note point (4) above. Core Lint does not check for incomplete case-matches;+see Note [Case expression invariants] in GHC.Core, invariant (4). As explained there,+an incomplete case-match might slip by Core Lint and cause trouble at runtime.++Note [GHC Formalism]+~~~~~~~~~~~~~~~~~~~~+This file implements the type-checking algorithm for System FC, the "official"+name of the Core language. Type safety of FC is heart of the claim that+executables produced by GHC do not have segmentation faults. Thus, it is+useful to be able to reason about System FC independently of reading the code.+To this purpose, there is a document core-spec.pdf built in docs/core-spec that+contains a formalism of the types and functions dealt with here. If you change+just about anything in this file or you change other types/functions throughout+the Core language (all signposted to this note), you should update that+formalism. See docs/core-spec/README for more info about how to do so.++Note [check vs lint]+~~~~~~~~~~~~~~~~~~~~+This file implements both a type checking algorithm and also general sanity+checking. For example, the "sanity checking" checks for TyConApp on the left+of an AppTy, which should never happen. These sanity checks don't really+affect any notion of type soundness. Yet, it is convenient to do the sanity+checks at the same time as the type checks. So, we use the following naming+convention:++- Functions that begin with 'lint'... are involved in type checking. These+  functions might also do some sanity checking.++- Functions that begin with 'check'... are *not* involved in type checking.+  They exist only for sanity checking.++Issues surrounding variable naming, shadowing, and such are considered *not*+to be part of type checking, as the formalism omits these details.++Summary of checks+~~~~~~~~~~~~~~~~~+Checks that a set of core bindings is well-formed.  The PprStyle and String+just control what we print in the event of an error.  The Bool value+indicates whether we have done any specialisation yet (in which case we do+some extra checks).++We check for+        (a) type errors+        (b) Out-of-scope type variables+        (c) Out-of-scope local variables+        (d) Ill-kinded types+        (e) Incorrect unsafe coercions++If we have done specialisation the we check that there are+        (a) No top-level bindings of primitive (unboxed type)++Note [Linting function types]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+All saturated applications of funTyCon are represented with the FunTy constructor.+See Note [Function type constructors and FunTy] in GHC.Builtin.Types.Prim++ We check this invariant in lintType.++Note [Linting type lets]+~~~~~~~~~~~~~~~~~~~~~~~~+In the desugarer, it's very very convenient to be able to say (in effect)+        let a = Type Bool in+        let x::a = True in <body>+That is, use a type let.  See Note [Core type and coercion invariant] in "GHC.Core".+One place it is used is in mkWwBodies; see Note [Join points and beta-redexes]+in GHC.Core.Opt.WorkWrap.Utils.  (Maybe there are other "clients" of this feature; I'm not sure).++* Hence when linting <body> we need to remember that a=Int, else we+  might reject a correct program.  So we carry a type substitution (in+  this example [a -> Bool]) and apply this substitution before+  comparing types. In effect, in Lint, type equality is always+  equality-modulo-le-subst.  This is in the le_subst field of+  LintEnv.  But nota bene:++  (SI1) The le_subst substitution is applied to types and coercions only++  (SI2) The result of that substitution is used only to check for type+        equality, to check well-typed-ness, /but is then discarded/.+        The result of substitution does not outlive the CoreLint pass.++  (SI3) The InScopeSet of le_subst includes only TyVar and CoVar binders.++* The function+        lintInTy :: Type -> LintM (Type, Kind)+  returns a substituted type.++* When we encounter a binder (like x::a) we must apply the substitution+  to the type of the binding variable.  lintBinders does this.++* Clearly we need to clone tyvar binders as we go.++* But take care (#17590)! We must also clone CoVar binders:+    let a = TYPE (ty |> cv)+    in \cv -> blah+  blindly substituting for `a` might capture `cv`.++* Alas, when cloning a coercion variable we might choose a unique+  that happens to clash with an inner Id, thus+      \cv_66 -> let wild_X7 = blah in blah+  We decide to clone `cv_66` because it's already in scope.  Fine,+  choose a new unique.  Aha, X7 looks good.  So we check the lambda+  body with le_subst of [cv_66 :-> cv_X7]++  This is all fine, even though we use the same unique as wild_X7.+  As (SI2) says, we do /not/ return a new lambda+     (\cv_X7 -> let wild_X7 = blah in ...)+  We simply use the le_subst substitution in types/coercions only, when+  checking for equality.++* We still need to check that Id occurrences are bound by some+  enclosing binding.  We do /not/ use the InScopeSet for the le_subst+  for this purpose -- it contains only TyCoVars.  Instead we have a separate+  le_ids for the in-scope Id binders.++Sigh.  We might want to explore getting rid of type-let!++Note [Bad unsafe coercion]+~~~~~~~~~~~~~~~~~~~~~~~~~~+For discussion see https://gitlab.haskell.org/ghc/ghc/wikis/bad-unsafe-coercions+Linter introduces additional rules that checks improper coercion between+different types, called bad coercions. Following coercions are forbidden:++  (a) coercions between boxed and unboxed values;+  (b) coercions between unlifted values of the different sizes, here+      active size is checked, i.e. size of the actual value but not+      the space allocated for value;+  (c) coercions between floating and integral boxed values, this check+      is not yet supported for unboxed tuples, as no semantics were+      specified for that;+  (d) coercions from / to vector type+  (e) If types are unboxed tuples then tuple (# A_1,..,A_n #) can be+      coerced to (# B_1,..,B_m #) if n=m and for each pair A_i, B_i rules+      (a-e) holds.++Note [Join points]+~~~~~~~~~~~~~~~~~~+We check the rules listed in Note [Invariants on join points] in GHC.Core. The+only one that causes any difficulty is the first: All occurrences must be tail+calls. To this end, along with the in-scope set, we remember in le_joins the+subset of in-scope Ids that are valid join ids. For example:++  join j x = ... in+  case e of+    A -> jump j y -- good+    B -> case (jump j z) of -- BAD+           C -> join h = jump j w in ... -- good+           D -> let x = jump j v in ... -- BAD++A join point remains valid in case branches, so when checking the A+branch, j is still valid. When we check the scrutinee of the inner+case, however, we set le_joins to empty, and catch the+error. Similarly, join points can occur free in RHSes of other join+points but not the RHSes of value bindings (thunks and functions).++Note [Avoiding compiler perf traps when constructing error messages.]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+It's quite common to put error messages into a where clause when it might+be triggered by multiple branches. E.g.++  checkThing x y z =+    case x of+      X -> unless (correctX x) $ failWithL errMsg+      Y -> unless (correctY y) $ failWithL errMsg+    where+      errMsg = text "My error involving:" $$ ppr x <+> ppr y++However ghc will compile this to:++  checkThink x y z =+    let errMsg = text "My error involving:" $$ ppr x <+> ppr y+    in case x of+      X -> unless (correctX x) $ failWithL errMsg+      Y -> unless (correctY y) $ failWithL errMsg++Putting the allocation of errMsg into the common non-error path.+One way to work around this is to turn errMsg into a function:++  checkThink x y z =+    case x of+      X -> unless (correctX x) $ failWithL (errMsg x y)+      Y -> unless (correctY y) $ failWithL (errMsg x y)+    where+      errMsg x y = text "My error involving:" $$ ppr x <+> ppr y++This way `errMsg` is a static function and it being defined in the common+path does not result in allocation in the hot path. This can be surprisingly+impactful. Changing `lint_app` reduced allocations for one test program I was+looking at by ~4%.++Note [MCInfo for Lint]+~~~~~~~~~~~~~~~~~~~~~~+When printing a Lint message, use the MCInfo severity so that the+message is printed on stderr rather than stdout (#13342).++************************************************************************+*                                                                      *+                 Beginning and ending passes+*                                                                      *+************************************************************************+-}++-- | Configuration for boilerplate operations at the end of a+-- compilation pass producing Core.+data EndPassConfig = EndPassConfig+  { ep_dumpCoreSizes :: !Bool+  -- ^ Whether core bindings should be dumped with the size of what they+  -- are binding (i.e. the size of the RHS of the binding).++  , ep_lintPassResult :: !(Maybe LintPassResultConfig)+  -- ^ Whether we should lint the result of this pass.++  , ep_namePprCtx :: !NamePprCtx++  , ep_dumpFlag :: !(Maybe DumpFlag)++  , ep_prettyPass :: !SDoc++  , ep_passDetails :: !SDoc+  }++endPassIO :: Logger+          -> EndPassConfig+          -> CoreProgram -> [CoreRule]+          -> IO ()+-- Used by the IO-is CorePrep too+endPassIO logger cfg binds rules+  = do { dumpPassResult logger (ep_dumpCoreSizes cfg) (ep_namePprCtx cfg) mb_flag+                        (renderWithContext defaultSDocContext (ep_prettyPass cfg))+                        (ep_passDetails cfg) binds rules+       ; for_ (ep_lintPassResult cfg) $ \lp_cfg ->+           lintPassResult logger lp_cfg binds+       }+  where+    mb_flag = case ep_dumpFlag cfg of+                Just flag | logHasDumpFlag logger flag                    -> Just flag+                          | logHasDumpFlag logger Opt_D_verbose_core2core -> Just flag+                _ -> Nothing++dumpPassResult :: Logger+               -> Bool                  -- dump core sizes?+               -> NamePprCtx+               -> Maybe DumpFlag        -- Just df => show details in a file whose+                                        --            name is specified by df+               -> String                -- Header+               -> SDoc                  -- Extra info to appear after header+               -> CoreProgram -> [CoreRule]+               -> IO ()+dumpPassResult logger dump_core_sizes name_ppr_ctx mb_flag hdr extra_info binds rules+  = do { forM_ mb_flag $ \flag -> do+           logDumpFile logger (mkDumpStyle name_ppr_ctx) flag hdr FormatCore dump_doc++         -- Report result size+         -- This has the side effect of forcing the intermediate to be evaluated+         -- if it's not already forced by a -ddump flag.+       ; Err.debugTraceMsg logger 2 size_doc+       }++  where+    size_doc = sep [text "Result size of" <+> text hdr, nest 2 (equals <+> ppr (coreBindsStats binds))]++    dump_doc  = vcat [ nest 2 extra_info+                     , size_doc+                     , blankLine+                     , if dump_core_sizes+                        then pprCoreBindingsWithSize binds+                        else pprCoreBindings         binds+                     , ppUnless (null rules) pp_rules ]+    pp_rules = vcat [ blankLine+                    , text "------ Local rules for imported ids --------"+                    , pprRules rules ]++{-+************************************************************************+*                                                                      *+                 Top-level interfaces+*                                                                      *+************************************************************************+-}++data LintPassResultConfig = LintPassResultConfig+  { lpr_diagOpts         :: !DiagOpts+  , lpr_platform         :: !Platform+  , lpr_makeLintFlags    :: !LintFlags+  , lpr_showLintWarnings :: !Bool+  , lpr_passPpr          :: !SDoc+  , lpr_localsInScope    :: ![Var]+  }++lintPassResult :: Logger -> LintPassResultConfig+               -> CoreProgram -> IO ()+lintPassResult logger cfg binds+  = do { let warns_and_errs = lintCoreBindings'+               (LintConfig+                { l_diagOpts = lpr_diagOpts cfg+                , l_platform = lpr_platform cfg+                , l_flags    = lpr_makeLintFlags cfg+                , l_vars     = lpr_localsInScope cfg+                })+               binds+       ; Err.showPass logger $+           "Core Linted result of " +++           renderWithContext defaultSDocContext (lpr_passPpr cfg)+       ; displayLintResults logger+                            (lpr_showLintWarnings cfg) (lpr_passPpr cfg)+                            (pprCoreBindings binds) warns_and_errs+       }++displayLintResults :: Logger+                   -> Bool -- ^ If 'True', display linter warnings.+                           --   If 'False', ignore linter warnings.+                   -> SDoc -- ^ The source of the linted program+                   -> SDoc -- ^ The linted program, pretty-printed+                   -> WarnsAndErrs+                   -> IO ()+displayLintResults logger display_warnings pp_what pp_pgm (warns, errs)+  | not (isEmptyBag errs)+  = do { logMsg logger Err.MCInfo noSrcSpan  -- See Note [MCInfo for Lint]+           $ withPprStyle defaultDumpStyle+           (vcat [ lint_banner "errors" pp_what, Err.pprMessageBag errs+                 , text "*** Offending Program ***"+                 , pp_pgm+                 , text "*** End of Offense ***" ])+       ; Err.ghcExit logger 1 }++  | not (isEmptyBag warns)+  , log_enable_debug (logFlags logger)+  , display_warnings+  = logMsg logger Err.MCInfo noSrcSpan  -- See Note [MCInfo for Lint]+      $ withPprStyle defaultDumpStyle+        (lint_banner "warnings" pp_what $$ Err.pprMessageBag (mapBag ($$ blankLine) warns))++  | otherwise = return ()++lint_banner :: String -> SDoc -> SDoc+lint_banner string pass = text "*** Core Lint"      <+> text string+                          <+> text ": in result of" <+> pass+                          <+> text "***"++-- | Type-check a 'CoreProgram'. See Note [Core Lint guarantee].+lintCoreBindings' :: LintConfig -> CoreProgram -> WarnsAndErrs+--   Returns (warnings, errors)+-- If you edit this function, you may need to update the GHC formalism+-- See Note [GHC Formalism]+lintCoreBindings' cfg binds+  = initL cfg $+    addLoc TopLevelBindings           $+    do { -- Check that all top-level binders are distinct+         -- We do not allow  [NonRec x=1, NonRec y=x, NonRec x=2]+         -- because of glomming; see Note [Glomming] in GHC.Core.Opt.OccurAnal+         checkL (null dups) (dupVars dups)++         -- Check for External top level binders with the same M.n name+       ; checkL (null ext_dups) (dupExtVars ext_dups)++         -- Typecheck the bindings+       ; lintRecBindings TopLevel all_pairs $ \_ ->+         return () }+  where+    all_pairs = flattenBinds binds+     -- Put all the top-level binders in scope at the start+     -- This is because rewrite rules can bring something+     -- into use 'unexpectedly'; see Note [Glomming] in "GHC.Core.Opt.OccurAnal"+    binders = map fst all_pairs++    (_, dups) = removeDups compare binders++    -- ext_dups checks for names with different uniques+    -- but the same External name M.n.  We don't+    -- allow this at top level:+    --    M.n{r3}  = ...+    --    M.n{r29} = ...+    -- because they both get the same linker symbol+    ext_dups = snd $ removeDupsOn ord_ext $+               filter isExternalName $ map Var.varName binders+    ord_ext n = (nameModule n, nameOccName n)++{-+************************************************************************+*                                                                      *+\subsection[lintUnfolding]{lintUnfolding}+*                                                                      *+************************************************************************++Note [Linting Unfoldings from Interfaces]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+We use this to check all top-level unfoldings that come in from interfaces+(it is very painful to catch errors otherwise).++We do not need to call lintUnfolding on unfoldings that are nested within+top-level unfoldings; they are linted when we lint the top-level unfolding;+hence the `TopLevelFlag` on `tcPragExpr` in GHC.IfaceToCore.++-}++lintUnfolding :: Bool             -- ^ True <=> is a compulsory unfolding+              -> LintConfig+              -> SrcLoc+              -> CoreExpr+              -> Maybe (Bag SDoc) -- Nothing => OK++lintUnfolding is_compulsory cfg locn expr+  | isEmptyBag errs = Nothing+  | otherwise       = Just errs+  where+    (_warns, errs) = initL cfg $+                     if is_compulsory+                       -- See Note [Checking for representation polymorphism]+                     then noFixedRuntimeRepChecks linter+                     else linter+    linter = addLoc (ImportedUnfolding locn) $+             lintCoreExpr expr++lintExpr :: LintConfig+         -> CoreExpr+         -> Maybe (Bag SDoc)  -- Nothing => OK++lintExpr cfg expr+  | isEmptyBag errs = Nothing+  | otherwise       = Just errs+  where+    (_warns, errs) = initL cfg linter+    linter = addLoc TopLevelBindings $+             lintCoreExpr expr++{-+************************************************************************+*                                                                      *+\subsection[lintCoreBinding]{lintCoreBinding}+*                                                                      *+************************************************************************++Check a core binding, returning the list of variables bound.+-}++-- Returns a UsageEnv because this function is called in lintCoreExpr for+-- Let++lintRecBindings :: TopLevelFlag -> [(Id, CoreExpr)]+                -> ([OutId] -> LintM a) -> LintM (a, [UsageEnv])+lintRecBindings top_lvl pairs thing_inside+  = lintIdBndrs top_lvl bndrs $ \ bndrs' ->+    do { ues <- zipWithM lint_pair bndrs' rhss+       ; a <- thing_inside bndrs'+       ; return (a, ues) }+  where+    (bndrs, rhss) = unzip pairs+    lint_pair bndr' rhs+      = addLoc (RhsOf bndr') $+        do { (rhs_ty, ue) <- lintRhs bndr' rhs         -- Check the rhs+           ; lintLetBind top_lvl Recursive bndr' rhs rhs_ty+           ; return ue }++lintLetBody :: LintLocInfo -> [OutId] -> CoreExpr -> LintM (OutType, UsageEnv)+lintLetBody loc bndrs body+  = do { (body_ty, body_ue) <- addLoc loc (lintCoreExpr body)+       ; mapM_ (lintJoinBndrType body_ty) bndrs+       ; return (body_ty, body_ue) }++lintLetBind :: TopLevelFlag -> RecFlag -> OutId+              -> CoreExpr -> OutType -> LintM ()+-- Binder's type, and the RHS, have already been linted+-- This function checks other invariants+lintLetBind top_lvl rec_flag binder rhs rhs_ty+  = do { let binder_ty = idType binder+       ; ensureEqTys binder_ty rhs_ty (mkRhsMsg binder (text "RHS") rhs_ty)++       -- If the binding is for a CoVar, the RHS should be (Coercion co)+       -- See Note [Core type and coercion invariant] in GHC.Core+       ; checkL (not (isCoVar binder) || isCoArg rhs)+                (mkLetErr binder rhs)++        -- Check the let-can-float invariant+        -- See Note [Core let-can-float invariant] in GHC.Core+       ; checkL ( isJoinId binder+               || mightBeLiftedType binder_ty+               || (isNonRec rec_flag && exprOkForSpeculation rhs)+               || isDataConWorkId binder || isDataConWrapId binder -- until #17521 is fixed+               || exprIsTickedString rhs)+           (badBndrTyMsg binder (text "unlifted"))++        -- Check that if the binder is at the top level and has type Addr#,+        -- that it is a string literal.+        -- See Note [Core top-level string literals].+       ; checkL (not (isTopLevel top_lvl && binder_ty `eqType` addrPrimTy)+                 || exprIsTickedString rhs)+           (mkTopNonLitStrMsg binder)++       ; flags <- getLintFlags++         -- Check that a join-point binder has a valid type+         -- NB: lintIdBinder has checked that it is not top-level bound+       ; case idJoinPointHood binder of+            NotJoinPoint    -> return ()+            JoinPoint arity ->  checkL (isValidJoinPointType arity binder_ty)+                                       (mkInvalidJoinPointMsg binder binder_ty)++       ; when (lf_check_inline_loop_breakers flags+               && isStableUnfolding (realIdUnfolding binder)+               && isStrongLoopBreaker (idOccInfo binder)+               && isInlinePragma (idInlinePragma binder))+              (addWarnL (text "INLINE binder is (non-rule) loop breaker:" <+> ppr binder))+              -- Only non-rule loop breakers inhibit inlining++       -- We used to check that the dmdTypeDepth of a demand signature never+       -- exceeds idArity, but that is an unnecessary complication, see+       -- Note [idArity varies independently of dmdTypeDepth] in GHC.Core.Opt.DmdAnal++       -- Check that the binder's arity is within the bounds imposed by the type+       -- and the strictness signature. See Note [Arity invariants for bindings]+       -- and Note [Trimming arity]++       ; checkL (typeArity (idType binder) >= idArity binder)+           (text "idArity" <+> ppr (idArity binder) <+>+           text "exceeds typeArity" <+>+           ppr (typeArity (idType binder)) <> colon <+>+           ppr binder)++       -- See Note [idArity varies independently of dmdTypeDepth]+       --     in GHC.Core.Opt.DmdAnal+       ; case splitDmdSig (idDmdSig binder) of+           (demands, result_info) | isDeadEndDiv result_info ->+              if (demands `lengthAtLeast` idArity binder)+              then return ()+              else pprTrace "Hack alert: lintLetBind #24623"+                       (ppr (idArity binder) $$ ppr (idDmdSig binder)) $+                   return ()+--             checkL (demands `lengthAtLeast` idArity binder)+--               (text "idArity" <+> ppr (idArity binder) <+>+--               text "exceeds arity imposed by the strictness signature" <+>+--               ppr (idDmdSig binder) <> colon <+>+--               ppr binder)++           _ -> return ()++       ; addLoc (RuleOf binder) $ mapM_ (lintCoreRule binder binder_ty) (idCoreRules binder)++       ; addLoc (UnfoldingOf binder) $+         lintIdUnfolding binder binder_ty (idUnfolding binder)+       ; return () }++        -- We should check the unfolding, if any, but this is tricky because+        -- the unfolding is a SimplifiableCoreExpr. Give up for now.++-- | Checks the RHS of bindings. It only differs from 'lintCoreExpr'+-- in that it doesn't reject occurrences of the function 'makeStatic' when they+-- appear at the top level and @lf_check_static_ptrs == AllowAtTopLevel@, and+-- for join points, it skips the outer lambdas that take arguments to the+-- join point.+--+-- See Note [Checking StaticPtrs].+lintRhs :: Id -> CoreExpr -> LintM (OutType, UsageEnv)+-- NB: the Id can be Linted or not -- it's only used for+--     its OccInfo and join-pointer-hood+lintRhs bndr rhs+    | JoinPoint arity <- idJoinPointHood bndr+    = lintJoinLams arity (Just bndr) rhs+    | AlwaysTailCalled arity <- tailCallInfo (idOccInfo bndr)+    = lintJoinLams arity Nothing rhs++-- Allow applications of the data constructor @StaticPtr@ at the top+-- but produce errors otherwise.+lintRhs _bndr rhs = fmap lf_check_static_ptrs getLintFlags >>= go+  where+    -- Allow occurrences of 'makeStatic' at the top-level but produce errors+    -- otherwise.+    go :: StaticPtrCheck -> LintM (OutType, UsageEnv)+    go AllowAtTopLevel+      | (binders0, rhs') <- collectTyBinders rhs+      , Just (fun, t, info, e) <- collectMakeStaticArgs rhs'+      = markAllJoinsBad $+        foldr+        -- imitate @lintCoreExpr (Lam ...)@+        lintLambda+        -- imitate @lintCoreExpr (App ...)@+        (do fun_ty_ue <- lintCoreExpr fun+            lintCoreArgs fun_ty_ue [Type t, info, e]+        )+        binders0+    go _ = markAllJoinsBad $ lintCoreExpr rhs++-- | Lint the RHS of a join point with expected join arity of @n@ (see Note+-- [Join points] in "GHC.Core").+lintJoinLams :: JoinArity -> Maybe Id -> CoreExpr -> LintM (OutType, UsageEnv)+lintJoinLams join_arity enforce rhs+  = go join_arity rhs+  where+    go 0 expr            = lintCoreExpr expr+    go n (Lam var body)  = lintLambda var $ go (n-1) body+    go n expr | Just bndr <- enforce -- Join point with too few RHS lambdas+              = failWithL $ mkBadJoinArityMsg bndr join_arity n rhs+              | otherwise -- Future join point, not yet eta-expanded+              = markAllJoinsBad $ lintCoreExpr expr+                -- Body of lambda is not a tail position++lintIdUnfolding :: Id -> Type -> Unfolding -> LintM ()+lintIdUnfolding bndr bndr_ty uf+  | isStableUnfolding uf+  , Just rhs <- maybeUnfoldingTemplate uf+  = do { ty <- fst <$> (if isCompulsoryUnfolding uf+                        then noFixedRuntimeRepChecks $ lintRhs bndr rhs+            --               ^^^^^^^^^^^^^^^^^^^^^^^+            -- See Note [Checking for representation polymorphism]+                        else lintRhs bndr rhs)+       ; ensureEqTys bndr_ty ty (mkRhsMsg bndr (text "unfolding") ty) }+lintIdUnfolding  _ _ _+  = return ()       -- Do not Lint unstable unfoldings, because that leads+                    -- to exponential behaviour; c.f. GHC.Core.FVs.idUnfoldingVars++{- Note [Checking for INLINE loop breakers]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+It's very suspicious if a strong loop breaker is marked INLINE.++However, the desugarer generates instance methods with INLINE pragmas+that form a mutually recursive group.  Only after a round of+simplification are they unravelled.  So we suppress the test for+the desugarer.  Here is an example:+  instance Eq T where+    t1 == t2 = blah+    t1 /= t2 = not (t1 == t2)+    {-# INLINE (/=) #-}++This will generate something like+    -- From the class decl for Eq+    data Eq a = EqDict (a->a->Bool) (a->a->Bool)+    eq_sel :: Eq a -> (a->a->Bool)+    eq_sel (EqDict eq _) = eq++    -- From the instance Eq T+    $ceq :: T -> T -> Bool+    $ceq = blah++    Rec { $dfEqT :: Eq T {-# DFunId #-}+          $dfEqT = EqDict $ceq $cnoteq++          $cnoteq :: T -> T -> Bool  {-# INLINE #-}+          $cnoteq x y = not (eq_sel $dfEqT x y) }++Notice that++* `$dfEqT` and `$cnotEq` are mutually recursive.++* We do not want `$dfEqT` to be the loop breaker: it's a DFunId, and+  we want to let it "cancel" with "eq_sel" (see Note [ClassOp/DFun+  selection] in GHC.Tc.TyCl.Instance, which it can't do if it's a loop+  breaker.++So we make `$cnoteq` into the loop breaker. That means it can't+inline, despite the INLINE pragma. That's what gives rise to the+warning, which is perfectly appropriate for, say+   Rec { {-# INLINE f #-}  f = \x -> ...f.... }+We can't inline a recursive function -- it's a loop breaker.++But now we can optimise `eq_sel $dfEqT` to `$ceq`, so we get+  Rec {+    $dfEqT :: Eq T {-# DFunId #-}+    $dfEqT = EqDict $ceq $cnoteq++    $cnoteq :: T -> T -> Bool  {-# INLINE #-}+    $cnoteq x y = not ($ceq x y) }++and now the dependencies of the Rec have gone, and we can split it up to give+    NonRec {  $dfEqT :: Eq T {-# DFunId #-}+              $dfEqT = EqDict $ceq $cnoteq }++    NonRec {  $cnoteq :: T -> T -> Bool  {-# INLINE #-}+              $cnoteq x y = not ($ceq x y) }++Now $cnoteq is not a loop breaker any more, so the INLINE pragma can+take effect -- the warning turned out to be temporary.++To stop excessive warnings, this warning for INLINE loop breakers is+switched off when linting the result of the desugarer.  See+lf_check_inline_loop_breakers in GHC.Core.Lint.+++Note [Checking for representation polymorphism]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+We ordinarily want to check for bad representation polymorphism. See+Note [Representation polymorphism invariants] in GHC.Core. However, we do *not*+want to do this in a compulsory unfolding. Compulsory unfoldings arise+only internally, for things like newtype wrappers, dictionaries, and+(notably) unsafeCoerce#. These might legitimately be representation-polymorphic;+indeed representation-polymorphic unfoldings are a primary reason for the+very existence of compulsory unfoldings (we can't compile code for+the original, representation-polymorphic, binding).++It is vitally important that we do representation polymorphism checks *after*+performing the unfolding, but not beforehand. This is all safe because+we will check any unfolding after it has been unfolded; checking the+unfolding beforehand is merely an optimization, and one that actively+hurts us here.++Note [Linting of runRW#]+~~~~~~~~~~~~~~~~~~~~~~~~+runRW# has some very special behavior (see Note [runRW magic] in+GHC.CoreToStg.Prep) which CoreLint must accommodate, by allowing+join points in its argument.  For example, this is fine:++    join j x = ...+    in runRW#  (\s. case v of+                       A -> j 3+                       B -> j 4)++Usually those calls to the join point 'j' would not be valid tail calls,+because they occur in a function argument.  But in the case of runRW#+they are fine, because runRW# (\s.e) behaves operationally just like e.+(runRW# is ultimately inlined in GHC.CoreToStg.Prep.)++In the case that the continuation is /not/ a lambda we simply disable this+special behaviour.  For example, this is /not/ fine:++    join j = ...+    in runRW# @r @ty (jump j)++Note [Coercions in terms]+~~~~~~~~~~~~~~~~~~~~~~~~~+The expression (Type ty) can occur only as the argument of an application,+or the RHS of a non-recursive Let.  But what about (Coercion co)?++Currently it appears in ghc-prim:GHC.Types.coercible_sel, a WiredInId whose+definition is:+   coercible_sel :: Coercible a b => (a ~R# b)+   coercible_sel d = case d of+                         MkCoercibleDict (co :: a ~# b) -> Coercion co++So this function has a (Coercion co) in the alternative of a case.++Richard says (!11908): it shouldn't appear outside of arguments, but we've been+loose about this. coercible_sel is some thin ice. Really we should be unpacking+Coercible using case, not a selector. I recall looking into this a few years+back and coming to the conclusion that the fix was worse than the disease. Don't+remember the details, but could probably recover it if we want to revisit.++So Lint current accepts (Coercion co) in arbitrary places.  There is no harm in+that: it really is a value, albeit a zero-bit value.++************************************************************************+*                                                                      *+\subsection[lintCoreExpr]{lintCoreExpr}+*                                                                      *+************************************************************************+-}++lintCoreExpr :: InExpr -> LintM (OutType, UsageEnv)+-- The returned type has the substitution from the monad+-- already applied to it:+--      lintCoreExpr e subst = exprType (subst e)+--+-- The returned "type" can be a kind, if the expression is (Type ty)++-- If you edit this function, you may need to update the GHC formalism+-- See Note [GHC Formalism]++lintCoreExpr (Var var)+  = do {  var_pair@(var_ty, _) <- lintIdOcc var 0+           -- See Note [Linting representation-polymorphic builtins]+       ; checkRepPolyBuiltin (Var var) [] var_ty+           --checkDataToTagPrimOpTyCon (Var var) []+       ; return var_pair }++lintCoreExpr (Lit lit)+  = return (literalType lit, zeroUE)++lintCoreExpr (Cast expr co)+  = do { (expr_ty, ue) <- markAllJoinsBad (lintCoreExpr expr)+            -- markAllJoinsBad: see Note [Join points and casts]++       ; lintCoercion co+       ; lintRole co Representational (coercionRole co)+       ; Pair from_ty to_ty <- substCoKindM co+       ; checkValueType (typeKind to_ty) $+         text "target of cast" <+> quotes (ppr co)+       ; ensureEqTys from_ty expr_ty (mkCastErr expr co from_ty expr_ty)+       ; return (to_ty, ue) }++lintCoreExpr (Tick tickish expr)+  = do { case tickish of+           Breakpoint _ _ ids -> forM_ ids $ \id -> lintIdOcc id 0+           _                  -> return ()+       ; markAllJoinsBadIf block_joins $ lintCoreExpr expr }+  where+    block_joins = not (tickish `tickishScopesLike` SoftScope)+      -- TODO Consider whether this is the correct rule. It is consistent with+      -- the simplifier's behaviour - cost-centre-scoped ticks become part of+      -- the continuation, and thus they behave like part of an evaluation+      -- context, but soft-scoped and non-scoped ticks simply wrap the result+      -- (see Simplify.simplTick).++lintCoreExpr (Let (NonRec tv (Type ty)) body)+  | isTyVar tv+  =     -- See Note [Linting type lets]+    do  { ty' <- lintTypeAndSubst ty+        ; lintTyCoBndr tv              $ \ tv' ->+    do  { addLoc (RhsOf tv) $ lintTyKind tv' ty'+                -- Now extend the substitution so we+                -- take advantage of it in the body+        ; extendTvSubstL tv ty' $+          addLoc (BodyOfLet tv) $+          lintCoreExpr body } }++lintCoreExpr (Let (NonRec bndr rhs) body)+  | isId bndr+  = do { -- First Lint the RHS, before bringing the binder into scope+         (rhs_ty, let_ue) <- lintRhs bndr rhs++          -- See Note [Multiplicity of let binders] in Var+         -- Now lint the binder+       ; lintBinder LetBind bndr $ \bndr' ->+    do { lintLetBind NotTopLevel NonRecursive bndr' rhs rhs_ty+       ; addAliasUE bndr' let_ue $+         lintLetBody (BodyOfLet bndr') [bndr'] body } }++  | otherwise+  = failWithL (mkLetErr bndr rhs)       -- Not quite accurate++lintCoreExpr e@(Let (Rec pairs) body)+  = do  { -- Check that the list of pairs is non-empty+          checkL (not (null pairs)) (emptyRec e)++          -- Check that there are no duplicated binders+        ; let (_, dups) = removeDups compare bndrs+        ; checkL (null dups) (dupVars dups)++          -- Check that either all the binders are joins, or none+        ; checkL (all isJoinId bndrs || all (not . isJoinId) bndrs) $+          mkInconsistentRecMsg bndrs++          -- See Note [Multiplicity of let binders] in Var+        ; ((body_type, body_ue), ues) <-+            lintRecBindings NotTopLevel pairs $ \ bndrs' ->+            lintLetBody (BodyOfLetRec bndrs') bndrs' body+        ; return (body_type, body_ue  `addUE` scaleUE ManyTy (foldr1WithDefault zeroUE addUE ues)) }+  where+    bndrs = map fst pairs++lintCoreExpr e@(App _ _)+  | Var fun <- fun+  , fun `hasKey` runRWKey+    -- See Note [Linting of runRW#]+    -- N.B. we may have an over-saturated application of the form:+    --   runRW (\s -> \x -> ...) y+  , ty_arg1 : ty_arg2 : cont_arg : rest <- args+  = do { let lint_rw_cont :: CoreArg -> Mult -> UsageEnv -> LintM (OutType, UsageEnv)+             lint_rw_cont expr@(Lam _ _) mult fun_ue+                = do { (arg_ty, arg_ue) <- lintJoinLams 1 (Just fun) expr+                     ; let app_ue = addUE fun_ue (scaleUE mult arg_ue)+                     ; return (arg_ty, app_ue) }++             lint_rw_cont expr mult ue+                = lintValArg expr mult ue+             -- TODO: Look through ticks?++       ; runrw_pr <- lintApp (text "runRW# expression")+                               lintTyArg lint_rw_cont+                               (idType fun) [ty_arg1,ty_arg2,cont_arg] zeroUE+       ; lintCoreArgs runrw_pr rest }++  | otherwise+  = do { fun_pair <- lintCoreFun fun (length args)+       ; app_pair@(app_ty, _) <- lintCoreArgs fun_pair args++       -- See Note [Linting representation-polymorphic builtins]+       ; checkRepPolyBuiltin fun args app_ty+       ; --checkDataToTagPrimOpTyCon fun args++       ; return app_pair}+  where+    skipTick t = case collectFunSimple e of+      (Var v) -> etaExpansionTick v t+      _ -> tickishFloatable t+    (fun, args, _source_ticks) = collectArgsTicks skipTick e+      -- We must look through source ticks to avoid #21152, for example:+      --+      -- reallyUnsafePtrEquality+      --   = \ @a ->+      --       (src<loc> reallyUnsafePtrEquality#)+      --         @Lifted @a @Lifted @a+      --+      -- To do this, we use `collectArgsTicks tickishFloatable` to match+      -- the eta expansion behaviour, as per Note [Eta expansion and source notes]+      -- in GHC.Core.Opt.Arity.+      -- Sadly this was not quite enough. So we now also accept things that CorePrep will allow.+      -- See Note [Ticks and mandatory eta expansion]++lintCoreExpr (Lam var expr)+  = markAllJoinsBad $+    lintLambda var $ lintCoreExpr expr++lintCoreExpr (Case scrut var alt_ty alts)+  = lintCaseExpr scrut var alt_ty alts++-- This case can't happen; linting types in expressions gets routed through lintTyArg+lintCoreExpr (Type ty)+  = failWithL (text "Type found as expression" <+> ppr ty)++lintCoreExpr (Coercion co)+  -- See Note [Coercions in terms]+  = do { addLoc (InCo co) $ lintCoercion co+       ; ty <- substTyM (coercionType co)+       ; return (ty, zeroUE) }++----------------------+lintIdOcc :: InId -> Int -- Number of arguments (type or value) being passed+          -> LintM (OutType, UsageEnv) -- returns type of the *variable*+lintIdOcc in_id nargs+  = addLoc (OccOf in_id) $+    do  { checkL (isNonCoVarId in_id)+                 (text "Non term variable" <+> ppr in_id)+                 -- See GHC.Core Note [Variable occurrences in Core]++        -- Check that the type of the occurrence is the same+        -- as the type of the binding site.  The inScopeIds are+        -- /un-substituted/, so this checks that the occurrence type+        -- is identical to the binder type.+        -- This makes things much easier for things like:+        --    /\a. \(x::Maybe a). /\a. ...(x::Maybe a)...+        -- The "::Maybe a" on the occurrence is referring to the /outer/ a.+        -- If we compared /substituted/ types we'd risk comparing+        -- (Maybe a) from the binding site with bogus (Maybe a1) from+        -- the occurrence site.  Comparing un-substituted types finesses+        -- this altogether+        ; out_ty <- lintVarOcc in_id++          -- Check for a nested occurrence of the StaticPtr constructor.+          -- See Note [Checking StaticPtrs].+        ; lf <- getLintFlags+        ; when (nargs /= 0 && lf_check_static_ptrs lf /= AllowAnywhere) $+            checkL (idName in_id /= makeStaticName) $+              text "Found makeStatic nested in an expression"++        ; checkDeadIdOcc in_id++        ; case isDataConId_maybe in_id of+             Nothing -> return ()+             Just dc -> checkTypeDataConOcc "expression" dc++        ; checkJoinOcc in_id nargs+        ; usage <- varCallSiteUsage in_id++        ; return (out_ty, usage) }++++lintCoreFun :: CoreExpr+            -> Int                          -- Number of arguments (type or val) being passed+            -> LintM (OutType, UsageEnv) -- Returns type of the *function*+lintCoreFun (Var var) nargs+  = lintIdOcc var nargs++lintCoreFun (Lam var body) nargs+  -- Act like lintCoreExpr of Lam, but *don't* call markAllJoinsBad;+  -- See Note [Beta redexes]+  | nargs /= 0+  = lintLambda var $ lintCoreFun body (nargs - 1)++lintCoreFun expr nargs+  = markAllJoinsBadIf (nargs /= 0) $+      -- See Note [Join points are less general than the paper]+    lintCoreExpr expr+------------------+lintLambda :: Var -> LintM (Type, UsageEnv) -> LintM (Type, UsageEnv)+lintLambda var lintBody =+    addLoc (LambdaBodyOf var) $+    lintBinder LambdaBind var $ \ var' ->+    do { (body_ty, ue) <- lintBody+       ; ue' <- checkLinearity ue var'+       ; return (mkLamType var' body_ty, ue') }+------------------+checkDeadIdOcc :: Id -> LintM ()+-- Occurrences of an Id should never be dead....+-- except when we are checking a case pattern+checkDeadIdOcc id+  | isDeadOcc (idOccInfo id)+  = do { in_case <- inCasePat+       ; checkL in_case+                (text "Occurrence of a dead Id" <+> ppr id) }+  | otherwise+  = return ()++------------------+lintJoinBndrType :: OutType -- Type of the body+                 -> OutId   -- Possibly a join Id+                -> LintM ()+-- Checks that the return type of a join Id matches the body+-- E.g. join j x = rhs in body+--      The type of 'rhs' must be the same as the type of 'body'+lintJoinBndrType body_ty bndr+  | JoinPoint arity <- idJoinPointHood bndr+  , let bndr_ty = idType bndr+  , (bndrs, res) <- splitPiTys bndr_ty+  = checkL (length bndrs >= arity+            && body_ty `eqType` mkPiTys (drop arity bndrs) res) $+    hang (text "Join point returns different type than body")+       2 (vcat [ text "Join bndr:" <+> ppr bndr <+> dcolon <+> ppr (idType bndr)+               , text "Join arity:" <+> ppr arity+               , text "Body type:" <+> ppr body_ty ])+  | otherwise+  = return ()++checkJoinOcc :: Id -> JoinArity -> LintM ()+-- Check that if the occurrence is a JoinId, then so is the+-- binding site, and it's a valid join Id+checkJoinOcc var n_args+  | JoinPoint join_arity_occ <- idJoinPointHood var+  = do { mb_join_arity_bndr <- lookupJoinId var+       ; case mb_join_arity_bndr of {+           NotJoinPoint -> do { join_set <- getValidJoins+                              ; addErrL (text "join set " <+> ppr join_set $$+                                invalidJoinOcc var) } ;++           JoinPoint join_arity_bndr ->++    do { checkL (join_arity_bndr == join_arity_occ) $+           -- Arity differs at binding site and occurrence+         mkJoinBndrOccMismatchMsg var join_arity_bndr join_arity_occ++       ; checkL (n_args == join_arity_occ) $+           -- Arity doesn't match #args+         mkBadJumpMsg var join_arity_occ n_args } } }++  | otherwise+  = return ()++checkTypeDataConOcc :: String -> DataCon -> LintM ()+-- Check that the Id is not a data constructor of a `type data` declaration+-- Invariant (I1) of Note [Type data declarations] in GHC.Rename.Module+checkTypeDataConOcc what dc+  = checkL (not (isTypeDataTyCon (dataConTyCon dc))) $+    (text "type data constructor found in a" <+> text what <> colon <+> ppr dc)++{-+-- | Check that a use of a dataToTag# primop satisfies conditions DTT2+-- and DTT3 from Note [DataToTag overview] in GHC.Tc.Instance.Class+--+-- Ignores applications not headed by dataToTag# primops.++-- Commented out because GHC.PrimopWrappers doesn't respect this condition yet.+-- See wrinkle DTW7 in Note [DataToTag overview].+checkDataToTagPrimOpTyCon+  :: CoreExpr   -- ^ the function (head of the application) we are checking+  -> [CoreArg]  -- ^ The arguments to the application+  -> LintM ()+checkDataToTagPrimOpTyCon (Var fun_id) args+  | Just op <- isPrimOpId_maybe fun_id+  , op == DataToTagSmallOp || op == DataToTagLargeOp+  = case args of+      Type _levity : Type dty : _rest+        | Just (tc, _) <- splitTyConApp_maybe dty+        , isValidDTT2TyCon tc+          -> do  platform <- getPlatform+                 let  numConstrs = tyConFamilySize tc+                      isSmallOp = op == DataToTagSmallOp+                 checkL (isSmallFamily platform numConstrs == isSmallOp) $+                   text "dataToTag# primop-size/tycon-family-size mismatch"+        | otherwise -> failWithL $ text "dataToTagLarge# used at non-ADT type:"+                                   <+> ppr dty+      _ -> failWithL $ text "dataToTagLarge# needs two type arguments but has args:"+                       <+> ppr (take 2 args)++checkDataToTagPrimOpTyCon _ _ = pure ()+-}++-- | Check representation-polymorphic invariants in an application of a+-- built-in function or newtype constructor.+--+-- See Note [Linting representation-polymorphic builtins].+checkRepPolyBuiltin :: CoreExpr   -- ^ the function (head of the application) we are checking+                    -> [CoreArg]  -- ^ the arguments to the application+                    -> OutType -- ^ the instantiated type of the overall application+                    -> LintM ()+checkRepPolyBuiltin (Var fun_id) args app_ty+  = do { do_rep_poly_checks <- lf_check_fixed_rep <$> getLintFlags+       ; when (do_rep_poly_checks && hasNoBinding fun_id) $+           if+             -- (2) representation-polymorphic unlifted newtypes+             | Just dc <- isDataConId_maybe fun_id+             , isNewDataCon dc+             -> if tcHasFixedRuntimeRep $ dataConTyCon dc+                then return ()+                else checkRepPolyNewtypeApp dc args app_ty++             -- (1) representation-polymorphic builtins+             | otherwise+             -> checkRepPolyBuiltinApp fun_id args+       }+checkRepPolyBuiltin _ _ _ = return ()++checkRepPolyNewtypeApp :: DataCon -> [CoreArg] -> OutType -> LintM ()+checkRepPolyNewtypeApp nt args app_ty+  -- If the newtype is saturated, we're OK.+  | any isValArg args+  = return ()+  -- Otherwise, check we can eta-expand.+  | otherwise+  = case getRuntimeArgTys app_ty of+      (Scaled _ first_val_arg_ty, _):_+        | not $ typeHasFixedRuntimeRep first_val_arg_ty+        -> failWithL (err_msg first_val_arg_ty)+      _ -> return ()++  where++      err_msg :: Type -> SDoc+      err_msg bad_arg_ty+        = vcat [ text "Cannot eta expand unlifted newtype constructor" <+> quotes (ppr nt) <> dot+               , text "Its argument type does not have a fixed runtime representation:"+               , nest 2 $ ppr_ty_ki bad_arg_ty ]++      ppr_ty_ki :: Type -> SDoc+      ppr_ty_ki ty = bullet <+> ppr ty <+> dcolon <+> ppr (typeKind ty)++checkRepPolyBuiltinApp :: Id -> [CoreArg] -> LintM ()+checkRepPolyBuiltinApp fun_id args = checkL (null not_concs) err_msg+  where++    conc_binder_positions :: IntMap ConcreteTvOrigin+    conc_binder_positions+      = concreteTyVarPositions fun_id+      $ idDetailsConcreteTvs+      $ idDetails fun_id++    max_pos :: Int+    max_pos =+      case nonEmpty $ IntMap.keys conc_binder_positions of+        Nothing -> 0+        Just positions -> maximum positions++    not_concs :: [(SDoc, ConcreteTvOrigin)]+    not_concs =+      mapMaybe is_bad (zip [1..max_pos] (map Just args ++ repeat Nothing))+        -- NB: 1-indexed++    is_bad :: (Int, Maybe CoreArg) -> Maybe (SDoc, ConcreteTvOrigin)+    is_bad (pos, mb_arg)+      | Just conc_reason <- IntMap.lookup pos conc_binder_positions+      , Just bad_ty <- case mb_arg of+          Just (Type ki)+            | isConcreteType ki+            -> Nothing+            | otherwise+            -- Here we handle the situation in which a "must be concrete" TyVar+            -- has been instantiated with a type that is not concrete.+            -> Just $ quotes (ppr ki) <+> text "is not concrete."+          -- We expected a type argument in this position, and got something else: panic!+          Just arg ->+            pprPanic "checkRepPolyBuiltinApp: expected a type in this position" $+              vcat [ text "fun_id:" <+> ppr fun_id <+> dcolon <+> ppr (idType fun_id)+                   , text "pos:" <+> ppr pos+                   , text "arg:" <+> ppr arg ]+          Nothing ->+            -- Here we handle the situation in which a "must be concrete" TyVar+            -- has not been instantiated at all.+            case conc_reason of+              ConcreteFRR frr_orig ->+                let ty = frr_type frr_orig+                in  Just $ ppr ty <+> dcolon <+> ppr (typeKind ty)+      = Just (bad_ty, conc_reason)+      | otherwise+      = Nothing++    err_msg :: SDoc+    err_msg+      = vcat $ map ((bullet <+>) . ppr_not_conc) not_concs++    ppr_not_conc :: (SDoc, ConcreteTvOrigin) -> SDoc+    ppr_not_conc (bad_ty, conc) =+      vcat+       [ ppr_conc_orig conc+       , nest 2 bad_ty ]++    ppr_conc_orig :: ConcreteTvOrigin -> SDoc+    ppr_conc_orig (ConcreteFRR frr_orig) =+      case frr_orig of+        FixedRuntimeRepOrigin { frr_context = ctxt } ->+          hsep [ ppr ctxt, text "does not have a fixed runtime representation:" ]++-- | Compute the 1-indexed positions in the outer forall'd quantified type variables+-- of the type in which the concrete type variables occur.+--+-- See Note [Representation-polymorphism checking built-ins] in GHC.Tc.Utils.Concrete.+concreteTyVarPositions :: Id -> ConcreteTyVars -> IntMap ConcreteTvOrigin+concreteTyVarPositions fun_id conc_tvs+  | isNullUFM conc_tvs+  = IntMap.empty+  | otherwise+  = case splitForAllTyCoVars (idType fun_id) of+    ([], _)  -> IntMap.empty+    (tvs, _) ->+      let positions =+            IntMap.fromList+              [ (pos, conc_orig)+              | (tv, pos) <- zip tvs [1..]+              , conc_orig <- maybeToList $ lookupNameEnv conc_tvs (tyVarName tv)+              ]+         -- Assert that we have as many positions as concrete type variables,+         -- i.e. we are not missing any concreteness information.+      in assertPpr (sizeUFM conc_tvs == length positions)+           (vcat [ text "concreteTyVarPositions: missing concreteness information"+                 , text "fun_id:" <+> ppr fun_id+                 , text "tvs:" <+> ppr tvs+                 , text "Expected # of concrete tvs:" <+> ppr (sizeUFM conc_tvs)+                 , text "  Actual # of concrete tvs:" <+> ppr (length positions) ])+           positions++-- Check that the usage of var is consistent with var itself, and pop the var+-- from the usage environment (this is important because of shadowing).+checkLinearity :: UsageEnv -> OutVar -> LintM UsageEnv+checkLinearity body_ue lam_var =+  case varMultMaybe lam_var of+    Just mult -> do+      let (lhs, body_ue') = popUE body_ue lam_var+          err_msg = vcat [ text "Linearity failure in lambda:" <+> ppr lam_var+                         , ppr lhs <+> text "⊈" <+> ppr mult+                         , ppr body_ue ]+      ensureSubUsage lhs mult err_msg+      return body_ue'+    Nothing    -> return body_ue -- A type variable++{- Note [Join points and casts]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+You might think that this should be OK:+   join j x = rhs+   in (case e of+          A   -> alt1+          B x -> (jump j x) |> co)++You might think that, since the cast is ultimately erased, the jump to+`j` should still be OK as a join point.  But no!  See #21716. Suppose++  newtype Age = MkAge Int   -- axAge :: Age ~ Int+  f :: Int -> ...           -- f strict in it's first argument++and consider the expression++  f (join j :: Bool -> Age+          j x = (rhs1 :: Age)+     in case v of+         Just x  -> (j x |> axAge :: Int)+         Nothing -> rhs2)++Then, if the Simplifier pushes the strict call into the join points+and alternatives we'll get++   join j' x = f (rhs1 :: Age)+   in case v of+      Just x  -> j' x |> axAge+      Nothing -> f rhs2++Utterly bogus.  `f` expects an `Int` and we are giving it an `Age`.+No no no.  Casts destroy the tail-call property.  Henc markAllJoinsBad+in the (Cast expr co) case of lintCoreExpr.++Note [No alternatives lint check]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+Case expressions with no alternatives are odd beasts, and it would seem+like they would worth be looking at in the linter (cf #10180). We+used to check two things:++* exprIsHNF is false: it would *seem* to be terribly wrong if+  the scrutinee was already in head normal form.++* exprIsDeadEnd is true: we should be able to see why GHC believes the+  scrutinee is diverging for sure.++It was already known that the second test was not entirely reliable.+Unfortunately (#13990), the first test turned out not to be reliable+either. Getting the checks right turns out to be somewhat complicated.++For example, suppose we have (comment 8)++  data T a where+    TInt :: T Int++  absurdTBool :: T Bool -> a+  absurdTBool v = case v of++  data Foo = Foo !(T Bool)++  absurdFoo :: Foo -> a+  absurdFoo (Foo x) = absurdTBool x++GHC initially accepts the empty case because of the GADT conditions. But then+we inline absurdTBool, getting++  absurdFoo (Foo x) = case x of++x is in normal form (because the Foo constructor is strict) but the+case is empty. To avoid this problem, GHC would have to recognize+that matching on Foo x is already absurd, which is not so easy.++More generally, we don't really know all the ways that GHC can+lose track of why an expression is bottom, so we shouldn't make too+much fuss when that happens.+++Note [Beta redexes]+~~~~~~~~~~~~~~~~~~~+Consider:++  join j @x y z = ... in+  (\@x y z -> jump j @x y z) @t e1 e2++This is clearly ill-typed, since the jump is inside both an application and a+lambda, either of which is enough to disqualify it as a tail call (see Note+[Invariants on join points] in GHC.Core). However, strictly from a+lambda-calculus perspective, the term doesn't go wrong---after the two beta+reductions, the jump *is* a tail call and everything is fine.++Why would we want to allow this when we have let? One reason is that a compound+beta redex (that is, one with more than one argument) has different scoping+rules: naively reducing the above example using lets will capture any free+occurrence of y in e2. More fundamentally, type lets are tricky; many passes,+such as Float Out, tacitly assume that the incoming program's type lets have+all been dealt with by the simplifier. Thus we don't want to let-bind any types+in, say, GHC.Core.Subst.simpleOptPgm, which in some circumstances can run immediately+before Float Out.++All that said, currently GHC.Core.Subst.simpleOptPgm is the only thing using this+loophole, doing so to avoid re-traversing large functions (beta-reducing a type+lambda without introducing a type let requires a substitution). TODO: Improve+simpleOptPgm so that we can forget all this ever happened.++************************************************************************+*                                                                      *+\subsection[lintCoreArgs]{lintCoreArgs}+*                                                                      *+************************************************************************++The basic version of these functions checks that the argument is a+subtype of the required type, as one would expect.+-}++-- Takes the functions type and arguments as argument.+-- Returns the *result* of applying the function to arguments.+-- e.g. f :: Int -> Bool -> Int would return `Int` as result type.+lintCoreArgs  :: (OutType, UsageEnv) -> [InExpr] -> LintM (OutType, UsageEnv)+lintCoreArgs (fun_ty, fun_ue) args+  = lintApp (text "expression")+              lintTyArg lintValArg fun_ty args fun_ue++lintTyArg :: InExpr -> LintM OutType++-- Type argument+lintTyArg (Type arg_ty)+  = do { checkL (not (isCoercionTy arg_ty))+                (text "Unnecessary coercion-to-type injection:"+                  <+> ppr arg_ty)+       ; lintTypeAndSubst arg_ty }+lintTyArg arg+  = failWithL (hang (text "Expected type argument but found") 2 (ppr arg))++lintValArg  :: InExpr -> Mult -> UsageEnv -> LintM (OutType, UsageEnv)+lintValArg arg mult fun_ue+  = do { (arg_ty, arg_ue) <- markAllJoinsBad $ lintCoreExpr arg+           -- See Note [Representation polymorphism invariants] in GHC.Core++       ; flags <- getLintFlags+       ; when (lf_check_fixed_rep flags) $+         -- Only check that 'arg_ty' has a fixed RuntimeRep+         -- if 'lf_check_fixed_rep' is on.+         do { checkL (typeHasFixedRuntimeRep arg_ty)+                     (text "Argument does not have a fixed runtime representation"+                      <+> ppr arg <+> dcolon+                      <+> parens (ppr arg_ty <+> dcolon <+> ppr (typeKind arg_ty))) }++       ; let app_ue = addUE fun_ue (scaleUE mult arg_ue)+       ; return (arg_ty, app_ue) }++-----------------+lintAltBinders :: UsageEnv+               -> Var         -- Case binder+               -> OutType     -- Scrutinee type+               -> OutType     -- Constructor type+               -> [(Mult, OutVar)]    -- Binders+               -> LintM UsageEnv+-- If you edit this function, you may need to update the GHC formalism+-- See Note [GHC Formalism]+lintAltBinders rhs_ue _case_bndr scrut_ty con_ty []+  = do { ensureEqTys con_ty scrut_ty (mkBadPatMsg con_ty scrut_ty)+       ; return rhs_ue }+lintAltBinders rhs_ue case_bndr scrut_ty con_ty ((var_w, bndr):bndrs)+  | isTyVar bndr+  = do { con_ty' <- lintTyApp con_ty (mkTyVarTy bndr)+       ; lintAltBinders rhs_ue case_bndr scrut_ty con_ty'  bndrs }+  | otherwise+  = do { (con_ty', _) <- lintValApp (Var bndr) con_ty (idType bndr) zeroUE zeroUE+         -- We can pass zeroUE to lintValApp because we ignore its usage+         -- calculation and compute it in the call for checkCaseLinearity below.+       ; rhs_ue' <- checkCaseLinearity rhs_ue case_bndr var_w bndr+       ; lintAltBinders rhs_ue' case_bndr scrut_ty con_ty' bndrs }++-- | Implements the case rules for linearity+checkCaseLinearity :: UsageEnv -> Var -> Mult -> Var -> LintM UsageEnv+checkCaseLinearity ue case_bndr var_w bndr = do+  ensureSubUsage lhs rhs err_msg+  lintLinearBinder (ppr bndr) (case_bndr_w `mkMultMul` var_w) (idMult bndr)+  return $ deleteUE ue bndr+  where+    lhs = bndr_usage `addUsage` (var_w `scaleUsage` case_bndr_usage)+    rhs = case_bndr_w `mkMultMul` var_w+    err_msg  = (text "Linearity failure in variable:" <+> ppr bndr+                $$ ppr lhs <+> text "⊈" <+> ppr rhs+                $$ text "Computed by:"+                <+> text "LHS:" <+> lhs_formula+                <+> text "RHS:" <+> rhs_formula)+    lhs_formula = ppr bndr_usage <+> text "+"+                                 <+> parens (ppr case_bndr_usage <+> text "*" <+> ppr var_w)+    rhs_formula = ppr case_bndr_w <+> text "*" <+> ppr var_w+    case_bndr_w = idMult case_bndr+    case_bndr_usage = lookupUE ue case_bndr+    bndr_usage = lookupUE ue bndr++++-----------------+lintTyApp :: OutType -> OutType -> LintM OutType+lintTyApp fun_ty arg_ty+  | Just (tv,body_ty) <- splitForAllTyVar_maybe fun_ty+  = do  { lintTyKind tv arg_ty+        ; in_scope <- getInScope+        -- substTy needs the set of tyvars in scope to avoid generating+        -- uniques that are already in scope.+        -- See Note [The substitution invariant] in GHC.Core.TyCo.Subst+        ; return (substTyWithInScope in_scope [tv] [arg_ty] body_ty) }++  | otherwise+  = failWithL (mkTyAppMsg fun_ty arg_ty)++-----------------++-- | @lintValApp arg fun_ty arg_ty@ lints an application of @fun arg@+-- where @fun :: fun_ty@ and @arg :: arg_ty@, returning the type of the+-- application.+lintValApp :: CoreExpr -> OutType -> OutType -> UsageEnv -> UsageEnv+           -> LintM (OutType, UsageEnv)+lintValApp arg fun_ty arg_ty fun_ue arg_ue+  | Just (_, w, arg_ty', res_ty') <- splitFunTy_maybe fun_ty+  = do { ensureEqTys arg_ty' arg_ty (mkAppMsg arg_ty' arg_ty arg)+       ; let app_ue =  addUE fun_ue (scaleUE w arg_ue)+       ; return (res_ty', app_ue) }+  | otherwise+  = failWithL err2+  where+    err2 = mkNonFunAppMsg fun_ty arg_ty arg++lintTyKind :: OutTyVar -> OutType -> LintM ()+-- Both args have had substitution applied++-- If you edit this function, you may need to update the GHC formalism+-- See Note [GHC Formalism]+lintTyKind tyvar arg_ty+  = unless (arg_kind `eqType` tyvar_kind) $+    addErrL (mkKindErrMsg tyvar arg_ty $$ (text "Linted Arg kind:" <+> ppr arg_kind))+  where+    tyvar_kind = tyVarKind tyvar+    arg_kind   = typeKind arg_ty++{-+************************************************************************+*                                                                      *+\subsection[lintCoreAlts]{lintCoreAlts}+*                                                                      *+************************************************************************+-}++lintCaseExpr :: CoreExpr -> InId -> InType -> [CoreAlt] -> LintM (OutType, UsageEnv)+lintCaseExpr scrut case_bndr alt_ty alts+  = do { let e = Case scrut case_bndr alt_ty alts   -- Just for error messages++       -- Check the scrutinee+       ; (scrut_ty', scrut_ue) <- markAllJoinsBad $ lintCoreExpr scrut+            -- See Note [Join points are less general than the paper]+            -- in GHC.Core++       ; alt_ty' <- addLoc (CaseTy scrut) $ lintValueType alt_ty++       ; checkCaseAlts e scrut scrut_ty' alts++       -- Lint the case-binder. Must do this after linting the scrutinee+       -- because the case-binder isn't in scope in the scrutineex+       ; lintBinder CaseBind case_bndr $ \case_bndr' ->+      -- Don't use lintIdBndr on case_bndr, because unboxed tuple is legitimate++    do { let case_bndr_ty' = idType case_bndr'+             scrut_mult    = idMult case_bndr'++       ; ensureEqTys case_bndr_ty' scrut_ty' (mkScrutMsg case_bndr case_bndr_ty' scrut_ty')+         -- See GHC.Core Note [Case expression invariants] item (7)++       ; -- Check the alternatives+       ; alt_ues <- mapM (lintCoreAlt case_bndr' scrut_ty' scrut_mult alt_ty') alts+       ; let case_ue = (scaleUE scrut_mult scrut_ue) `addUE` supUEs alt_ues+       ; return (alt_ty', case_ue) } }++checkCaseAlts :: InExpr -> InExpr -> OutType -> [CoreAlt] -> LintM ()+-- a) Check that the alts are non-empty+-- b1) Check that the DEFAULT comes first, if it exists+-- b2) Check that the others are in increasing order+-- c) Check that there's a default for infinite types+-- d) Check that the scrutinee is not a floating-point type+--    if there are any literal alternatives+-- e) Check if the scrutinee type has no constructors+--+-- We used to try to check whether a case expression with no+-- alternatives was legitimate, but this didn't work.+-- See Note [No alternatives lint check] for details.+--+-- NB: Algebraic cases are not necessarily exhaustive, because+--     the simplifier correctly eliminates case that can't+--     possibly match.+checkCaseAlts e scrut scrut_ty alts+  = do { checkL (all non_deflt con_alts) (mkNonDefltMsg e)+           -- See GHC.Core Note [Case expression invariants] item (2)++       ; checkL (increasing_tag con_alts) (mkNonIncreasingAltsMsg e)+           -- See GHC.Core Note [Case expression invariants] item (3)++            -- For types Int#, Word# with an infinite (well, large!) number of+            -- possible values, there should usually be a DEFAULT case+            -- But (see Note [Empty case alternatives] in GHC.Core) it's ok to+            -- have *no* case alternatives.+            -- In effect, this is a kind of partial test. I suppose it's possible+            -- that we might *know* that 'x' was 1 or 2, in which case+            --   case x of { 1 -> e1; 2 -> e2 }+            -- would be fine.+       ; checkL (isJust maybe_deflt || not is_infinite_ty || null alts)+                (nonExhaustiveAltsMsg e)++       -- Check that the scrutinee is not a floating-point type+       -- if there are any literal alternatives+       -- See GHC.Core Note [Case expression invariants] item (5)+       -- See Note [Rules for floating-point comparisons] in GHC.Core.Opt.ConstantFold+       ; checkL (not $ isFloatingPrimTy scrut_ty && any is_lit_alt alts)+           (text "Lint warning: Scrutinising floating-point expression with literal pattern in case analysis (see #9238)."+            $$ text "scrut" <+> ppr scrut)++       -- Check if scrutinee type has no constructors+       -- Just a trace message for now+       ; case tyConAppTyCon_maybe scrut_ty of+           Just tycon+                | debugIsOn+                , isAlgTyCon tycon+                , not (isAbstractTyCon tycon)+                , null (tyConDataCons tycon)+                , not (exprIsDeadEnd scrut)+                -> pprTrace "Lint warning: case scrutinee type has no constructors"+                        (ppr scrut_ty)+                          -- This can legitimately happen for type families+                        $ return ()+           _otherwise -> return ()+        }+  where+    (con_alts, maybe_deflt) = findDefault alts++        -- Check that successive alternatives have strictly increasing tags+    increasing_tag (alt1 : rest@( alt2 : _)) = alt1 `ltAlt` alt2 && increasing_tag rest+    increasing_tag _                         = True++    non_deflt (Alt DEFAULT _ _) = False+    non_deflt _                 = True++    is_lit_alt (Alt (LitAlt _) _  _) = True+    is_lit_alt _                     = False++    is_infinite_ty = case tyConAppTyCon_maybe scrut_ty of+                        Nothing    -> False+                        Just tycon -> isPrimTyCon tycon++lintAltExpr :: CoreExpr -> OutType -> LintM UsageEnv+lintAltExpr expr ann_ty+  = do { (actual_ty, ue) <- lintCoreExpr expr+       ; ensureEqTys actual_ty ann_ty (mkCaseAltMsg expr actual_ty ann_ty)+       ; return ue }+         -- See GHC.Core Note [Case expression invariants] item (6)++lintCoreAlt :: OutId         -- Case binder+            -> OutType       -- Type of scrutinee+            -> Mult          -- Multiplicity of scrutinee+            -> OutType       -- Type of the alternative+            -> CoreAlt+            -> LintM UsageEnv+-- If you edit this function, you may need to update the GHC formalism+-- See Note [GHC Formalism]+lintCoreAlt case_bndr _ scrut_mult alt_ty (Alt DEFAULT args rhs) =+  do { lintL (null args) (mkDefaultArgsMsg args)+     ; rhs_ue <- lintAltExpr rhs alt_ty+     ; let (case_bndr_usage, rhs_ue') = popUE rhs_ue case_bndr+           err_msg = vcat [ text "Linearity failure in the DEFAULT clause:" <+> ppr case_bndr+                          , ppr case_bndr_usage <+> text "⊈" <+> ppr scrut_mult ]+     ; ensureSubUsage case_bndr_usage scrut_mult err_msg+     ; return rhs_ue' }++lintCoreAlt case_bndr scrut_ty _ alt_ty (Alt (LitAlt lit) args rhs)+  | litIsLifted lit+  = failWithL integerScrutinisedMsg+  | otherwise+  = do { lintL (null args) (mkDefaultArgsMsg args)+       ; ensureEqTys lit_ty scrut_ty (mkBadPatMsg lit_ty scrut_ty)+       ; rhs_ue <- lintAltExpr rhs alt_ty+       ; return (deleteUE rhs_ue case_bndr) -- No need for linearity checks+       }+  where+    lit_ty = literalType lit++lintCoreAlt case_bndr scrut_ty _scrut_mult alt_ty alt@(Alt (DataAlt con) args rhs)+  | isNewTyCon (dataConTyCon con)+  = zeroUE <$ addErrL (mkNewTyDataConAltMsg scrut_ty alt)+  | Just (tycon, tycon_arg_tys) <- splitTyConApp_maybe scrut_ty+  = addLoc (CaseAlt alt) $  do+    { checkTypeDataConOcc "pattern" con+    ; lintL (tycon == dataConTyCon con) (mkBadConMsg tycon con)++      -- Instantiate the universally quantified+      -- type variables of the data constructor+    ; let { con_payload_ty = piResultTys (dataConRepType con) tycon_arg_tys+          ; binderMult (Named _)   = ManyTy+          ; binderMult (Anon st _) = scaledMult st+          -- See Note [Validating multiplicities in a case]+          ; multiplicities = map binderMult $ fst $ splitPiTys con_payload_ty }++        -- And now bring the new binders into scope+    ; lintBinders CasePatBind args $ \ args' -> do+      { rhs_ue <- lintAltExpr rhs alt_ty+      ; rhs_ue' <- addLoc (CasePat alt) $+                   lintAltBinders rhs_ue case_bndr scrut_ty con_payload_ty+                                  (zipEqual multiplicities  args')+      ; return $ deleteUE rhs_ue' case_bndr+      }+   }++  | otherwise   -- Scrut-ty is wrong shape+  = zeroUE <$ addErrL (mkBadAltMsg scrut_ty alt)++{-+Note [Validating multiplicities in a case]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+Suppose 'MkT :: a %m -> T m a'.+If we are validating 'case (x :: T Many a) of MkT y -> ...',+we have to substitute m := Many in the type of MkT - in particular,+y can be used Many times and that expression would still be linear in x.+We do this by looking at con_payload_ty, which is the type of the datacon+applied to the surrounding arguments.+Testcase: linear/should_compile/MultConstructor++Data constructors containing existential tyvars will then have+Named binders, which are always multiplicity Many.+Testcase: indexed-types/should_compile/GADT1+-}++lintLinearBinder :: SDoc -> Mult -> Mult -> LintM ()+lintLinearBinder doc actual_usage described_usage+  = ensureSubMult actual_usage described_usage err_msg+    where+      err_msg = (text "Multiplicity of variable does not agree with its context"+                $$ doc+                $$ ppr actual_usage+                $$ text "Annotation:" <+> ppr described_usage)++{-+************************************************************************+*                                                                      *+\subsection[lint-types]{Types}+*                                                                      *+************************************************************************+-}++-- When we lint binders, we (one at a time and in order):+--  1. Lint var types or kinds (possibly substituting)+--  2. Add the binder to the in scope set, and if its a coercion var,+--     we may extend the substitution to reflect its (possibly) new kind+lintBinders :: HasDebugCallStack => BindingSite -> [InVar] -> ([OutVar] -> LintM a) -> LintM a+lintBinders _    []         linterF = linterF []+lintBinders site (var:vars) linterF = lintBinder site var $ \var' ->+                                      lintBinders site vars $ \ vars' ->+                                      linterF (var':vars')++-- If you edit this function, you may need to update the GHC formalism+-- See Note [GHC Formalism]+lintBinder :: HasDebugCallStack => BindingSite -> InVar -> (OutVar -> LintM a) -> LintM a+lintBinder site var linterF+  | isTyCoVar var = lintTyCoBndr var linterF+  | otherwise     = lintIdBndr NotTopLevel site var linterF++lintTyCoBndr :: HasDebugCallStack => TyCoVar -> (OutTyCoVar -> LintM a) -> LintM a+lintTyCoBndr tcv thing_inside+  = do { tcv_type' <- lintTypeAndSubst (varType tcv)+       ; let tcv_kind' = typeKind tcv_type'++         -- See (FORALL1) and (FORALL2) in GHC.Core.Type+       ; if (isTyVar tcv)+         then -- Check that in (forall (a:ki). blah) we have ki:Type+              lintL (isLiftedTypeKind tcv_kind') $+              hang (text "TyVar whose kind does not have kind Type:")+                 2 (ppr tcv <+> dcolon <+> ppr tcv_type' <+> dcolon <+> ppr tcv_kind')+         else -- Check that in (forall (cv::ty). blah),+              -- then ty looks like (t1 ~# t2)+              lintL (isCoVarType tcv_type') $+              text "CoVar with non-coercion type:" <+> pprTyVar tcv++       ; addInScopeTyCoVar tcv tcv_type' thing_inside }++lintIdBndrs :: forall a. TopLevelFlag -> [InId] -> ([OutId] -> LintM a) -> LintM a+lintIdBndrs top_lvl ids thing_inside+  = go ids thing_inside+  where+    go :: [Id] -> ([Id] -> LintM a) -> LintM a+    go []       thing_inside = thing_inside []+    go (id:ids) thing_inside = lintIdBndr top_lvl LetBind id  $ \id' ->+                               go ids                         $ \ids' ->+                               thing_inside (id' : ids')++lintIdBndr :: TopLevelFlag -> BindingSite+           -> InVar -> (OutVar -> LintM a) -> LintM a+-- Do substitution on the type of a binder and add the var with this+-- new type to the in-scope set of the second argument+-- ToDo: lint its rules+lintIdBndr top_lvl bind_site id thing_inside+  = assertPpr (isId id) (ppr id) $+    do { flags <- getLintFlags+       ; checkL (not (lf_check_global_ids flags) || isLocalId id)+                (text "Non-local Id binder" <+> ppr id)+                -- See Note [Checking for global Ids]++       -- Check that if the binder is nested, it is not marked as exported+       ; checkL (not (isExportedId id) || is_top_lvl)+           (mkNonTopExportedMsg id)++       -- Check that if the binder is nested, it does not have an external name+       ; checkL (not (isExternalName (Var.varName id)) || is_top_lvl)+           (mkNonTopExternalNameMsg id)++          -- See Note [Representation polymorphism invariants] in GHC.Core+       ; lintL (isJoinId id || not (lf_check_fixed_rep flags)+                || typeHasFixedRuntimeRep id_ty) $+         text "Binder does not have a fixed runtime representation:" <+> ppr id <+> dcolon <+>+            parens (ppr id_ty <+> dcolon <+> ppr (typeKind id_ty))++       -- Check that a join-id is a not-top-level let-binding+       ; when (isJoinId id) $+         checkL (not is_top_lvl && is_let_bind) $+         mkBadJoinBindMsg id++       -- Check that the Id does not have type (t1 ~# t2) or (t1 ~R# t2);+       -- if so, it should be a CoVar, and checked by lintCoVarBndr+       ; lintL (not (isCoVarType id_ty))+               (text "Non-CoVar has coercion type" <+> ppr id <+> dcolon <+> ppr id_ty)++       -- Check that the lambda binder has no value or OtherCon unfolding.+       -- See #21496+       ; lintL (not (bind_site == LambdaBind && isEvaldUnfolding (idUnfolding id)))+                (text "Lambda binder with value or OtherCon unfolding.")++       ; out_ty <- addLoc (IdTy id) (lintValueType id_ty)++       ; addInScopeId id out_ty thing_inside }+  where+    id_ty = idType id++    is_top_lvl = isTopLevel top_lvl+    is_let_bind = case bind_site of+                    LetBind -> True+                    _       -> False++{-+%************************************************************************+%*                                                                      *+             Types+%*                                                                      *+%************************************************************************+-}++{- Note [Linting types and coercions]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+Notice that+   lintType     :: InType     -> LintM ()+   lintCoercion :: InCoercion -> LintM ()+Neither returns anything.++If you need the kind of the type, then do `typeKind` and then apply+the ambient substitution using `substTyM`.  Note that the substitution+empty unless there is shadowing or type-lets; and if the substitution is+empty, the `substTyM` is a no-op.++It is better to take the kind and then substitute, rather than substitute+and then take the kind, becaues the kind is usually smaller.++Note: you might wonder if we should apply the same logic to expressions.+Why do we have+  lintExpr :: InExpr -> LintM OutType+Partly inertia; but also taking the type of an expresison involve looking+down a deep chain of let's, whereas that is not true of taking the kind+of a type.  It'd be worth an experiment though.++Historical note: in the olden days we had+   lintType :: InType -> LintM OutType+but that burned a huge amount of allocation building an OutType that was+often discarded, or used only to get its kind.++I also experimented with+   lintType :: InType -> LintM OutKind+but that too was slower.  It is also much simpler to return ()!  If we+return the kind we have to duplicate the logic in `typeKind`; and it is+much worse for coercions.+-}++lintValueType :: Type -> LintM OutType+-- Types only, not kinds+-- Check the type, and apply the substitution to it+-- See Note [Linting type lets]+lintValueType ty+  = addLoc (InType ty) $+    do  { ty' <- lintTypeAndSubst ty+        ; let sk = typeKind ty'+        ; lintL (isTYPEorCONSTRAINT sk) $+          hang (text "Ill-kinded type:" <+> ppr ty)+             2 (text "has kind:" <+> ppr sk)+        ; return ty' }++checkTyCon :: TyCon -> LintM ()+checkTyCon tc+  = checkL (not (isTcTyCon tc)) (text "Found TcTyCon:" <+> ppr tc)++-------------------+lintTypeAndSubst :: InType -> LintM OutType+lintTypeAndSubst ty = do { lintType ty; substTyM ty }+           -- In GHCi we may lint an expression with a free+           -- type variable.  Then it won't be in the+           -- substitution, but it should be in scope++lintType :: InType -> LintM ()+-- See Note [Linting types and coercions]+--+-- If you edit this function, you may need to update the GHC formalism+-- See Note [GHC Formalism]+lintType (TyVarTy tv)+  | not (isTyVar tv)+  = failWithL (mkBadTyVarMsg tv)++  | otherwise+  = do { _ <- lintVarOcc tv+       ; return () }++lintType ty@(AppTy t1 t2)+  | TyConApp {} <- t1+  = failWithL $ text "TyConApp to the left of AppTy:" <+> ppr ty+  | otherwise+  = do { let (fun_ty, arg_tys) = collect t1 [t2]+       ; lintType fun_ty+       ; fun_kind <- substTyM (typeKind fun_ty)+       ; lint_ty_app ty fun_kind arg_tys }+  where+    collect (AppTy f a) as = collect f (a:as)+    collect fun         as = (fun, as)++lintType ty@(TyConApp tc tys)+  | isTypeSynonymTyCon tc || isTypeFamilyTyCon tc+  = do { report_unsat <- lf_report_unsat_syns <$> getLintFlags+       ; lintTySynFamApp report_unsat ty tc tys }++  | Just {} <- tyConAppFunTy_maybe tc tys+    -- We should never see a saturated application of funTyCon; such+    -- applications should be represented with the FunTy constructor.+    -- See Note [Linting function types]+  = failWithL (hang (text "Saturated application of" <+> quotes (ppr tc)) 2 (ppr ty))++  | otherwise  -- Data types, data families, primitive types+  = do { checkTyCon tc+       ; lint_ty_app ty (tyConKind tc) tys }++-- arrows can related *unlifted* kinds, so this has to be separate from+-- a dependent forall.+lintType ty@(FunTy af tw t1 t2)+  = do { lintType t1+       ; lintType t2+       ; lintType tw+       ; lintArrow (text "type or kind" <+> quotes (ppr ty)) af t1 t2 tw }++lintType ty@(ForAllTy {})+  = go [] ty+  where+    go :: [OutTyCoVar] -> InType -> LintM ()+    -- Loop, collecting the forall-binders+    go tcvs ty@(ForAllTy (Bndr tcv _) body_ty)+      | not (isTyCoVar tcv)+      = failWithL (text "Non-TyVar or Non-CoVar bound in type:" <+> ppr ty)++      | otherwise+      = lintTyCoBndr tcv $ \tcv' ->+        do { -- See GHC.Core.TyCo.Rep Note [Unused coercion variable in ForAllTy]+             -- Suspicious because it works on InTyCoVar; c.f. ForAllCo+             when (isCoVar tcv) $+             lintL (anyFreeVarsOfType (== tcv) body_ty) $+             text "Covar does not occur in the body:" <+> (ppr tcv $$ ppr body_ty)++           ; go (tcv' : tcvs) body_ty }++    go tcvs body_ty+      = do { lintType body_ty+           ; lintForAllBody tcvs body_ty }++lintType (CastTy ty co)+  = do { lintType ty+       ; ty_kind <- substTyM (typeKind ty)+       ; co_lk <- lintStarCoercion co+       ; ensureEqTys ty_kind co_lk (mkCastTyErr ty co ty_kind co_lk) }++lintType (LitTy l)       = lintTyLit l+lintType (CoercionTy co) = lintCoercion co++-----------------+lintForAllBody :: [OutTyCoVar] -> InType -> LintM ()+-- Do the checks for the body of a forall-type+lintForAllBody tcvs body_ty+  = do { -- For type variables, check for skolem escape+         -- See Note [Phantom type variables in kinds] in GHC.Core.Type+         -- The kind of (forall cv. th) is liftedTypeKind, so no+         -- need to check for skolem-escape in the CoVar case+         body_kind <- substTyM (typeKind body_ty)+       ; case occCheckExpand tcvs body_kind of+           Just {} -> return ()+           Nothing -> failWithL $+                      hang (text "Variable escape in forall:")+                         2 (vcat [ text "tycovars (reversed):" <+> ppr tcvs+                                 , text "type:" <+> ppr body_ty+                                 , text "kind:" <+> ppr body_kind ])+       ; checkValueType body_kind (text "the body of forall:" <+> ppr body_ty) }++-----------------+lintTySynFamApp :: Bool -> InType -> TyCon -> [InType] -> LintM ()+-- The TyCon is a type synonym or a type family (not a data family)+-- See Note [Linting type synonym applications]+-- c.f. GHC.Tc.Validity.check_syn_tc_app+lintTySynFamApp report_unsat ty tc tys+  | report_unsat   -- Report unsaturated only if report_unsat is on+  , tys `lengthLessThan` tyConArity tc+  = failWithL (hang (text "Un-saturated type application") 2 (ppr ty))++  -- Deal with type synonyms+  | ExpandsSyn tenv rhs tys' <- expandSynTyCon_maybe tc tys+  , let expanded_ty = mkAppTys (substTy (mkTvSubstPrs tenv) rhs) tys'+  = do { when report_unsat $ do { _ <- lintType expanded_ty+                                ; return () }++       ; -- Kind-check the argument types, but without reporting+         -- un-saturated type families/synonyms+       ; setReportUnsat False $+         lint_ty_app ty (tyConKind tc) tys }++  -- Otherwise this must be a type family+  | otherwise+  = lint_ty_app ty (tyConKind tc) tys++-----------------+-- Confirms that a kind is really TYPE r or Constraint+checkValueType :: OutKind -> SDoc -> LintM ()+checkValueType kind doc+  = lintL (isTYPEorCONSTRAINT kind)+          (text "Non-Type-like kind when Type-like expected:" <+> ppr kind $$+           text "when checking" <+> doc)++-----------------+lintArrow :: SDoc -> FunTyFlag -> InType -> InType -> InType -> LintM ()+-- If you edit this function, you may need to update the GHC formalism+-- See Note [GHC Formalism]+lintArrow what af t1 t2 tw  -- Eg lintArrow "type or kind `blah'" k1 k2 kw+                            -- or lintArrow "coercion `blah'" k1 k2 kw+  = do { k1 <- substTyM (typeKind t1)+       ; k2 <- substTyM (typeKind t2)+       ; kw <- substTyM (typeKind tw)+       ; unless (isTYPEorCONSTRAINT k1) (report (text "argument")     t1 k1)+       ; unless (isTYPEorCONSTRAINT k2) (report (text "result")       t2 k2)+       ; unless (isMultiplicityTy kw)   (report (text "multiplicity") tw kw)++       ; let real_af = chooseFunTyFlag t1 t2+       ; unless (real_af == af) $ addErrL $+         hang (text "Bad FunTyFlag")+            2 (vcat [ text "FunTyFlag =" <+> ppr af+                    , text "Computed FunTyFlag =" <+> ppr real_af+                    , text "in" <+> what ]) }+  where+    report ar t k = addErrL (hang (text "Ill-kinded" <+> ar)+                                2 (vcat [ ppr t <+> dcolon <+> ppr k+                                        , text "in" <+> what ]))++-----------------+lintTyLit :: TyLit -> LintM ()+lintTyLit (NumTyLit n)+  | n >= 0    = return ()+  | otherwise = failWithL msg+    where msg = text "Negative type literal:" <+> integer n+lintTyLit (StrTyLit _) = return ()+lintTyLit (CharTyLit _) = return ()++-----------------+lint_ty_app :: InType -> OutKind -> [InType] -> LintM ()+lint_ty_app ty = lint_tyco_app (text "type" <+> quotes (ppr ty))++lint_co_app :: HasDebugCallStack => Coercion -> OutKind -> [InType] -> LintM ()+lint_co_app co = lint_tyco_app (text "coercion" <+> quotes (ppr co))++lint_tyco_app :: SDoc -> OutKind -> [InType] -> LintM ()+lint_tyco_app msg fun_kind arg_tys+    -- See Note [Avoiding compiler perf traps when constructing error messages.]+  = do { _ <- lintApp msg (\ty     -> do { lintType ty; substTyM ty })+                            (\ty _ _ -> do { lintType ty; ki <- substTyM (typeKind ty); return (ki,()) })+                            fun_kind arg_tys ()+       ; return () }++----------------+lintApp :: forall in_a acc. Outputable in_a =>+             SDoc+          -> (in_a -> LintM OutType)                        -- Lint the thing and return its value+          -> (in_a -> Mult -> acc -> LintM (OutKind, acc))  -- Lint the thing and return its type+          -> OutType+          -> [in_a]                               -- The arguments, always "In" things+          -> acc                                  -- Used (only) for UsageEnv in /term/ applications+          -> LintM (OutType,acc)+-- lintApp is a performance-critical function, which deals with multiple+-- applications such as  (/\a./\b./\c. expr) @ta @tb @tc+-- When returning the type of this expression we want to avoid substituting a:=ta,+-- and /then/ substituting b:=tb, etc.  That's quadratic, and can be a huge+-- perf hole.  So we gather all the arguments [in_a], and then gather the+-- substitution incrementally in the `go` loop.+--+-- lintApp is used:+--    * for term applications (lintCoreArgs)+--    * for type applications (lint_ty_app)+--    * for coercion application (lint_co_app)+-- To deal with these cases `lintApp` has two higher order arguments;+-- but we specialise it for each call site (by inlining)+{-# INLINE lintApp #-}    -- INLINE: very few call sites;+                          -- not recursive; specialised at its call sites++lintApp msg lint_forall_arg lint_arrow_arg !orig_fun_ty all_args acc+    = do { !in_scope <- getInScope+         -- We need the in_scope set to satisfy the invariant in+         -- Note [The substitution invariant] in GHC.Core.TyCo.Subst+         -- Forcing the in scope set eagerly here reduces allocations by up to 4%.++         ; let init_subst = mkEmptySubst in_scope++               go :: Subst -> OutType -> acc -> [in_a] -> LintM (OutType, acc)+                     -- The Subst applies (only) to the fun_ty+                     -- c.f. GHC.Core.Type.piResultTys, which has a similar loop++               go subst fun_ty acc []+                 = return (substTy subst fun_ty, acc)++               go subst (ForAllTy (Bndr tv _vis) body_ty) acc (arg:args)+                 = do { arg' <- lint_forall_arg arg+                      ; let tv_kind = substTy subst (varType tv)+                            karg'   = typeKind arg'+                            subst'  = extendTCvSubst subst tv arg'+                      ; ensureEqTys karg' tv_kind $+                        lint_app_fail_msg msg orig_fun_ty all_args+                            (hang (text "Forall:" <+> (ppr tv $$ ppr tv_kind))+                                2 (ppr arg' <+> dcolon <+> ppr karg'))+                      ; go subst' body_ty acc args }++               go subst fun_ty@(FunTy _ mult exp_arg_ty res_ty) acc (arg:args)+                 = do { (arg_ty, acc') <- lint_arrow_arg arg (substTy subst mult) acc+                      ; ensureEqTys (substTy subst exp_arg_ty) arg_ty $+                        lint_app_fail_msg msg orig_fun_ty all_args+                            (hang (text "Fun:" <+> ppr fun_ty)+                                2 (vcat [ text "exp_arg_ty:" <+> ppr exp_arg_ty+                                        , text "arg:" <+> ppr arg <+> dcolon <+> ppr arg_ty ]))+                      ; go subst res_ty acc' args }++               go subst fun_ty acc args+                 | Just fun_ty' <- coreView fun_ty+                 = go subst fun_ty' acc args++                 | not (isEmptyTCvSubst subst)  -- See Note [Care with kind instantiation]+                 = go init_subst (substTy subst fun_ty) acc args++                 | otherwise+                 = failWithL (lint_app_fail_msg msg orig_fun_ty all_args+                                  (text "Not a fun:" <+> (ppr fun_ty $$ ppr args)))++         ; go init_subst orig_fun_ty acc all_args }++-- This is a top level definition to ensure we pass all variables of the error message+-- explicitly and don't capture them as free variables. Otherwise this binder might+-- become a thunk that get's allocated in the hot code path.+-- See Note [Avoiding compiler perf traps when constructing error messages.]+lint_app_fail_msg :: (Outputable a2) => SDoc -> OutType -> a2 -> SDoc -> SDoc+lint_app_fail_msg msg kfn arg_tys extra+  = vcat [ hang (text "Application error in") 2 msg+         , nest 2 (text "Function type =" <+> ppr kfn)+         , nest 2 (text "Args =" <+> ppr arg_tys)+         , extra ]++{- *********************************************************************+*                                                                      *+        Linting rules+*                                                                      *+********************************************************************* -}++lintCoreRule :: OutVar -> OutType -> CoreRule -> LintM ()+lintCoreRule _ _ (BuiltinRule {})+  = return ()  -- Don't bother++lintCoreRule fun fun_ty rule@(Rule { ru_name = name, ru_bndrs = bndrs+                                   , ru_args = args, ru_rhs = rhs })+  = lintBinders LambdaBind bndrs $ \ _ ->+    do { (lhs_ty, _) <- lintCoreArgs (fun_ty, zeroUE) args+       ; (rhs_ty, _) <- case idJoinPointHood fun of+                     JoinPoint join_arity+                       -> do { checkL (args `lengthIs` join_arity) $+                                mkBadJoinPointRuleMsg fun join_arity rule+                               -- See Note [Rules for join points]+                             ; lintCoreExpr rhs }+                     _ -> markAllJoinsBad $ lintCoreExpr rhs+       ; ensureEqTys lhs_ty rhs_ty $+         (rule_doc <+> vcat [ text "lhs type:" <+> ppr lhs_ty+                            , text "rhs type:" <+> ppr rhs_ty+                            , text "fun_ty:" <+> ppr fun_ty ])+       ; let bad_bndrs = filter is_bad_bndr bndrs++       ; checkL (null bad_bndrs)+                (rule_doc <+> text "unbound" <+> ppr bad_bndrs)+            -- See Note [Linting rules]+    }+  where+    rule_doc = text "Rule" <+> doubleQuotes (ftext name) <> colon++    lhs_fvs = exprsFreeVars args+    rhs_fvs = exprFreeVars rhs++    is_bad_bndr :: Var -> Bool+    -- See Note [Unbound RULE binders] in GHC.Core.Rules+    is_bad_bndr bndr = not (bndr `elemVarSet` lhs_fvs)+                    && bndr `elemVarSet` rhs_fvs+                    && isNothing (isReflCoVar_maybe bndr)+++{- Note [Linting rules]+~~~~~~~~~~~~~~~~~~~~~~~+It's very bad if simplifying a rule means that one of the template+variables (ru_bndrs) that /is/ mentioned on the RHS becomes+not-mentioned in the LHS (ru_args).  How can that happen?  Well, in #10602,+SpecConstr stupidly constructed a rule like++  forall x,c1,c2.+     f (x |> c1 |> c2) = ....++But simplExpr collapses those coercions into one.  (Indeed in #10602,+it collapsed to the identity and was removed altogether.)++We don't have a great story for what to do here, but at least+this check will nail it.++NB (#11643): it's possible that a variable listed in the+binders becomes not-mentioned on both LHS and RHS.  Here's a silly+example:+   RULE forall x y. f (g x y) = g (x+1) (y-1)+And suppose worker/wrapper decides that 'x' is Absent.  Then+we'll end up with+   RULE forall x y. f ($gw y) = $gw (x+1)+This seems sufficiently obscure that there isn't enough payoff to+try to trim the forall'd binder list.++Note [Rules for join points]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~+A join point cannot be partially applied. However, the left-hand side of a rule+for a join point is effectively a *pattern*, not a piece of code, so there's an+argument to be made for allowing a situation like this:++  join $sj :: Int -> Int -> String+       $sj n m = ...+       j :: forall a. Eq a => a -> a -> String+       {-# RULES "SPEC j" jump j @ Int $dEq = jump $sj #-}+       j @a $dEq x y = ...++Applying this rule can't turn a well-typed program into an ill-typed one, so+conceivably we could allow it. But we can always eta-expand such an+"undersaturated" rule (see 'GHC.Core.Opt.Arity.etaExpandToJoinPointRule'), and in fact+the simplifier would have to in order to deal with the RHS. So we take a+conservative view and don't allow undersaturated rules for join points. See+Note [Join points and unfoldings/rules] in "GHC.Core.Opt.OccurAnal" for further discussion.+-}++{-+************************************************************************+*                                                                      *+         Linting coercions+*                                                                      *+************************************************************************+-}++{- Note [Asymptotic efficiency]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+When linting coercions (and types actually) we return a linted+(substituted) coercion.  Then we often have to take the coercionKind of+that returned coercion. If we get long chains, that can be asymptotically+inefficient, notably in+* TransCo+* InstCo+* SelCo (cf #9233)+* LRCo++But the code is simple.  And this is only Lint.  Let's wait to see if+the bad perf bites us in practice.++A solution would be to return the kind and role of the coercion,+as well as the linted coercion.  Or perhaps even *only* the kind and role,+which is what used to happen.   But that proved tricky and error prone+(#17923), so now we return the coercion.+-}+++-- lintStarCoercion lints a coercion, confirming that its lh kind and+-- its rh kind are both *; also ensures that the role is Nominal+-- Returns the lh kind+lintStarCoercion :: InCoercion -> LintM OutType+lintStarCoercion g+  = do { lintCoercion g+       ; Pair t1 t2 <- substCoKindM g+       ; checkValueType (typeKind t1) (text "the kind of the left type in" <+> ppr g)+       ; checkValueType (typeKind t2) (text "the kind of the right type in" <+> ppr g)+       ; lintRole g Nominal (coercionRole g)+       ; return t1 }++substCoKindM :: InCoercion -> LintM (Pair OutType)+substCoKindM co+  = do { let !(Pair lk rk) = coercionKind co+       ; lk' <- substTyM lk+       ; rk' <- substTyM rk+       ; return (Pair lk' rk') }++lintCoercion :: HasDebugCallStack => InCoercion -> LintM ()+-- See Note [Linting types and coercions]+--+-- If you edit this function, you may need to update the GHC formalism+-- See Note [GHC Formalism]++lintCoercion (CoVarCo cv)+  | not (isCoVar cv)+  = failWithL (hang (text "Bad CoVarCo:" <+> ppr cv)+                  2 (text "With offending type:" <+> ppr (varType cv)))++  | otherwise  -- C.f. lintType (TyVarTy tv), which has better docs+  = do { _ <- lintVarOcc cv; return () }++lintCoercion (Refl ty)          = lintType ty+lintCoercion (GRefl _r ty MRefl) = lintType ty++lintCoercion (GRefl _r ty (MCo co))+  = do { lintType ty+       ; lintCoercion co+       ; tk <- substTyM (typeKind ty)+       ; tl <- substTyM (coercionLKind co)+       ; ensureEqTys tk tl $+         hang (text "GRefl coercion kind mis-match:" <+> ppr co)+            2 (vcat [ppr ty, ppr tk, ppr tl])+       ; lintRole co Nominal (coercionRole co) }++lintCoercion co@(TyConAppCo r tc cos)+  | Just {} <- tyConAppFunCo_maybe r tc cos+  = failWithL (hang (text "Saturated application of" <+> quotes (ppr tc))+                  2 (ppr co))+    -- All saturated TyConAppCos should be FunCos++  | Just {} <- synTyConDefn_maybe tc+  = failWithL (text "Synonym in TyConAppCo:" <+> ppr co)++  | otherwise+  = do { checkTyCon tc+       ; mapM_ lintCoercion cos+       ; let tc_kind = tyConKind tc+       ; lint_co_app co tc_kind (map coercionLKind cos)+       ; lint_co_app co tc_kind (map coercionRKind cos)+       ; zipWithM_ (lintRole co) (tyConRoleListX r tc) (map coercionRole cos) }+++lintCoercion co@(AppCo co1 co2)+  | TyConAppCo {} <- co1+  = failWithL (text "TyConAppCo to the left of AppCo:" <+> ppr co)+  | Just (TyConApp {}, _) <- isReflCo_maybe co1+  = failWithL (text "Refl (TyConApp ...) to the left of AppCo:" <+> ppr co)+  | otherwise+  = do { lintCoercion co1+       ; lintCoercion co2+       ; let !(Pair lt1 rt1) = coercionKind co1+       ; lk1 <- substTyM (typeKind lt1)+       ; rk1 <- substTyM (typeKind rt1)+       ; lint_co_app co lk1 [coercionLKind co2]+       ; lint_co_app co rk1 [coercionRKind co2]++       ; let r2 = coercionRole co2+       ; if coercionRole co1 == Phantom+         then lintL (r2 == Phantom || r2 == Nominal)+                     (text "Second argument in AppCo cannot be R:" $$+                      ppr co)+         else lintRole co Nominal r2 }++----------+lintCoercion co@(ForAllCo {})+-- See Note [ForAllCo] in GHC.Core.TyCo.Rep for the typing rule for ForAllCo+  = do { _ <- go [] co; return () }+  where+    go :: [OutTyCoVar]   -- Binders in reverse order+       -> InCoercion -> LintM Role+    go tcvs co@(ForAllCo { fco_tcv = tcv, fco_visL = visL, fco_visR = visR+                         , fco_kind = kind_co, fco_body = body_co })+      | not (isTyCoVar tcv)+      = failWithL (text "Non tyco binder in ForAllCo:" <+> ppr co)++      | otherwise+      = do { lk <- lintStarCoercion kind_co+           ; lintTyCoBndr tcv $ \tcv' ->+        do { ensureEqTys (varType tcv') lk $+             text "Kind mis-match in ForallCo" <+> ppr co++           -- I'm not very sure about this part, because it traverses body_co+           -- but at least it's on a cold path (a ForallCo for a CoVar)+           -- Also it works on InTyCoVar and InCoercion, which is suspect+           ; when (isCoVar tcv) $+             do { lintL (visL == coreTyLamForAllTyFlag && visR == coreTyLamForAllTyFlag) $+                  text "Invalid visibility flags in CoVar ForAllCo" <+> ppr co+                  -- See (FC7) in Note [ForAllCo] in GHC.Core.TyCo.Rep+                ; lintL (almostDevoidCoVarOfCo tcv body_co) $+                  text "Covar can only appear in Refl and GRefl: " <+> ppr co }+                  -- See (FC6) in Note [ForAllCo] in GHC.Core.TyCo.Rep++           ; role <- go (tcv':tcvs) body_co++           ; when (role == Nominal) $+             lintL (visL `eqForAllVis` visR) $+             text "Nominal ForAllCo has mismatched visibilities: " <+> ppr co++           ; return role } }++    go tcvs body_co+      = do { lintCoercion body_co++           -- Need to check that+           --    (forall (tcv:k1). lty) and+           --    (forall (tcv:k2). rty[(tcv:k2) |> sym kind_co/tcv])+           -- are both well formed, including the skolem escape check.+           -- Easiest way is to call lintForAllBody for each+           ; let Pair lty rty = coercionKind body_co+           ; lintForAllBody tcvs lty+           ; lintForAllBody tcvs rty++           ; return (coercionRole body_co) }+++lintCoercion (FunCo { fco_role = r, fco_afl = afl, fco_afr = afr+                    , fco_mult = cow, fco_arg = co1, fco_res = co2 })+  = do { lintCoercion co1+       ; lintCoercion co2+       ; lintCoercion cow+       ; let Pair lt1 rt1 = coercionKind co1+             Pair lt2 rt2 = coercionKind co2+             Pair ltw rtw = coercionKind cow+       ; lintArrow (bad_co_msg "arrowl") afl lt1 lt2 ltw+       ; lintArrow (bad_co_msg "arrowr") afr rt1 rt2 rtw+       ; lintRole co1 r (coercionRole co1)+       ; lintRole co2 r (coercionRole co2)+       ; let expected_mult_role = case r of+                                    Phantom -> Phantom+                                    _ -> Nominal+       ; lintRole cow expected_mult_role (coercionRole cow) }+  where+    bad_co_msg s = hang (text "Bad coercion" <+> parens (text s))+                      2 (vcat [ text "afl:" <+> ppr afl+                              , text "afr:" <+> ppr afr+                              , text "arg_co:" <+> ppr co1+                              , text "res_co:" <+> ppr co2 ])++-- See Note [Bad unsafe coercion]+lintCoercion co@(UnivCo { uco_role = r, uco_prov = prov+                        , uco_lty = ty1, uco_rty = ty2, uco_deps = deps })+  = do { -- Check the role.  PhantomProv must have Phantom role, otherwise any role is fine+         case prov of+            PhantomProv -> lintRole co Phantom r+            _           -> return ()++       -- Check the to and from types+       ; lintType ty1+       ; lintType ty2+       ; tk1 <- substTyM (typeKind ty1)+       ; tk2 <- substTyM (typeKind ty2)++       ; when (r /= Phantom && isTYPEorCONSTRAINT tk1 && isTYPEorCONSTRAINT tk2)+              (checkTypes ty1 ty2)++       -- Check the coercions on which this UnivCo depends+       ; mapM_ lintCoercion deps }+   where+     report s = hang (text $ "Unsafe coercion: " ++ s)+                     2 (vcat [ text "From:" <+> ppr ty1+                             , text "  To:" <+> ppr ty2])+     isUnBoxed :: PrimRep -> Bool+     isUnBoxed = not . isGcPtrRep++       -- see #9122 for discussion of these checks+     checkTypes t1 t2+       = do { checkWarnL fixed_rep_1+                         (report "left-hand type does not have a fixed runtime representation")+            ; checkWarnL fixed_rep_2+                         (report "right-hand type does not have a fixed runtime representation")+            ; when (fixed_rep_1 && fixed_rep_2) $+              do { checkWarnL (reps1 `equalLength` reps2)+                              (report "between values with different # of reps")+                 ; zipWithM_ validateCoercion reps1 reps2 }}+       where+         fixed_rep_1 = typeHasFixedRuntimeRep t1+         fixed_rep_2 = typeHasFixedRuntimeRep t2++         -- don't look at these unless lev_poly1/2 are False+         -- Otherwise, we get #13458+         reps1 = typePrimRep t1+         reps2 = typePrimRep t2++     validateCoercion :: PrimRep -> PrimRep -> LintM ()+     validateCoercion rep1 rep2+       = do { platform <- getPlatform+            ; checkWarnL (isUnBoxed rep1 == isUnBoxed rep2)+                         (report "between unboxed and boxed value")+            ; checkWarnL (TyCon.primRepSizeB platform rep1+                           == TyCon.primRepSizeB platform rep2)+                         (report "between unboxed values of different size")+            ; let fl = liftM2 (==) (TyCon.primRepIsFloat rep1)+                                   (TyCon.primRepIsFloat rep2)+            ; case fl of+                Nothing    -> addWarnL (report "between vector types")+                Just False -> addWarnL (report "between float and integral values")+                _          -> return ()+            }++lintCoercion (SymCo co) = lintCoercion co++lintCoercion co@(TransCo co1 co2)+  = do { lintCoercion co1+       ; lintCoercion co2+       ; rk1 <- substTyM (coercionRKind co1)+       ; lk2 <- substTyM (coercionLKind co2)+       ; ensureEqTys rk1 lk2+               (hang (text "Trans coercion mis-match:" <+> ppr co)+                   2 (vcat [ppr (coercionKind co1), ppr (coercionKind co2)]))+       ; lintRole co (coercionRole co1) (coercionRole co2) }++lintCoercion the_co@(SelCo cs co)+  = do { lintCoercion co+       ; Pair s t <- substCoKindM co++       ; if -- forall (both TyVar and CoVar)+            | Just _ <- splitForAllTyCoVar_maybe s+            , Just _ <- splitForAllTyCoVar_maybe t+            , SelForAll <- cs+            ,   (isForAllTy_ty s && isForAllTy_ty t)+             || (isForAllTy_co s && isForAllTy_co t)+            -> return ()++            -- function+            | isFunTy s+            , isFunTy t+            , SelFun {} <- cs+            -> return ()++            -- TyCon+            | Just (tc_s, tys_s) <- splitTyConApp_maybe s+            , Just (tc_t, tys_t) <- splitTyConApp_maybe t+            , tc_s == tc_t+            , SelTyCon n r0 <- cs+            , let co_role = coercionRole co+            , isInjectiveTyCon tc_s co_role+                -- see Note [SelCo and newtypes] in GHC.Core.TyCo.Rep+            , tys_s `equalLength` tys_t+            , tys_s `lengthExceeds` n+            -> do { lintRole the_co (tyConRole co_role tc_s n) r0+                  ; return () }++            | otherwise+            -> failWithL (hang (text "Bad SelCo:")+                             2 (ppr the_co $$ ppr s $$ ppr t)) }++lintCoercion the_co@(LRCo _lr co)+  = do { lintCoercion co+       ; Pair s t <- substCoKindM co+       ; lintRole co Nominal (coercionRole co)+       ; case (splitAppTy_maybe s, splitAppTy_maybe t) of+           (Just {}, Just {}) -> return ()+           _ -> failWithL (hang (text "Bad LRCo:")+                              2 (ppr the_co $$ ppr s $$ ppr t)) }+++lintCoercion orig_co@(InstCo co arg)+  = go co [arg]+  where+    go (InstCo co arg) args = do { lintCoercion arg; go co (arg:args) }+    go co              args = do { lintCoercion co+                                 ; let Pair lty rty = coercionKind co+                                 ; lty' <- substTyM lty+                                 ; rty' <- substTyM rty+                                 ; in_scope <- getInScope+                                 ; let subst = mkEmptySubst in_scope+                                 ; go_args (subst, lty') (subst,rty') args }++    -------------+    go_args :: (Subst, OutType) -> (Subst,OutType) -> [InCoercion]+           -> LintM ()+    go_args _ _ []+      = return ()+    go_args lty rty (arg:args)+      = do { (lty1, rty1)  <- go_arg lty rty arg+           ; go_args lty1 rty1 args }++    -------------+    go_arg :: (Subst, OutType) -> (Subst,OutType) -> InCoercion+           -> LintM ((Subst,OutType), (Subst,OutType))+    go_arg (lsubst,lty) (rsubst,rty) arg+      = do { lintRole arg Nominal (coercionRole arg)+           ; Pair arg_lty arg_rty <- substCoKindM arg++           ; case (splitForAllTyCoVar_maybe lty, splitForAllTyCoVar_maybe rty) of+              -- forall over tvar+                (Just (ltv,lty1), Just (rtv,rty1))+                  | typeKind arg_lty `eqType` substTy lsubst (tyVarKind ltv)+                  , typeKind arg_rty `eqType` substTy rsubst (tyVarKind rtv)+                  -> return ( (extendTCvSubst lsubst ltv arg_lty, lty1)+                            , (extendTCvSubst rsubst rtv arg_rty, rty1) )+                  | otherwise+                  -> failWithL (hang (text "Kind mis-match in inst coercion")+                                   2 (vcat [ text "arg"  <+> ppr arg+                                           , text "lty"  <+> ppr lty <+> dcolon <+> ppr (typeKind lty)+                                           , text "rty"  <+> ppr rty <+> dcolon <+> ppr (typeKind rty)+                                           , text "arg_lty" <+> ppr arg_lty <+> dcolon <+> ppr (typeKind arg_lty)+                                           , text "arg_rty" <+> ppr arg_rty <+> dcolon <+> ppr (typeKind arg_rty)+                                           , text "ltv" <+> ppr ltv <+> dcolon <+> ppr (tyVarKind ltv)+                                           , text "rtv" <+> ppr rtv <+> dcolon <+> ppr (tyVarKind rtv) ]))++                _ -> failWithL (text "Bad argument of inst" <+> ppr orig_co) }++lintCoercion this_co@(AxiomCo ax cos)+  = do { mapM_ lintCoercion cos+       ; lint_roles 0 (coAxiomRuleArgRoles ax) cos+       ; prs <- mapM substCoKindM cos+       ; lint_ax ax prs }++  where+    lint_ax :: CoAxiomRule -> [Pair OutType] -> LintM ()+    lint_ax (BuiltInFamRew  bif) prs+      = checkL (isJust (bifrw_proves bif prs))  bad_bif+    lint_ax (BuiltInFamInj bif) prs+      = checkL (case prs of+                  [pr] -> isJust (bifinj_proves bif pr)+                  _    -> False)+               bad_bif+    lint_ax (UnbranchedAxiom ax) prs+      = lintBranch this_co (coAxiomTyCon ax) (coAxiomSingleBranch ax) prs+    lint_ax (BranchedAxiom ax ind) prs+      = do { checkL (0 <= ind && ind < numBranches (coAxiomBranches ax))+                    (bad_ax this_co (text "index out of range"))+           ; lintBranch this_co (coAxiomTyCon ax) (coAxiomNthBranch ax ind) prs }++    bad_bif = bad_ax this_co (text "Proves returns Nothing")++    err :: forall a. String -> [SDoc] -> LintM a+    err m xs  = failWithL $+                hang (text m) 2 $ vcat (text "Rule:" <+> ppr ax : xs)++    lint_roles n (e : es) (co:cos)+      | e == coercionRole co+      = lint_roles (n+1) es cos+      | otherwise = err "Argument roles mismatch"+                        [ text "In argument:" <+> int (n+1)+                        , text "Expected:" <+> ppr e+                        , text "Found:" <+> ppr (coercionRole co) ]+    lint_roles _ [] []  = return ()+    lint_roles n [] rs  = err "Too many coercion arguments"+                            [ text "Expected:" <+> int n+                            , text "Provided:" <+> int (n + length rs) ]++    lint_roles n es []  = err "Not enough coercion arguments"+                            [ text "Expected:" <+> int (n + length es)+                            , text "Provided:" <+> int n ]++lintCoercion (KindCo co) = lintCoercion co++lintCoercion (SubCo co)+  = do { lintCoercion co+       ; lintRole co Nominal (coercionRole co) }++lintCoercion (HoleCo h)+  = failWithL (text "Unfilled coercion hole:" <+> ppr h)++{-+Note [Conflict checking for axiom applications]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+Consider the following type family and axiom:++type family Equal (a :: k) (b :: k) :: Bool+type instance where+  Equal a a = True+  Equal a b = False+--+Equal :: forall k::*. k -> k -> Bool+axEqual :: { forall k::*. forall a::k. Equal k a a ~ True+           ; forall k::*. forall a::k. forall b::k. Equal k a b ~ False }++The coercion (axEqual[1] <*> <Int> <Int) is ill-typed, and Lint should reject it.+(Recall that the index is 0-based, so this is the second branch of the axiom.)+The problem is that, on the surface, it seems that++  (axEqual[1] <*> <Int> <Int>) :: (Equal * Int Int ~ False)++and that all is OK. But, all is not OK: we want to use the first branch of the+axiom in this case, not the second. The problem is that the parameters of the+first branch can unify with the supplied coercions, thus meaning that the first+branch should be taken. See also Note [Apartness] in "GHC.Core.FamInstEnv".++For more details, see the section "Branched axiom conflict checking" in+docs/core-spec, which defines the corresponding no_conflict function used by the+Co_AxiomInstCo rule in the section "Coercion typing".+-}++-- | Check to make sure that an axiom application is internally consistent.+-- Returns the conflicting branch, if it exists+-- Note [Conflict checking for axiom applications]+lintBranch :: Coercion -> TyCon-> CoAxBranch -> [Pair Type] -> LintM ()+-- defined here to avoid dependencies in GHC.Core.Coercion+-- If you edit this function, you may need to update the GHC formalism+-- See Note [GHC Formalism] in GHC.Core.Lint+lintBranch this_co fam_tc branch arg_kinds+  | CoAxBranch { cab_tvs = ktvs, cab_cvs = cvs } <- branch+  = do { checkL (arg_kinds `equalLength` (ktvs ++ cvs)) $+                (bad_ax this_co (text "lengths"))++       ; subst <- getSubst+       ; let empty_subst = zapSubst subst+       ; _ <- foldlM check_ki (empty_subst, empty_subst)+                              (zip (ktvs ++ cvs) arg_kinds)++       ; case check_no_conflict target incomps of+            Nothing -> return ()+            Just bad_branch -> failWithL $ bad_ax this_co $+                               text "inconsistent with" <+>+                                 pprCoAxBranch fam_tc bad_branch }+  where+    check_ki (subst_l, subst_r) (ktv, Pair s' t')+      = do { let sk' = typeKind s'+                 tk' = typeKind t'+           ; let ktv_kind_l = substTy subst_l (tyVarKind ktv)+                 ktv_kind_r = substTy subst_r (tyVarKind ktv)+           ; checkL (sk' `eqType` ktv_kind_l)+                    (bad_ax this_co (text "check_ki1" <+> vcat [ ppr this_co, ppr sk', ppr ktv, ppr ktv_kind_l ] ))+           ; checkL (tk' `eqType` ktv_kind_r)+                    (bad_ax this_co (text "check_ki2" <+> vcat [ ppr this_co, ppr tk', ppr ktv, ppr ktv_kind_r ] ))+           ; return (extendTCvSubst subst_l ktv s',+                     extendTCvSubst subst_r ktv t') }++    tvs          = coAxBranchTyVars branch+    cvs          = coAxBranchCoVars branch+    incomps      = coAxBranchIncomps branch+    (tys, cotys) = splitAtList tvs (map pFst arg_kinds)+    co_args      = map stripCoercionTy cotys+    subst        = zipTvSubst tvs tys `composeTCvSubst`+                   zipCvSubst cvs co_args+    target   = Type.substTys subst (coAxBranchLHS branch)++    check_no_conflict :: [Type] -> [CoAxBranch] -> Maybe CoAxBranch+    check_no_conflict _    [] = Nothing+    check_no_conflict flat (b@CoAxBranch { cab_lhs = lhs_incomp } : rest)+         -- See Note [Apartness] in GHC.Core.FamInstEnv+      | SurelyApart <- tcUnifyTysFG alwaysBindFam alwaysBindTv flat lhs_incomp+      = check_no_conflict flat rest+      | otherwise+      = Just b++bad_ax :: Coercion -> SDoc -> SDoc+bad_ax this_co what+    = hang (text "Bad axiom application" <+> parens what) 2 (ppr this_co)+++{-+************************************************************************+*                                                                      *+              Axioms+*                                                                      *+************************************************************************+-}++lintAxioms :: Logger+           -> LintConfig+           -> SDoc -- ^ The source of the linted axioms+           -> [CoAxiom Branched]+           -> IO ()+lintAxioms logger cfg what axioms =+  displayLintResults logger True what (vcat $ map pprCoAxiom axioms) $+  initL cfg $+  do { mapM_ lint_axiom axioms+     ; let axiom_groups = groupWith coAxiomTyCon axioms+     ; mapM_ lint_axiom_group axiom_groups }++lint_axiom :: CoAxiom Branched -> LintM ()+lint_axiom ax@(CoAxiom { co_ax_tc = tc, co_ax_branches = branches+                       , co_ax_role = ax_role })+  = addLoc (InAxiom ax) $+    do { mapM_ (lint_branch tc) branch_list+       ; extra_checks }+  where+    branch_list = fromBranches branches++    extra_checks+      | isNewTyCon tc+      = do { CoAxBranch { cab_tvs     = ax_tvs+                        , cab_eta_tvs = eta_tvs+                        , cab_cvs     = cvs+                        , cab_roles   = roles+                        , cab_lhs     = lhs_tys }+              <- case branch_list of+               [branch] -> return branch+               _        -> failWithL (text "multi-branch axiom with newtype")++           -- The LHS of the axiom is (N lhs_tys)+           -- We expect it to be      (N ax_tvs)+           ; lintL (mkTyVarTys ax_tvs `eqTypes` lhs_tys)+                   (text "Newtype axiom LHS does not match newtype definition")+           ; lintL (null cvs)+                   (text "Newtype axiom binds coercion variables")+           ; lintL (null eta_tvs)  -- See Note [Eta reduction for data families]+                                   -- which is not about newtype axioms+                   (text "Newtype axiom has eta-tvs")+           ; lintL (ax_role == Representational)+                   (text "Newtype axiom role not representational")+           ; lintL (roles `equalLength` ax_tvs)+                   (text "Newtype axiom roles list is the wrong length." $$+                    text "roles:" <+> sep (map ppr roles))+           ; lintL (roles == takeList roles (tyConRoles tc))+                   (vcat [ text "Newtype axiom roles do not match newtype tycon's."+                         , text "axiom roles:" <+> sep (map ppr roles)+                         , text "tycon roles:" <+> sep (map ppr (tyConRoles tc)) ])+           }++      | isFamilyTyCon tc+      = do { if | isTypeFamilyTyCon tc+                  -> lintL (ax_role == Nominal)+                           (text "type family axiom is not nominal")++                | isDataFamilyTyCon tc+                  -> lintL (ax_role == Representational)+                           (text "data family axiom is not representational")++                | otherwise+                  -> addErrL (text "A family TyCon is neither a type family nor a data family:" <+> ppr tc)++           ; mapM_ (lint_family_branch tc) branch_list }++      | otherwise+      = addErrL (text "Axiom tycon is neither a newtype nor a family.")++lint_branch :: TyCon -> CoAxBranch -> LintM ()+lint_branch ax_tc (CoAxBranch { cab_tvs = tvs, cab_cvs = cvs+                              , cab_lhs = lhs_args, cab_rhs = rhs })+  = lintBinders LambdaBind (tvs ++ cvs) $ \_ ->+    do { let lhs = mkTyConApp ax_tc lhs_args+       ; lintType lhs+       ; lintType rhs+       ; lhs_kind <- substTyM (typeKind lhs)+       ; rhs_kind <- substTyM (typeKind rhs)+       ; lintL (not (lhs_kind `typesAreApart` rhs_kind)) $+         hang (text "Inhomogeneous axiom")+            2 (text "lhs:" <+> ppr lhs <+> dcolon <+> ppr lhs_kind $$+               text "rhs:" <+> ppr rhs <+> dcolon <+> ppr rhs_kind) }+         -- Type and Constraint are not Apart, so this test allows+         -- the newtype axiom for a single-method class.  Indeed the+         -- whole reason Type and Constraint are not Apart is to allow+         -- such axioms!++-- these checks do not apply to newtype axioms+lint_family_branch :: TyCon -> CoAxBranch -> LintM ()+lint_family_branch fam_tc br@(CoAxBranch { cab_tvs     = tvs+                                         , cab_eta_tvs = eta_tvs+                                         , cab_cvs     = cvs+                                         , cab_roles   = roles+                                         , cab_lhs     = lhs+                                         , cab_incomps = incomps })+  = do { lintL (isDataFamilyTyCon fam_tc || null eta_tvs)+               (text "Type family axiom has eta-tvs")+       ; lintL (all (`elemVarSet` tyCoVarsOfTypes lhs) tvs)+               (text "Quantified variable in family axiom unused in LHS")+       ; lintL (all isTyFamFree lhs)+               (text "Type family application on LHS of family axiom")+       ; lintL (all (== Nominal) roles)+               (text "Non-nominal role in family axiom" $$+                text "roles:" <+> sep (map ppr roles))+       ; lintL (null cvs)+               (text "Coercion variables bound in family axiom")+       ; forM_ incomps $ \ br' ->+           lintL (not (compatibleBranches br br')) $+           hang (text "Incorrect incompatible branches:")+              2 (vcat [text "Branch:"       <+> ppr br,+                       text "Bogus incomp:" <+> ppr br']) }++lint_axiom_group :: NonEmpty (CoAxiom Branched) -> LintM ()+lint_axiom_group (_  :| []) = return ()+lint_axiom_group (ax :| axs)+  = do { lintL (isOpenFamilyTyCon tc)+               (text "Non-open-family with multiple axioms")+       ; let all_pairs = [ (ax1, ax2) | ax1 <- all_axs+                                      , ax2 <- all_axs ]+       ; mapM_ (lint_axiom_pair tc) all_pairs }+  where+    all_axs = ax : axs+    tc      = coAxiomTyCon ax++lint_axiom_pair :: TyCon -> (CoAxiom Branched, CoAxiom Branched) -> LintM ()+lint_axiom_pair tc (ax1, ax2)+  | Just br1@(CoAxBranch { cab_tvs = tvs1+                         , cab_lhs = lhs1+                         , cab_rhs = rhs1 }) <- coAxiomSingleBranch_maybe ax1+  , Just br2@(CoAxBranch { cab_tvs = tvs2+                         , cab_lhs = lhs2+                         , cab_rhs = rhs2 }) <- coAxiomSingleBranch_maybe ax2+  = lintL (compatibleBranches br1 br2) $+    vcat [ hsep [ text "Axioms", ppr ax1, text "and", ppr ax2+                , text "are incompatible" ]+         , text "tvs1 =" <+> pprTyVars tvs1+         , text "lhs1 =" <+> ppr (mkTyConApp tc lhs1)+         , text "rhs1 =" <+> ppr rhs1+         , text "tvs2 =" <+> pprTyVars tvs2+         , text "lhs2 =" <+> ppr (mkTyConApp tc lhs2)+         , text "rhs2 =" <+> ppr rhs2 ]++  | otherwise+  = addErrL (text "Open type family axiom has more than one branch: either" <+>+             ppr ax1 <+> text "or" <+> ppr ax2)++{-+************************************************************************+*                                                                      *+\subsection[lint-monad]{The Lint monad}+*                                                                      *+************************************************************************+-}++-- If you edit this type, you may need to update the GHC formalism+-- See Note [GHC Formalism]+data LintEnv+  = LE { le_flags :: LintFlags       -- Linting the result of this pass+       , le_loc   :: [LintLocInfo]   -- Locations++       , le_subst :: Subst+                  -- Current substitution, for TyCoVars only.+                  -- Non-CoVar Ids don't appear in here, not even in the InScopeSet+                  -- Used for (a) cloning to avoid shadowing of TyCoVars,+                  --              so that eqType works ok+                  --          (b) substituting for let-bound tyvars, when we have+                  --              (let @a = Int -> Int in ...)++       , le_in_vars :: VarEnv (InVar, OutType)+                    -- Maps an InVar (i.e. its unique) to its binding InVar+                    --    and to its OutType+                    -- /All/ in-scope variables are here (term variables,+                    --    type variables, and coercion variables)+                    -- Used at an occurrence of the InVar++       , le_joins :: IdSet     -- Join points in scope that are valid+                               -- A subset of the InScopeSet in le_subst+                               -- See Note [Join points]++       , le_ue_aliases :: NameEnv UsageEnv+             -- See Note [Linting linearity]+             -- Assigns usage environments to the alias-like binders,+             -- as found in non-recursive lets.+             -- Domain is OutIds++       , le_platform   :: Platform         -- ^ Target platform+       , le_diagOpts   :: DiagOpts         -- ^ Target platform+       }++data LintFlags+  = LF { lf_check_global_ids           :: Bool -- See Note [Checking for global Ids]+       , lf_check_inline_loop_breakers :: Bool -- See Note [Checking for INLINE loop breakers]+       , lf_check_static_ptrs :: StaticPtrCheck -- ^ See Note [Checking StaticPtrs]+       , lf_report_unsat_syns :: Bool -- ^ See Note [Linting type synonym applications]+       , lf_check_linearity :: Bool -- ^ See Note [Linting linearity]+       , lf_check_fixed_rep :: Bool -- See Note [Checking for representation polymorphism]+    }++-- See Note [Checking StaticPtrs]+data StaticPtrCheck+    = AllowAnywhere+        -- ^ Allow 'makeStatic' to occur anywhere.+    | AllowAtTopLevel+        -- ^ Allow 'makeStatic' calls at the top-level only.+    | RejectEverywhere+        -- ^ Reject any 'makeStatic' occurrence.+  deriving Eq++newtype LintM a =+   LintM' { unLintM ::+            LintEnv ->+            WarnsAndErrs ->           -- Warning and error messages so far+            LResult a } -- Result and messages (if any)+++pattern LintM :: (LintEnv -> WarnsAndErrs -> LResult a) -> LintM a+-- See Note [The one-shot state monad trick] in GHC.Utils.Monad+pattern LintM m <- LintM' m+  where+    LintM m = LintM' (oneShot $ \env -> oneShot $ \we -> m env we)+    -- LintM m = LintM' (oneShot $ oneShot m)+{-# COMPLETE LintM #-}++instance Functor (LintM) where+  fmap f (LintM m) = LintM $ \e w -> mapLResult f (m e w)++type WarnsAndErrs = (Bag SDoc, Bag SDoc)++-- Using a unboxed tuple here reduced allocations for a lint heavy+-- file by ~6%. Using MaybeUB reduced them further by another ~12%.+--+-- Warning: if you don't inline the matcher for JustUB etc, Lint becomes+-- /tremendously/ inefficient, and compiling GHC.Tc.Errors.Types (which+-- contains gigantic types) is very very slow indeed. Conclusion: make+-- sure unfoldings are expose in GHC.Data.Unboxed, and that you compile+-- Lint.hs with optimistation on.+type LResult a = (# MaybeUB a, WarnsAndErrs #)++pattern LResult :: MaybeUB a -> WarnsAndErrs -> LResult a+pattern LResult m w = (# m, w #)+{-# COMPLETE LResult #-}++mapLResult :: (a1 -> a2) -> LResult a1 -> LResult a2+mapLResult f (LResult r w) = LResult (fmapMaybeUB f r) w++-- Just for testing.+fromBoxedLResult :: (Maybe a, WarnsAndErrs) -> LResult a+fromBoxedLResult (Just x, errs) = LResult (JustUB x) errs+fromBoxedLResult (Nothing,errs) = LResult NothingUB errs++{- Note [Checking for global Ids]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+Before CoreTidy, all locally-bound Ids must be LocalIds, even+top-level ones. See Note [Exported LocalIds] and #9857.++Note [Checking StaticPtrs]+~~~~~~~~~~~~~~~~~~~~~~~~~~+See Note [Grand plan for static forms] in GHC.Iface.Tidy.StaticPtrTable for an overview.++Every occurrence of the function 'makeStatic' should be moved to the+top level by the FloatOut pass.  It's vital that we don't have nested+'makeStatic' occurrences after CorePrep, because we populate the Static+Pointer Table from the top-level bindings. See SimplCore Note [Grand+plan for static forms].++The linter checks that no occurrence is left behind, nested within an+expression. The check is enabled only after the FloatOut, CorePrep,+and CoreTidy passes and only if the module uses the StaticPointers+language extension. Checking more often doesn't help since the condition+doesn't hold until after the first FloatOut pass.++Note [Type substitution]+~~~~~~~~~~~~~~~~~~~~~~~~+Why do we need a type substitution?  Consider+        /\(a:*). \(x:a). /\(a:*). id a x+This is ill typed, because (renaming variables) it is really+        /\(a:*). \(x:a). /\(b:*). id b x+Hence, when checking an application, we can't naively compare x's type+(at its binding site) with its expected type (at a use site).  So we+rename type binders as we go, maintaining a substitution.++The same substitution also supports let-type, current expressed as+        (/\(a:*). body) ty+Here we substitute 'ty' for 'a' in 'body', on the fly.++Note [Linting type synonym applications]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+When linting a type-synonym, or type-family, application+  S ty1 .. tyn+we behave as follows (#15057, #T15664):++* If lf_report_unsat_syns = True, and S has arity < n,+  complain about an unsaturated type synonym or type family++* Switch off lf_report_unsat_syns, and lint ty1 .. tyn.++  Reason: catch out of scope variables or other ill-kinded gubbins,+  even if S discards that argument entirely. E.g. (#15012):+     type FakeOut a = Int+     type family TF a+     type instance TF Int = FakeOut a+  Here 'a' is out of scope; but if we expand FakeOut, we conceal+  that out-of-scope error.++  Reason for switching off lf_report_unsat_syns: with+  LiberalTypeSynonyms, GHC allows unsaturated synonyms provided they+  are saturated when the type is expanded. Example+     type T f = f Int+     type S a = a -> a+     type Z = T S+  In Z's RHS, S appears unsaturated, but it is saturated when T is expanded.++* If lf_report_unsat_syns is on, expand the synonym application and+  lint the result.  Reason: want to check that synonyms are saturated+  when the type is expanded.++Note [Linting linearity]+~~~~~~~~~~~~~~~~~~~~~~~~+Lint ignores linearity unless `-dlinear-core-lint` is set.  For why, see below.++* When do we /check linearity/ in Lint?  That is, when is `-dlinear-core-lint`+  lint set?  Answer: we check linearity in the output of the desugarer, shortly+  after type checking.++* When so we /not/ check linearity in Lint?  On all passes after desugaring.  Why?+  Because optimisation passes are not (yet) guaranteed to maintain linearity.+  They should do so semantically (GHC is careful not to duplicate computation)+  but it is much harder to ensure that the statically-checkable constraints of+  Linear Core are maintained. See examples below.++The current Linear Core is described in the wiki at:+https://gitlab.haskell.org/ghc/ghc/-/wikis/linear-types/implementation.++Concretely, "ignore linearity in Lint" specifically means two things:+* In `ensureEqTypes`, use `eqTypeIgnoringMultiplicity`+* In `ensureSubMult`, do nothing++Here are some examples of how the optimiser can break linearity checking.  Other+examples are documented in the linear-type implementation wiki page+[https://gitlab.haskell.org/ghc/ghc/-/wikis/linear-types/implementation#core-to-core-passes]++* EXAMPLE 1: the binder swap transformation+    Consider++      data T = MkT {-# UNPACK #-} !Int++    The wrapper for MkT is++      $wMkT :: Int %1 -> T+      $wMkT n = case %1 n of+        I# n' -> MkT n'++    This introduces, in particular, a `case %1` (this is not actual Haskell or+    Core syntax), where the `%1` means that the `case` expression consumes its+    scrutinee linearly.++    Now, `case %1` interacts with the binder swap optimisation in a non-trivial+    way. Take a slightly modified version of the code for $wMkT:++      case %1 x of z {+        I# n' -> (x, n')+      }++    Binder-swap changes this to++      case %1 x of z {+        I# n' -> let x = z in (x, n')+      }++    This is rejected by `-dlinear-core-lint` because 1/ n' must be used linearly+    2/ `-dlinear-core-lint` recognises a use of `z` as a use of `n'`. So it sees+    two uses of n' where there should be a single one.++* EXAMPLE 2: letrec+    Some optimisations can create a letrec which uses a variable+    linearly, e.g.++      letrec f True = f False+             f False = x+      in f True++    uses 'x' linearly, but this is not seen by the linter, which considers,+    conservatively, that a letrec always has multiplicity Many (in particular+    that every captured free variable must have multiplicity Many). This issue+    is discussed in ticket #18694.++* EXAMPLE 3: rewrite rules+    Ignoring linearity means in particular that `a -> b` and `a %1 -> b` must be+    treated the same by rewrite rules (see also Note [Rewrite rules ignore+    multiplicities in FunTy] in GHC.Core.Unify). Consider++      m :: Bool -> A+      m' :: (Bool -> Bool) -> A+      {- RULES "ex" forall f. m (f True) = m' f -}++      f :: Bool %1 -> A+      x = m (f True)++    The rule "ex" must match . So the linter must accept `m' f`.++* EXAMPLE 4: eta-reduction+   Eta-expansion can change linear functions into unrestricted functions++     f :: A %1 -> B++     g :: A %Many -> B+     g = \x -> f x++   Eta-reduction undoes this and produces:++     g :: A %Many -> B+     g = f++Historical note: In the original linear-types implementation, we had tried to+make every optimisation pass produce code that passes `-dlinear-core-lint`. It+had proved very difficult. We kept finding corner case after corner+case. Furthermore, to attempt to achieve that goal we ended up restricting+transformations when `-dlinear-core-lint` couldn't typecheck the result.++In the future, we may be able to lint the linearity of the output of+Core-to-Core passes (#19165). But this shouldn't be done at the expense of+producing efficient code. Therefore we lay the following principle.++PRINCIPLE: The type system bends to the optimisation, not the other way around.++There is a useful discussion at https://gitlab.haskell.org/ghc/ghc/-/issues/22123++Note [Linting representation-polymorphic builtins]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+As described in Note [Representation-polymorphism checking built-ins], on+top of the two main representation-polymorphism invariants described in the+Note [Representation polymorphism invariants], we must perform additional+representation-polymorphism checks on builtin functions which don't have a+binding, for example to ensure that we don't run afoul of the+representation-polymorphism invariants when eta-expanding.++There are two situations:++  1. Builtins which have skolem type variables which must be instantiated to+     concrete types, such as the RuntimeRep type argument r to the catch# primop.++  2. Representation-polymorphic unlifted newtypes, which must always be instantiated+     at a fixed runtime representation.++For 1, consider for example 'coerce':++  coerce :: forall {r} (a :: TYPE r) (b :: TYPE r). Coercible a b => a -> b++We store in the IdDetails of the coerce Id that the first binder, r, must always+be instantiated to a concrete type. We thus check this in Core Lint: whenever we+see an application of the form++  coerce @{rep1} ...++we ensure that 'rep1' is concrete. This is done in the function "checkRepPolyBuiltinApp".+Moreover, not instantiating these type variables at all is also an error, as+we would again not be able to perform eta-expansion. (This is a bit more theoretical,+as in user programs the typechecker will insert these type applications when+instantiating, but it can still arise when constructing Core expressions).++For 2, whenever we have an unlifted newtype such as++  type RR :: Type -> RuntimeRep+  type family RR a++  type F :: forall (a :: Type) -> TYPE (RR a)+  type family F a++  type N :: forall (a :: Type) -> TYPE (RR a)+  newtype N a = MkN (F a)++and an unsaturated occurrence++  MkN @ty -- NB: no value argument!++we check that the (instantiated) argument type has a fixed runtime representation.+This is done in the function "checkRepPolyNewtypeApp".+-}++instance Applicative LintM where+      pure x = LintM $ \ _ errs -> LResult (JustUB x) errs+                                   --(Just x, errs)+      (<*>) = ap++instance Monad LintM where+  m >>= k  = LintM (\ env errs ->+                       let res = unLintM m env errs in+                         case res of+                           LResult (JustUB r) errs' -> unLintM (k r) env errs'+                           LResult NothingUB errs' -> LResult NothingUB errs'+                    )+                          --  LError errs'-> LError errs')+                      --  let (res, errs') = unLintM m env errs in+                          --  Just r -> unLintM (k r) env errs'+                          --  Nothing -> (Nothing, errs'))++instance MonadFail LintM where+    fail err = failWithL (text err)++getPlatform :: LintM Platform+getPlatform = LintM (\ e errs -> (LResult (JustUB $ le_platform e) errs))++data LintLocInfo+  = RhsOf Id            -- The variable bound+  | OccOf Id            -- Occurrence of id+  | LambdaBodyOf Id     -- The lambda-binder+  | RuleOf Id           -- Rules attached to a binder+  | UnfoldingOf Id      -- Unfolding of a binder+  | BodyOfLet Id        -- The let-bound variable+  | BodyOfLetRec [Id]   -- The binders of the let+  | CaseAlt CoreAlt     -- Case alternative+  | CasePat CoreAlt     -- The *pattern* of the case alternative+  | CaseTy CoreExpr     -- The type field of a case expression+                        -- with this scrutinee+  | IdTy Id             -- The type field of an Id binder+  | AnExpr CoreExpr     -- Some expression+  | ImportedUnfolding SrcLoc -- Some imported unfolding (ToDo: say which)+  | TopLevelBindings+  | InType Type         -- Inside a type+  | InCo   Coercion     -- Inside a coercion+  | InAxiom (CoAxiom Branched)   -- Inside a CoAxiom++data LintConfig = LintConfig+  { l_diagOpts   :: !DiagOpts         -- ^ Diagnostics opts+  , l_platform   :: !Platform         -- ^ Target platform+  , l_flags      :: !LintFlags        -- ^ Linting the result of this pass+  , l_vars       :: ![Var]            -- ^ 'Id's that should be treated as being in scope+  }++initL :: LintConfig+      -> LintM a            -- ^ Action to run+      -> WarnsAndErrs+initL cfg m+  = case unLintM m env (emptyBag, emptyBag) of+      LResult (JustUB _) errs -> errs+      LResult NothingUB errs@(_, e) | not (isEmptyBag e) -> errs+                                    | otherwise -> pprPanic ("Bug in Lint: a failure occurred " +++                                                      "without reporting an error message") empty+  where+    vars = l_vars cfg+    env = LE { le_flags   = l_flags cfg+             , le_subst   = mkEmptySubst (mkInScopeSetList vars)+             , le_in_vars = mkVarEnv [ (v,(v, varType v)) | v <- vars ]+             , le_joins   = emptyVarSet+             , le_loc     = []+             , le_ue_aliases = emptyNameEnv+             , le_platform = l_platform cfg+             , le_diagOpts = l_diagOpts cfg+             }++setReportUnsat :: Bool -> LintM a -> LintM a+-- Switch off lf_report_unsat_syns+setReportUnsat ru thing_inside+  = LintM $ \ env errs ->+    let env' = env { le_flags = (le_flags env) { lf_report_unsat_syns = ru } }+    in unLintM thing_inside env' errs++-- See Note [Checking for representation polymorphism]+noFixedRuntimeRepChecks :: LintM a -> LintM a+noFixedRuntimeRepChecks thing_inside+  = LintM $ \env errs ->+    let env' = env { le_flags = (le_flags env) { lf_check_fixed_rep = False } }+    in unLintM thing_inside env' errs++getLintFlags :: LintM LintFlags+getLintFlags = LintM $ \ env errs -> fromBoxedLResult (Just (le_flags env), errs)++checkL :: Bool -> SDoc -> LintM ()+checkL True  _   = return ()+checkL False msg = failWithL msg++-- like checkL, but relevant to type checking+lintL :: Bool -> SDoc -> LintM ()+lintL = checkL++checkWarnL :: Bool -> SDoc -> LintM ()+checkWarnL True   _  = return ()+checkWarnL False msg = addWarnL msg++failWithL :: SDoc -> LintM a+failWithL msg = LintM $ \ env (warns,errs) ->+                fromBoxedLResult (Nothing, (warns, addMsg True env errs msg))++addErrL :: SDoc -> LintM ()+addErrL msg = LintM $ \ env (warns,errs) ->+              fromBoxedLResult (Just (), (warns, addMsg True env errs msg))++addWarnL :: SDoc -> LintM ()+addWarnL msg = LintM $ \ env (warns,errs) ->+              fromBoxedLResult (Just (), (addMsg True env warns msg, errs))++addMsg :: Bool -> LintEnv ->  Bag SDoc -> SDoc -> Bag SDoc+addMsg show_context env msgs msg+  = assertPpr (notNull loc_msgs) msg $+    msgs `snocBag` mk_msg msg+  where+   loc_msgs :: [(SrcLoc, SDoc)]  -- Innermost first+   loc_msgs = map dumpLoc (le_loc env)++   cxt_doc = vcat [ vcat $ reverse $ map snd loc_msgs+                  , text "Substitution:" <+> ppr (le_subst env) ]++   context | show_context  = cxt_doc+           | otherwise     = whenPprDebug cxt_doc+     -- Print voluminous info for Lint errors+     -- but not for warnings++   msg_span = case [ span | (loc,_) <- loc_msgs+                          , let span = srcLocSpan loc+                          , isGoodSrcSpan span ] of+               []    -> noSrcSpan+               (s:_) -> s+   !diag_opts = le_diagOpts env+   mk_msg msg = mkLocMessage (mkMCDiagnostic diag_opts WarningWithoutFlag Nothing) msg_span+                             (msg $$ context)++addLoc :: LintLocInfo -> LintM a -> LintM a+addLoc extra_loc m+  = LintM $ \ env errs ->+    unLintM m (env { le_loc = extra_loc : le_loc env }) errs++inCasePat :: LintM Bool         -- A slight hack; see the unique call site+inCasePat = LintM $ \ env errs -> fromBoxedLResult (Just (is_case_pat env), errs)+  where+    is_case_pat (LE { le_loc = CasePat {} : _ }) = True+    is_case_pat _other                           = False++addInScopeId :: InId -> OutType -> (OutId -> LintM a) -> LintM a+-- Unlike addInScopeTyCoVar, this function does no cloning; Ids never get cloned+addInScopeId in_id out_ty thing_inside+  = LintM $ \ env errs ->+    let !(out_id, env') = add env+    in unLintM (thing_inside out_id) env' errs++  where+    add env@(LE { le_in_vars = id_vars, le_joins = join_set+                , le_ue_aliases = aliases, le_subst = subst })+      = (out_id, env1)+      where+        env1 = env { le_in_vars = in_vars', le_joins = join_set', le_ue_aliases = aliases' }++        in_vars' = extendVarEnv id_vars in_id (in_id, out_ty)+        aliases' = delFromNameEnv aliases (idName in_id)+           -- aliases': when shadowing an alias, we need to make sure the+           -- Id is no longer classified as such. E.g.+           --   let x = <e1> in case x of x { _DEFAULT -> <e2> }+           -- Occurrences of 'x' in e2 shouldn't count as occurrences of e1.++        -- A very tiny optimisation, not sure if it's really worth it+        -- Short-cut when the substitution is a no-op+        out_id | isEmptyTCvSubst subst = in_id+               | otherwise             = setIdType in_id out_ty++        join_set'+          | isJoinId out_id = extendVarSet join_set in_id -- Overwrite with new arity+          | otherwise       = delVarSet    join_set in_id -- Remove any existing binding++addInScopeTyCoVar :: InTyCoVar -> OutType -> (OutTyCoVar -> LintM a) -> LintM a+-- This function clones to avoid shadowing of TyCoVars+addInScopeTyCoVar tcv tcv_type thing_inside+  = LintM $ \ env@(LE { le_in_vars = in_vars, le_subst = subst }) errs ->+    let (tcv', subst') = subst_bndr subst+        env' = env { le_in_vars = extendVarEnv in_vars tcv (tcv, tcv_type)+                   , le_subst = subst' }+    in unLintM (thing_inside tcv') env' errs+  where+    subst_bndr subst+      | isEmptyTCvSubst subst                -- No change in kind+      , not (tcv `elemInScopeSet` in_scope)  -- Not already in scope+      = -- Do not extend the substitution, just the in-scope set+        (if (varType tcv `eqType` tcv_type) then (\x->x) else+          pprTrace "addInScopeTyCoVar" (+            vcat [ text "tcv" <+> ppr tcv <+> dcolon <+> ppr (varType tcv)+                 , text "tcv_type" <+> ppr tcv_type ])) $+        (tcv, subst `extendSubstInScope` tcv)++      -- Clone, and extend the substitution+      | let tcv' = uniqAway in_scope (setVarType tcv tcv_type)+      = (tcv', extendTCvSubstWithClone subst tcv tcv')+      where+        in_scope = substInScopeSet subst++getInVarEnv :: LintM (VarEnv (InId, OutType))+getInVarEnv = LintM (\env errs -> fromBoxedLResult (Just (le_in_vars env), errs))++extendTvSubstL :: TyVar -> Type -> LintM a -> LintM a+extendTvSubstL tv ty m+  = LintM $ \ env errs ->+    unLintM m (env { le_subst = Type.extendTvSubst (le_subst env) tv ty }) errs++markAllJoinsBad :: LintM a -> LintM a+markAllJoinsBad m+  = LintM $ \ env errs -> unLintM m (env { le_joins = emptyVarSet }) errs++markAllJoinsBadIf :: Bool -> LintM a -> LintM a+markAllJoinsBadIf True  m = markAllJoinsBad m+markAllJoinsBadIf False m = m++getValidJoins :: LintM IdSet+getValidJoins = LintM (\ env errs -> fromBoxedLResult (Just (le_joins env), errs))++getSubst :: LintM Subst+getSubst = LintM (\ env errs -> fromBoxedLResult (Just (le_subst env), errs))++substTyM :: InType -> LintM OutType+-- Apply the substitution to the type+-- The substitution is often empty, in which case it is a no-op+substTyM ty+  = do { subst <- getSubst+       ; return (substTy subst ty) }++getUEAliases :: LintM (NameEnv UsageEnv)+getUEAliases = LintM (\ env errs -> fromBoxedLResult (Just (le_ue_aliases env), errs))++getInScope :: LintM InScopeSet+getInScope = LintM (\ env errs -> fromBoxedLResult (Just (substInScopeSet $ le_subst env), errs))++lintVarOcc :: InVar -> LintM OutType+-- Used at an occurrence of a variable: term variables, type variables, and coercion variables+-- Checks two things:+-- a) that it is in scope+-- b) that the InType at the ocurrences matches the InType at the binding site+lintVarOcc v_occ+  = do { in_var_env <- getInVarEnv+       ; case lookupVarEnv in_var_env v_occ of+           Nothing | isGlobalId v_occ -> return (idType v_occ)+                   | otherwise        -> failWithL (text pp_what <+> quotes (ppr v_occ)+                                                    <+> text "is out of scope")+           Just (v_bndr, out_ty) -> do { check_bad_global v_bndr+                                       ; ensureEqTys occ_ty bndr_ty $  -- Compares InTypes+                                         mkBndrOccTypeMismatchMsg v_occ bndr_ty occ_ty+                                       ; return out_ty }+             where+               occ_ty  = varType v_occ+               bndr_ty = varType v_bndr }+  where+    pp_what | isTyVar v_occ = "The type variable"+            | isCoVar v_occ = "The coercion variable"+            | otherwise     = "The value variable"++       -- 'check_bad_global' checks for the case where an /occurrence/ is+       -- a GlobalId, but there is an enclosing binding fora a LocalId.+       -- NB: the in-scope variables are mostly LocalIds, checked by lintIdBndr,+       --     but GHCi adds GlobalIds from the interactive context.  These+       --     are fine; hence the test (isLocalId id == isLocalId v)+       -- NB: when compiling Control.Exception.Base, things like absentError+       --     are defined locally, but appear in expressions as (global)+       --     wired-in Ids after worker/wrapper+       --     So we simply disable the test in this case+    check_bad_global v_bndr+      | isGlobalId v_occ+      , isLocalId v_bndr+      , not (isWiredIn v_occ)+      = failWithL $ hang (text "Occurrence is GlobalId, but binding is LocalId")+                       2 (vcat [ hang (text "occurrence:") 2 $ pprBndr LetBind v_occ+                               , hang (text "binder    :") 2 $ pprBndr LetBind v_bndr ])+      | otherwise+      = return ()++lookupJoinId :: Id -> LintM JoinPointHood+-- Look up an Id which should be a join point, valid here+-- If so, return its arity, if not return Nothing+lookupJoinId id+  = do { join_set <- getValidJoins+       ; case lookupVarSet join_set id of+            Just id' -> return (idJoinPointHood id')+            Nothing  -> return NotJoinPoint }++addAliasUE :: OutId -> UsageEnv -> LintM a -> LintM a+addAliasUE id ue thing_inside = LintM $ \ env errs ->+  let new_ue_aliases =+        extendNameEnv (le_ue_aliases env) (getName id) ue+  in+    unLintM thing_inside (env { le_ue_aliases = new_ue_aliases }) errs++varCallSiteUsage :: OutId -> LintM UsageEnv+varCallSiteUsage id =+  do m <- getUEAliases+     return $ case lookupNameEnv m (getName id) of+         Nothing    -> singleUsageUE id+         Just id_ue -> id_ue++ensureEqTys :: OutType -> OutType -> SDoc -> LintM ()+-- check ty2 is subtype of ty1 (ie, has same structure but usage+-- annotations need only be consistent, not equal)+-- Assumes ty1,ty2 are have already had the substitution applied+{-# INLINE ensureEqTys #-} -- See Note [INLINE ensureEqTys]+ensureEqTys ty1 ty2 msg+  = do { flags <- getLintFlags+       ; lintL (eq_type flags ty1 ty2) msg }++eq_type :: LintFlags -> Type -> Type -> Bool+-- When `-dlinear-core-lint` is off, then consider `a -> b` and `a %1 -> b` to+-- be equal. See Note [Linting linearity].+eq_type flags ty1 ty2 | lf_check_linearity flags = eqType                     ty1 ty2+                      | otherwise                = eqTypeIgnoringMultiplicity ty1 ty2++{- Note [INLINE ensureEqTys]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~+To make Lint fast, we want to avoid allocating a thunk for <msg> in+      ensureEqTypes ty1 ty2 <msg>+because the test almost always succeeds, and <msg> isn't needed.+So we INLINE `ensureEqTys`.  This actually make a difference of+1-2% when compiling programs with -dcore-lint.+-}++ensureSubUsage :: Usage -> Mult -> SDoc -> LintM ()+ensureSubUsage Bottom     _              _ = return ()+ensureSubUsage Zero       described_mult err_msg = ensureSubMult ManyTy described_mult err_msg+ensureSubUsage (MUsage m) described_mult err_msg = ensureSubMult m described_mult err_msg++ensureSubMult :: Mult -> Mult -> SDoc -> LintM ()+ensureSubMult actual_mult described_mult err_msg = do+    flags <- getLintFlags+    when (lf_check_linearity flags) $+      unless (deepSubMult actual_mult described_mult) $+        addErrL err_msg+  where+    -- Check for submultiplicity using the following rules:+    -- 1. x*y <= z when x <= z and y <= z.+    --    This rule follows from the fact that x*y = sup{x,y} for any+    --    multiplicities x,y.+    -- 2. x <= y*z when x <= y or x <= z.+    --    This rule is not complete: when x = y*z, we cannot+    --    change y*z <= y*z to y*z <= y or y*z <= z.+    --    However, we eliminate products on the LHS in step 1.+    -- 3. One <= x and x <= Many for any x, as checked by 'submult'.+    -- 4. x <= x.+    -- Otherwise, we fail.+    deepSubMult :: Mult -> Mult -> Bool+    deepSubMult m n+      | Just (m1, m2) <- isMultMul m = deepSubMult m1 n  && deepSubMult m2 n+      | Just (n1, n2) <- isMultMul n = deepSubMult m  n1 || deepSubMult m  n2+      | Submult <- m `submult` n = True+      | otherwise = m `eqType` n++lintRole :: Outputable thing+          => thing     -- where the role appeared+          -> Role      -- expected+          -> Role      -- actual+          -> LintM ()+lintRole co r1 r2+  = lintL (r1 == r2)+          (text "Role incompatibility: expected" <+> ppr r1 <> comma <+>+           text "got" <+> ppr r2 $$+           text "in" <+> ppr co)++{-+************************************************************************+*                                                                      *+\subsection{Error messages}+*                                                                      *+************************************************************************+-}++dumpLoc :: LintLocInfo -> (SrcLoc, SDoc)++dumpLoc (RhsOf v)+  = (getSrcLoc v, text "In the RHS of" <+> pp_binders [v])++dumpLoc (OccOf v)+  = (getSrcLoc v, text "In an occurrence of" <+> pp_binder v)++dumpLoc (LambdaBodyOf b)+  = (getSrcLoc b, text "In the body of lambda with binder" <+> pp_binder b)++dumpLoc (RuleOf b)+  = (getSrcLoc b, text "In a rule attached to" <+> pp_binder b)++dumpLoc (UnfoldingOf b)+  = (getSrcLoc b, text "In the unfolding of" <+> pp_binder b)++dumpLoc (BodyOfLet b)+  = (noSrcLoc, text "In the body of a let with binder" <+> pp_binder b)++dumpLoc (BodyOfLetRec [])+  = (noSrcLoc, text "In body of a letrec with no binders")++dumpLoc (BodyOfLetRec bs@(b:_))+  = ( getSrcLoc b, text "In the body of a letrec with binders" <+> pp_binders bs)++dumpLoc (AnExpr e)+  = (noSrcLoc, text "In the expression:" <+> ppr e)++dumpLoc (CaseAlt (Alt con args _))+  = (noSrcLoc, text "In a case alternative:" <+> parens (ppr con <+> pp_binders args))++dumpLoc (CasePat (Alt con args _))+  = (noSrcLoc, text "In the pattern of a case alternative:" <+> parens (ppr con <+> pp_binders args))++dumpLoc (CaseTy scrut)+  = (noSrcLoc, hang (text "In the result-type of a case with scrutinee:")+                  2 (ppr scrut))++dumpLoc (IdTy b)+  = (getSrcLoc b, text "In the type of a binder:" <+> ppr b)++dumpLoc (ImportedUnfolding locn)+  = (locn, text "In an imported unfolding")+dumpLoc TopLevelBindings+  = (noSrcLoc, Outputable.empty)+dumpLoc (InType ty)+  = (noSrcLoc, text "In the type" <+> quotes (ppr ty))+dumpLoc (InCo co)+  = (noSrcLoc, text "In the coercion" <+> quotes (ppr co))+dumpLoc (InAxiom ax)+  = (getSrcLoc ax, hang (text "In the coercion axiom")+                      2 (pprCoAxiom ax))++pp_binders :: [Var] -> SDoc+pp_binders bs = sep (punctuate comma (map pp_binder bs))++pp_binder :: Var -> SDoc+pp_binder b | isId b    = hsep [ppr b, dcolon, ppr (idType b)]+            | otherwise = hsep [ppr b, dcolon, ppr (tyVarKind b)]++------------------------------------------------------+--      Messages for case expressions++mkDefaultArgsMsg :: [Var] -> SDoc+mkDefaultArgsMsg args+  = hang (text "DEFAULT case with binders")+         4 (ppr args)++mkCaseAltMsg :: CoreExpr -> Type -> Type -> SDoc+mkCaseAltMsg e ty1 ty2+  = hang (text "Type of case alternatives not the same as the annotation on case:")+         4 (vcat [ text "Actual type:" <+> ppr ty1,+                   text "Annotation on case:" <+> ppr ty2,+                   text "Alt Rhs:" <+> ppr e ])++mkScrutMsg :: Id -> Type -> Type -> SDoc+mkScrutMsg var var_ty scrut_ty+  = vcat [text "Result binder in case doesn't match scrutinee:" <+> ppr var,+          text "Result binder type:" <+> ppr var_ty,--(idType var),+          text "Scrutinee type:" <+> ppr scrut_ty]++mkNonDefltMsg, mkNonIncreasingAltsMsg :: CoreExpr -> SDoc+mkNonDefltMsg e+  = hang (text "Case expression with DEFAULT not at the beginning") 4 (ppr e)+mkNonIncreasingAltsMsg e+  = hang (text "Case expression with badly-ordered alternatives") 4 (ppr e)++nonExhaustiveAltsMsg :: CoreExpr -> SDoc+nonExhaustiveAltsMsg e+  = hang (text "Case expression with non-exhaustive alternatives") 4 (ppr e)++mkBadConMsg :: TyCon -> DataCon -> SDoc+mkBadConMsg tycon datacon+  = vcat [+        text "In a case alternative, data constructor isn't in scrutinee type:",+        text "Scrutinee type constructor:" <+> ppr tycon,+        text "Data con:" <+> ppr datacon+    ]++mkBadPatMsg :: Type -> Type -> SDoc+mkBadPatMsg con_result_ty scrut_ty+  = vcat [+        text "In a case alternative, pattern result type doesn't match scrutinee type:",+        text "Pattern result type:" <+> ppr con_result_ty,+        text "Scrutinee type:" <+> ppr scrut_ty+    ]++integerScrutinisedMsg :: SDoc+integerScrutinisedMsg+  = text "In a LitAlt, the literal is lifted (probably Integer)"++mkBadAltMsg :: Type -> CoreAlt -> SDoc+mkBadAltMsg scrut_ty alt+  = vcat [ text "Data alternative when scrutinee is not a tycon application",+           text "Scrutinee type:" <+> ppr scrut_ty,+           text "Alternative:" <+> pprCoreAlt alt ]++mkNewTyDataConAltMsg :: Type -> CoreAlt -> SDoc+mkNewTyDataConAltMsg scrut_ty alt+  = vcat [ text "Data alternative for newtype datacon",+           text "Scrutinee type:" <+> ppr scrut_ty,+           text "Alternative:" <+> pprCoreAlt alt ]+++------------------------------------------------------+--      Other error messages++mkAppMsg :: Type -> Type -> CoreExpr -> SDoc+mkAppMsg expected_arg_ty actual_arg_ty arg+  = vcat [text "Argument value doesn't match argument type:",+              hang (text "Expected arg type:") 4 (ppr expected_arg_ty),+              hang (text "Actual arg type:") 4 (ppr actual_arg_ty),+              hang (text "Arg:") 4 (ppr arg)]++mkNonFunAppMsg :: Type -> Type -> CoreExpr -> SDoc+mkNonFunAppMsg fun_ty arg_ty arg+  = vcat [text "Non-function type in function position",+              hang (text "Fun type:") 4 (ppr fun_ty),+              hang (text "Arg type:") 4 (ppr arg_ty),+              hang (text "Arg:") 4 (ppr arg)]++mkLetErr :: TyVar -> CoreExpr -> SDoc+mkLetErr bndr rhs+  = vcat [text "Bad `let' binding:",+          hang (text "Variable:")+                 4 (ppr bndr <+> dcolon <+> ppr (varType bndr)),+          hang (text "Rhs:")+                 4 (ppr rhs)]++mkTyAppMsg :: OutType -> Type -> SDoc+mkTyAppMsg ty arg_ty+  = vcat [text "Illegal type application:",+              hang (text "Function type:")+                 4 (ppr ty <+> dcolon <+> ppr (typeKind ty)),+              hang (text "Type argument:")+                 4 (ppr arg_ty <+> dcolon <+> ppr (typeKind arg_ty))]++emptyRec :: CoreExpr -> SDoc+emptyRec e = hang (text "Empty Rec binding:") 2 (ppr e)++mkRhsMsg :: Id -> SDoc -> Type -> SDoc+mkRhsMsg binder what ty+  = vcat+    [hsep [text "The type of this binder doesn't match the type of its" <+> what <> colon,+            ppr binder],+     hsep [text "Binder's type:", ppr (idType binder)],+     hsep [text "Rhs type:", ppr ty]]++badBndrTyMsg :: Id -> SDoc -> SDoc+badBndrTyMsg binder what+  = vcat [ text "The type of this binder is" <+> what <> colon <+> ppr binder+         , text "Binder's type:" <+> ppr (idType binder) ]++mkNonTopExportedMsg :: Id -> SDoc+mkNonTopExportedMsg binder+  = hsep [text "Non-top-level binder is marked as exported:", ppr binder]++mkNonTopExternalNameMsg :: Id -> SDoc+mkNonTopExternalNameMsg binder+  = hsep [text "Non-top-level binder has an external name:", ppr binder]++mkTopNonLitStrMsg :: Id -> SDoc+mkTopNonLitStrMsg binder+  = hsep [text "Top-level Addr# binder has a non-literal rhs:", ppr binder]++mkKindErrMsg :: TyVar -> Type -> SDoc+mkKindErrMsg tyvar arg_ty+  = vcat [text "Kinds don't match in type application:",+          hang (text "Type variable:")+                 4 (ppr tyvar <+> dcolon <+> ppr (tyVarKind tyvar)),+          hang (text "Arg type:")+                 4 (ppr arg_ty <+> dcolon <+> ppr (typeKind arg_ty))]++mkCastErr :: CoreExpr -> Coercion -> Type -> Type -> SDoc+mkCastErr expr = mk_cast_err "expression" "type" (ppr expr)++mkCastTyErr :: Type -> Coercion -> Kind -> Kind -> SDoc+mkCastTyErr ty = mk_cast_err "type" "kind" (ppr ty)++mk_cast_err :: String -- ^ What sort of casted thing this is+                      --   (\"expression\" or \"type\").+            -> String -- ^ What sort of coercion is being used+                      --   (\"type\" or \"kind\").+            -> SDoc   -- ^ The thing being casted.+            -> Coercion -> Type -> Type -> SDoc+mk_cast_err thing_str co_str pp_thing co from_ty thing_ty+  = vcat [from_msg <+> text "of Cast differs from" <+> co_msg+            <+> text "of" <+> enclosed_msg,+          from_msg <> colon <+> ppr from_ty,+          text (capitalise co_str) <+> text "of" <+> enclosed_msg <> colon+            <+> ppr thing_ty,+          text "Actual" <+> enclosed_msg <> colon <+> pp_thing,+          text "Coercion used in cast:" <+> ppr co+         ]+  where+    co_msg, from_msg, enclosed_msg :: SDoc+    co_msg       = text co_str+    from_msg     = text "From-" <> co_msg+    enclosed_msg = text "enclosed" <+> text thing_str++mkBadTyVarMsg :: Var -> SDoc+mkBadTyVarMsg tv+  = text "Non-tyvar used in TyVarTy:"+      <+> ppr tv <+> dcolon <+> ppr (varType tv)++mkBadJoinBindMsg :: Var -> SDoc+mkBadJoinBindMsg var+  = vcat [ text "Bad join point binding:" <+> ppr var+         , text "Join points can be bound only by a non-top-level let" ]++mkInvalidJoinPointMsg :: Var -> Type -> SDoc+mkInvalidJoinPointMsg var ty+  = hang (text "Join point has invalid type:")+        2 (ppr var <+> dcolon <+> ppr ty)++mkBadJoinArityMsg :: Var -> Int -> Int -> CoreExpr -> SDoc+mkBadJoinArityMsg var ar n rhs+  = vcat [ text "Join point has too few lambdas",+           text "Join var:" <+> ppr var,+           text "Join arity:" <+> ppr ar,+           text "Number of lambdas:" <+> ppr (ar - n),+           text "Rhs = " <+> ppr rhs+           ]++invalidJoinOcc :: Var -> SDoc+invalidJoinOcc var+  = vcat [ text "Invalid occurrence of a join variable:" <+> ppr var+         , text "The binder is either not a join point, or not valid here" ]++mkBadJumpMsg :: Var -> Int -> Int -> SDoc+mkBadJumpMsg var ar nargs+  = vcat [ text "Join point invoked with wrong number of arguments",+           text "Join var:" <+> ppr var,+           text "Join arity:" <+> ppr ar,+           text "Number of arguments:" <+> int nargs ]++mkInconsistentRecMsg :: [Var] -> SDoc+mkInconsistentRecMsg bndrs+  = vcat [ text "Recursive let binders mix values and join points",+           text "Binders:" <+> hsep (map ppr_with_details bndrs) ]+  where+    ppr_with_details bndr = ppr bndr <> ppr (idDetails bndr)++mkJoinBndrOccMismatchMsg :: Var -> JoinArity -> JoinArity -> SDoc+mkJoinBndrOccMismatchMsg bndr join_arity_bndr join_arity_occ+  = vcat [ text "Mismatch in join point arity between binder and occurrence"+         , text "Var:" <+> ppr bndr+         , text "Arity at binding site:" <+> ppr join_arity_bndr+         , text "Arity at occurrence:  " <+> ppr join_arity_occ ]++mkBndrOccTypeMismatchMsg :: InVar -> InType -> InType -> SDoc+mkBndrOccTypeMismatchMsg var bndr_ty occ_ty+  = vcat [ text "Mismatch in type between binder and occurrence"+         , text "Binder:    " <+> ppr var <+> dcolon <+> ppr bndr_ty+         , text "Occurrence:" <+> ppr var <+> dcolon <+> ppr occ_ty ]  mkBadJoinPointRuleMsg :: JoinId -> JoinArity -> CoreRule -> SDoc mkBadJoinPointRuleMsg bndr join_arity rule
GHC/Core/Make.hs view
@@ -1,11 +1,10 @@-{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-}- -- | Handy functions for creating much Core syntax module GHC.Core.Make (         -- * Constructing normal syntax         mkCoreLet, mkCoreLets,-        mkCoreApp, mkCoreApps, mkCoreConApps,-        mkCoreLams, mkWildCase, mkIfThenElse,+        mkCoreApp, mkCoreApps, mkCoreConApps, mkCoreConWrapApps,+        mkCoreLams, mkCoreTyLams,+        mkWildCase, mkIfThenElse,         mkWildValBinder,         mkSingleAltCase,         sortQuantVars, castBottomExpr,@@ -65,12 +64,12 @@ import GHC.Types.Unique.Supply  import GHC.Core-import GHC.Core.Utils ( exprType, mkSingleAltCase, bindNonRec )+import GHC.Core.Utils ( exprType, mkSingleAltCase, bindNonRec, mkCast ) import GHC.Core.Type-import GHC.Core.Predicate    ( isCoVarType )+import GHC.Core.Predicate    ( scopedSort, isEqPred ) import GHC.Core.TyCo.Compare ( eqType )-import GHC.Core.Coercion     ( isCoVar )-import GHC.Core.DataCon      ( DataCon, dataConWorkId )+import GHC.Core.Coercion     ( isCoVar, mkRepReflCo, mkForAllVisCos )+import GHC.Core.DataCon      ( DataCon, dataConWorkId, dataConWrapId ) import GHC.Core.Multiplicity  import GHC.Builtin.Types@@ -83,8 +82,10 @@  import GHC.Settings.Constants( mAX_TUPLE_SIZE ) import GHC.Data.FastString+import GHC.Data.Maybe ( expectJust )  import Data.List        ( partition )+import Data.List.NonEmpty ( NonEmpty (..) ) import Data.Char        ( ord )  infixl 4 `mkCoreApp`, `mkCoreApps`@@ -122,6 +123,14 @@ mkCoreLams :: [CoreBndr] -> CoreExpr -> CoreExpr mkCoreLams = mkLams +-- | Create a type lambda (/\a b c. e) and apply a cast to fix up visibilities+-- if needed. See Note [Required foralls in Core]+mkCoreTyLams :: [TyVarBinder] -> CoreExpr -> CoreExpr+mkCoreTyLams binders body = mkCast lam co+  where+    lam = mkCoreLams (binderVars binders) body+    co  = mkForAllVisCos binders (mkRepReflCo (exprType body))+ -- | Bind a list of binding groups over an expression. The leftmost binding -- group becomes the outermost group in the resulting expression mkCoreLets :: [CoreBind] -> CoreExpr -> CoreExpr@@ -133,6 +142,13 @@ mkCoreConApps :: DataCon -> [CoreExpr] -> CoreExpr mkCoreConApps con args = mkCoreApps (Var (dataConWorkId con)) args +-- | A variant of 'mkCoreConApps' constructs an expression which represents the+-- application of a number of expressions to that of a data constructor+-- expression using the wrapper, not the worker, of the data constructor. The+-- leftmost expression in the list is applied first+mkCoreConWrapApps :: DataCon -> [CoreExpr] -> CoreExpr+mkCoreConWrapApps con args = mkCoreApps (Var (dataConWrapId con)) args+ -- | Construct an expression which represents the application of a number of -- expressions to another. The leftmost expression in the list is applied first mkCoreApps :: CoreExpr -- ^ function@@ -224,12 +240,12 @@ mkLitRubbish ty   | not (noFreeVarsOfType rep)   = Nothing   -- Satisfy INVARIANT 1-  | isCoVarType ty+  | isEqPred ty   = Nothing   -- Satisfy INVARIANT 2   | otherwise   = Just (Lit (LitRubbish torc rep) `mkTyApps` [ty])   where-    Just (torc, rep) = sORTKind_maybe (typeKind ty)+    (torc, rep) = expectJust $ sORTKind_maybe (typeKind ty)  {- ************************************************************************@@ -609,8 +625,13 @@         where           tpl_tys = [mkBoxedTupleTy (map idType gp) | gp <- vars_s]           tpl_vs  = mkTemplateLocals tpl_tys-          [(tpl_v, group)] = [(tpl,gp) | (tpl,gp) <- zipEqual "mkBigTupleSelector" tpl_vs vars_s,-                                         the_var `elem` gp ]+          (tpl_v, group) = case+            [ (tpl,gp)+            | (tpl,gp) <- zipEqual tpl_vs vars_s+            , the_var `elem` gp+            ] of+              [x] -> x+              _ -> panic "mkBigTupleSelector" -- ^ 'mkBigTupleSelectorSolo' is like 'mkBigTupleSelector' -- but one-tuples are NOT flattened (see Note [Flattening one-tuples]) mkBigTupleSelectorSolo vars the_var scrut_var scrut@@ -1277,7 +1298,7 @@ mkRuntimeErrorTy torc = mkSpecForAllTys [runtimeRep1TyVar, tyvar] $                         mkFunctionType ManyTy addrPrimTy (mkTyVarTy tyvar)   where-    (tyvar:_) = mkTemplateTyVars [kind]+    tyvar:|_ = expectNonEmpty $ mkTemplateTyVars [kind]     kind = case torc of               TypeLike       -> mkTYPEapp       runtimeRep1Ty               ConstraintLike -> mkCONSTRAINTapp runtimeRep1Ty
GHC/Core/Map/Expr.hs view
@@ -122,6 +122,7 @@     alterTM k f (CoreMap m) = CoreMap (alterTM (deBruijnize k) f m)     foldTM k (CoreMap m) = foldTM k m     filterTM f (CoreMap m) = CoreMap (filterTM f m)+    mapMaybeTM f (CoreMap m) = CoreMap (mapMaybeTM f m)  -- | @CoreMapG a@ is a map from @DeBruijn CoreExpr@ to @a@.  The extended -- key makes it suitable for recursive traversal, since it can track binders,@@ -197,11 +198,10 @@  eqDeBruijnTickish :: DeBruijn CoreTickish -> DeBruijn CoreTickish -> Bool eqDeBruijnTickish (D env1 t1) (D env2 t2) = go t1 t2 where-    go (Breakpoint lext lid lids lmod) (Breakpoint rext rid rids rmod)+    go (Breakpoint lext lid lids) (Breakpoint rext rid rids)         =  lid == rid         && D env1 lids == D env2 rids         && lext == rext-        && lmod == rmod     go l r = l == r  -- Compares for equality, modulo alpha@@ -271,6 +271,7 @@    alterTM  = xtE    foldTM   = fdE    filterTM = ftE+   mapMaybeTM = mpE  -------------------------- ftE :: (a->Bool) -> CoreMapX a -> CoreMapX a@@ -287,6 +288,20 @@        , cm_letr = fmap (fmap (filterTM f)) cletr, cm_case = fmap (filterTM f) ccase        , cm_ecase = fmap (filterTM f) cecase, cm_tick = fmap (filterTM f) ctick } +mpE :: (a -> Maybe b) -> CoreMapX a -> CoreMapX b+mpE f (CM { cm_var = cvar, cm_lit = clit+          , cm_co = cco, cm_type = ctype+          , cm_cast = ccast , cm_app = capp+          , cm_lam = clam, cm_letn = cletn+          , cm_letr = cletr, cm_case = ccase+          , cm_ecase = cecase, cm_tick = ctick })+  = CM { cm_var = mapMaybeTM f cvar, cm_lit = mapMaybeTM f clit+       , cm_co = mapMaybeTM f cco, cm_type = mapMaybeTM f ctype+       , cm_cast = fmap (mapMaybeTM f) ccast, cm_app = fmap (mapMaybeTM f) capp+       , cm_lam = fmap (mapMaybeTM f) clam, cm_letn = fmap (fmap (mapMaybeTM f)) cletn+       , cm_letr = fmap (fmap (mapMaybeTM f)) cletr, cm_case = fmap (mapMaybeTM f) ccase+       , cm_ecase = fmap (mapMaybeTM f) cecase, cm_tick = fmap (mapMaybeTM f) ctick }+ -------------------------- lookupCoreMap :: CoreMap a -> CoreExpr -> Maybe a lookupCoreMap cm e = lookupTM e cm@@ -409,6 +424,7 @@    alterTM  = xtA emptyCME    foldTM   = fdA    filterTM = ftA+   mapMaybeTM = mpA  instance Eq (DeBruijn CoreAlt) where   D env1 a1 == D env2 a2 = go a1 a2 where@@ -446,3 +462,9 @@ fdA k m = foldTM k (am_deflt m)         . foldTM (foldTM k) (am_data m)         . foldTM (foldTM k) (am_lit m)++mpA :: (a -> Maybe b) -> AltMap a -> AltMap b+mpA f (AM { am_deflt = adeflt, am_data = adata, am_lit = alit })+  = AM { am_deflt = mapMaybeTM f adeflt+       , am_data = fmap (mapMaybeTM f) adata+       , am_lit = fmap (mapMaybeTM f) alit }
GHC/Core/Map/Type.hs view
@@ -47,7 +47,7 @@ import GHC.Types.Name.Env import GHC.Types.Var import GHC.Types.Var.Env-import GHC.Types.Unique.DFM+import GHC.Types.Unique.FM import GHC.Utils.Outputable  import GHC.Utils.Panic@@ -96,6 +96,7 @@    alterTM k f (CoercionMap m) = CoercionMap (alterTM (deBruijnize k) f m)    foldTM k    (CoercionMap m) = foldTM k m    filterTM f  (CoercionMap m) = CoercionMap (filterTM f m)+   mapMaybeTM f (CoercionMap m) = CoercionMap (mapMaybeTM f m)  type CoercionMapG = GenMap CoercionMapX newtype CoercionMapX a = CoercionMapX (TypeMapX a)@@ -112,6 +113,7 @@   alterTM  = xtC   foldTM f (CoercionMapX core_tm) = foldTM f core_tm   filterTM f (CoercionMapX core_tm) = CoercionMapX (filterTM f core_tm)+  mapMaybeTM f (CoercionMapX core_tm) = CoercionMapX (mapMaybeTM f core_tm)  instance Eq (DeBruijn Coercion) where   D env1 co1 == D env2 co2@@ -189,6 +191,7 @@    alterTM  = xtT    foldTM   = fdT    filterTM = filterT+   mapMaybeTM = mpT  instance Eq (DeBruijn Type) where   (==) = eqDeBruijnType@@ -364,14 +367,14 @@  ------------------------ data TyLitMap a = TLM { tlm_number :: Map.Map Integer a-                      , tlm_string :: UniqDFM  FastString a+                      , tlm_string :: UniqFM  FastString a                       , tlm_char   :: Map.Map Char a                       }  -- TODO(22292): derive instance Functor TyLitMap where     fmap f TLM { tlm_number = tn, tlm_string = ts, tlm_char = tc } = TLM-      { tlm_number = Map.map f tn, tlm_string = mapUDFM f ts, tlm_char = Map.map f tc }+      { tlm_number = Map.map f tn, tlm_string = mapUFM f ts, tlm_char = Map.map f tc }  instance TrieMap TyLitMap where    type Key TyLitMap = TyLit@@ -380,33 +383,38 @@    alterTM  = xtTyLit    foldTM   = foldTyLit    filterTM = filterTyLit+   mapMaybeTM = mpTyLit  emptyTyLitMap :: TyLitMap a-emptyTyLitMap = TLM { tlm_number = Map.empty, tlm_string = emptyUDFM, tlm_char = Map.empty }+emptyTyLitMap = TLM { tlm_number = Map.empty, tlm_string = emptyUFM, tlm_char = Map.empty }  lkTyLit :: TyLit -> TyLitMap a -> Maybe a lkTyLit l =   case l of     NumTyLit n -> tlm_number >.> Map.lookup n-    StrTyLit n -> tlm_string >.> (`lookupUDFM` n)+    StrTyLit n -> tlm_string >.> (`lookupUFM` n)     CharTyLit n -> tlm_char >.> Map.lookup n  xtTyLit :: TyLit -> XT a -> TyLitMap a -> TyLitMap a xtTyLit l f m =   case l of     NumTyLit n ->  m { tlm_number = Map.alter f n (tlm_number m) }-    StrTyLit n ->  m { tlm_string = alterUDFM  f (tlm_string m) n }+    StrTyLit n ->  m { tlm_string = alterUFM  f (tlm_string m) n }     CharTyLit n -> m { tlm_char = Map.alter f n (tlm_char m) }  foldTyLit :: (a -> b -> b) -> TyLitMap a -> b -> b-foldTyLit l m = flip (foldUDFM l)  (tlm_string m)+foldTyLit l m = flip (nonDetFoldUFM l) (tlm_string m)               . flip (Map.foldr l) (tlm_number m)               . flip (Map.foldr l) (tlm_char m)  filterTyLit :: (a -> Bool) -> TyLitMap a -> TyLitMap a filterTyLit f (TLM { tlm_number = tn, tlm_string = ts, tlm_char = tc })-  = TLM { tlm_number = Map.filter f tn, tlm_string = filterUDFM f ts, tlm_char = Map.filter f tc }+  = TLM { tlm_number = Map.filter f tn, tlm_string = filterUFM f ts, tlm_char = Map.filter f tc } +mpTyLit :: (a -> Maybe b) -> TyLitMap a -> TyLitMap b+mpTyLit f (TLM { tlm_number = tn, tlm_string = ts, tlm_char = tc })+  = TLM { tlm_number = Map.mapMaybe f tn, tlm_string = mapMaybeUFM f ts, tlm_char = Map.mapMaybe f tc }+ ------------------------------------------------- -- | @TypeMap a@ is a map from 'Type' to @a@.  If you are a client, this -- is the type you want. The keys in this map may have different kinds.@@ -435,6 +443,7 @@     alterTM k f m = xtTT (deBruijnize k) f m     foldTM k (TypeMap m) = foldTM (foldTM k) m     filterTM f (TypeMap m) = TypeMap (fmap (filterTM f) m)+    mapMaybeTM f (TypeMap m) = TypeMap (fmap (mapMaybeTM f) m)  foldTypeMap :: (a -> b -> b) -> b -> TypeMap a -> b foldTypeMap k z m = foldTM k m z@@ -479,6 +488,7 @@   alterTM k f (LooseTypeMap m) = LooseTypeMap (alterTM (deBruijnize k) f m)   foldTM f (LooseTypeMap m) = foldTM f m   filterTM f (LooseTypeMap m) = LooseTypeMap (filterTM f m)+  mapMaybeTM f (LooseTypeMap m) = LooseTypeMap (mapMaybeTM f m)  {- ************************************************************************@@ -558,10 +568,13 @@    alterTM  = xtBndr emptyCME    foldTM   = fdBndrMap    filterTM = ftBndrMap+   mapMaybeTM = mpBndrMap  fdBndrMap :: (a -> b -> b) -> BndrMap a -> b -> b fdBndrMap f (BndrMap tm) = foldTM (foldTM f) tm +mpBndrMap :: (a -> Maybe b) -> BndrMap a -> BndrMap b+mpBndrMap f (BndrMap tm) = BndrMap (fmap (mapMaybeTM f) tm)  -- We need to use 'BndrMap' for 'Coercion', 'CoreExpr' AND 'Type', since all -- of these data types have binding forms.@@ -594,6 +607,7 @@    alterTM  = xtVar emptyCME    foldTM   = fdVar    filterTM = ftVar+   mapMaybeTM = mpVar  lkVar :: CmEnv -> Var -> VarMap a -> Maybe a lkVar env v@@ -619,9 +633,24 @@ ftVar f (VM { vm_bvar = bv, vm_fvar = fv })   = VM { vm_bvar = filterTM f bv, vm_fvar = filterTM f fv } +mpVar :: (a -> Maybe b) -> VarMap a -> VarMap b+mpVar f (VM { vm_bvar = bv, vm_fvar = fv })+  = VM { vm_bvar = mapMaybeTM f bv, vm_fvar = mapMaybeTM f fv }+ ------------------------------------------------- lkDNamed :: NamedThing n => n -> DNameEnv a -> Maybe a lkDNamed n env = lookupDNameEnv env (getName n)  xtDNamed :: NamedThing n => n -> XT a -> DNameEnv a -> DNameEnv a xtDNamed tc f m = alterDNameEnv f m (getName tc)++mpT :: (a -> Maybe b) -> TypeMapX a -> TypeMapX b+mpT f (TM { tm_var  = tvar, tm_app = tapp, tm_tycon = ttycon+          , tm_forall = tforall, tm_tylit = tlit+          , tm_coerce = tcoerce })+  = TM { tm_var    = mapMaybeTM f tvar+       , tm_app    = fmap (mapMaybeTM f) tapp+       , tm_tycon  = mapMaybeTM f ttycon+       , tm_forall = fmap (mapMaybeTM f) tforall+       , tm_tylit  = mapMaybeTM f tlit+       , tm_coerce = tcoerce >>= f }
GHC/Core/Opt/Arity.hs view
@@ -7,6 +7,7 @@ -}  {-# LANGUAGE CPP #-}+{-# LANGUAGE MultiWayIf #-}  -- | Arity and eta expansion module GHC.Core.Opt.Arity@@ -52,9 +53,9 @@ import GHC.Core.FVs import GHC.Core.Utils import GHC.Core.DataCon-import GHC.Core.TyCon     ( tyConArity )+import GHC.Core.TyCon     ( TyCon, tyConArity, isInjectiveTyCon ) import GHC.Core.TyCon.RecWalk     ( initRecTc, checkRecTc )-import GHC.Core.Predicate ( isDictTy, isEvVar, isCallStackPredTy, isCallStackTy )+import GHC.Core.Predicate ( isDictTy, isEvId, isCallStackPredTy, isCallStackTy ) import GHC.Core.Multiplicity  -- We have two sorts of substitution:@@ -87,6 +88,8 @@ import GHC.Utils.Panic import GHC.Utils.Misc +import Data.List.NonEmpty ( nonEmpty )+import qualified Data.List.NonEmpty as NE import Data.Maybe( isJust )  {-@@ -1533,7 +1536,7 @@         -- See Note [Eta expanding through dictionaries]         -- See Note [Eta expanding through CallStacks] -    cheap_fun e = exprIsCheapX (myIsCheapApp sigs) e+    cheap_fun e = exprIsCheapX (myIsCheapApp sigs) False e  -- | A version of 'isCheapApp' that considers results from arity analysis. -- See Note [Arity analysis] for what's in the signature environment and why@@ -1599,23 +1602,22 @@         --      f x y = case x of { (a,b) -> e }         -- The difference is observable using 'seq'         ---arityType env (Case scrut bndr _ alts)-  | exprIsDeadEnd scrut || null alts-  = botArityType    -- Do not eta expand. See (1) in Note [Dealing with bottom]--  | not (pedanticBottoms env)  -- See (2) in Note [Dealing with bottom]-  , myExprIsCheap env scrut (Just (idType bndr))-  = alts_type+arityType env (Case scrut bndr _ altList)+  | not $ exprIsDeadEnd scrut, Just alts <- nonEmpty altList+  = let env' = delInScope env bndr+        arity_type_alt (Alt _con bndrs rhs) = arityType (delInScopeList env' bndrs) rhs+        alts_type = foldr1 (andArityType env) (NE.map arity_type_alt alts)+    in if+      | not (pedanticBottoms env)  -- See (2) in Note [Dealing with bottom]+      , myExprIsCheap env scrut (Just (idType bndr))+       -> alts_type -  | exprOkForSpeculation scrut-  = alts_type+      | exprOkForSpeculation scrut+       -> alts_type -  | otherwise            -- In the remaining cases we may not push-  = addWork alts_type    -- evaluation of the scrutinee in-  where-    env' = delInScope env bndr-    arity_type_alt (Alt _con bndrs rhs) = arityType (delInScopeList env' bndrs) rhs-    alts_type = foldr1 (andArityType env) (map arity_type_alt alts)+      | otherwise            -- In the remaining cases we may not push+       -> addWork alts_type -- evaluation of the scrutinee in+  | otherwise = botArityType    -- Do not eta expand. See (1) in Note [Dealing with bottom]  arityType env (Let (NonRec b rhs) e)   = -- See Note [arityType for non-recursive let-bindings]@@ -2258,7 +2260,7 @@ -- If                    e :: ty -- then   etaInfoApp e eis :: etaInfoApp ty eis etaInfoAppTy ty (EI bs mco)-  = applyTypeToArgs (text "etaInfoAppTy") ty1 (map varToCoreExpr bs)+  = applyTypeToArgs ty1 (map varToCoreExpr bs)   where     ty1 = case mco of              MRefl  -> ty@@ -2304,7 +2306,7 @@      go _ [] subst _        ----------- Done!  No more expansion needed-       = (getSubstInScope subst, EI [] MRefl)+       = (substInScopeSet subst, EI [] MRefl)      go n oss@(one_shot:oss1) subst ty        ----------- Forall types  (forall a. ty)@@ -2351,7 +2353,7 @@                          -- but its type isn't a function, or a binder                          -- does not have a fixed runtime representation        = warnPprTrace True "mkEtaWW" ((ppr orig_oss <+> ppr orig_ty) $$ ppr_orig_expr)-         (getSubstInScope subst, EI [] MRefl)+         (substInScopeSet subst, EI [] MRefl)         -- This *can* legitimately happen:         -- e.g.  coerce Int (\x. x) Essentially the programmer is         -- playing fast and loose with types (Happy does this a lot).@@ -2789,7 +2791,7 @@          arity = idArity fun      ----------------    ok_lam v = isTyVar v || isEvVar v+    ok_lam v = isTyVar v || isEvId v     -- See Note [Eta reduction makes sense], point (2)      ---------------@@ -3020,14 +3022,14 @@     | otherwise     = Nothing -pushCoDataCon :: DataCon -> [CoreExpr] -> MCoercion+pushCoDataCon :: DataCon -> [CoreExpr] -> MCoercionR               -> Maybe (DataCon                        , [Type]      -- Universal type args                        , [CoreExpr]) -- All other args incl existentials -- Implement the KPush reduction rule as described in "Down with kinds" -- The transformation applies iff we have --      (C e1 ... en) `cast` co--- where co :: (T t1 .. tn) ~ to_ty+-- where co :: (T t1 .. tn) ~ (T s1 .. sn) -- The left-hand one must be a T, because exprIsConApp returned True -- but the right-hand one might not be.  (Though it usually will.) pushCoDataCon dc dc_args MRefl    = Just $! (push_dc_refl dc dc_args)@@ -3039,7 +3041,7 @@   where     !(univ_ty_args, rest_args) = splitAtList (dataConUnivTyVars dc) dc_args -push_dc_gen :: DataCon -> [CoreExpr] -> Coercion -> Pair Type+push_dc_gen :: DataCon -> [CoreExpr] -> CoercionR -> Pair Type             -> Maybe (DataCon, [Type], [CoreExpr]) push_dc_gen dc dc_args co (Pair from_ty to_ty)   | from_ty `eqType` to_ty  -- try cheap test first@@ -3052,44 +3054,54 @@         -- where S is a type function.  In fact, exprIsConApp         -- will probably not be called in such circumstances,         -- but there's nothing wrong with it+  = Just (push_data_con to_tc to_tc_arg_tys dc dc_args co Representational) -  = let-        tc_arity       = tyConArity to_tc-        dc_univ_tyvars = dataConUnivTyVars dc-        dc_ex_tcvars   = dataConExTyCoVars dc-        arg_tys        = dataConRepArgTys dc+  | otherwise+  = Nothing -        non_univ_args  = dropList dc_univ_tyvars dc_args-        (ex_args, val_args) = splitAtList dc_ex_tcvars non_univ_args -        -- Make the "Psi" from the paper-        omegas = decomposeCo tc_arity co (tyConRolesRepresentational to_tc)-        (psi_subst, to_ex_arg_tys)-          = liftCoSubstWithEx Representational-                              dc_univ_tyvars-                              omegas-                              dc_ex_tcvars-                              (map exprToType ex_args)+push_data_con :: TyCon -> [Type] -> DataCon -> [CoreExpr]+              -> CoercionR -> Role                  -- Coercion and its role+              -> (DataCon, [Type], [CoreExpr])+push_data_con to_tc to_tc_arg_tys dc dc_args co role+  = assertPpr (eqType from_ty dc_app_ty)     dump_doc $+    assertPpr (equalLength val_args arg_tys) dump_doc $+    assertPpr (role == coercionRole co)      dump_doc $+    assertPpr (isInjectiveTyCon to_tc role)  dump_doc $+    -- isInjectiveTyCon: see (UCM9) in Note [Unary class magic]+    --                   in GHC.Core.TyCon+    (dc, to_tc_arg_tys, to_ex_args ++ new_val_args)+  where+    Pair from_ty to_ty = coercionKind co+    tc_arity       = tyConArity to_tc+    dc_univ_tyvars = dataConUnivTyVars dc+    dc_ex_tcvars   = dataConExTyCoVars dc+    arg_tys        = dataConRepArgTys dc -          -- Cast the value arguments (which include dictionaries)-        new_val_args = zipWith cast_arg (map scaledThing arg_tys) val_args-        cast_arg arg_ty arg = mkCast arg (psi_subst arg_ty)+    dc_app_ty = mkTyConApp to_tc (map exprToType $ takeList dc_univ_tyvars dc_args) -        to_ex_args = map Type to_ex_arg_tys+    non_univ_args  = dropList dc_univ_tyvars dc_args+    (ex_args, val_args) = splitAtList dc_ex_tcvars non_univ_args -        dump_doc = vcat [ppr dc,      ppr dc_univ_tyvars, ppr dc_ex_tcvars,-                         ppr arg_tys, ppr dc_args,-                         ppr ex_args, ppr val_args, ppr co, ppr from_ty, ppr to_ty, ppr to_tc-                         , ppr $ mkTyConApp to_tc (map exprToType $ takeList dc_univ_tyvars dc_args) ]-    in-    assertPpr (eqType from_ty (mkTyConApp to_tc (map exprToType $ takeList dc_univ_tyvars dc_args))) dump_doc $-    assertPpr (equalLength val_args arg_tys) dump_doc $-    Just (dc, to_tc_arg_tys, to_ex_args ++ new_val_args)+    -- Make the "Psi" from the paper+    omegas = decomposeCo tc_arity co (tyConRolesX role to_tc)+    (psi_subst, to_ex_arg_tys)+      = liftCoSubstWithEx dc_univ_tyvars+                          omegas+                          dc_ex_tcvars+                          (map exprToType ex_args) -  | otherwise-  = Nothing+      -- Cast the value arguments (which include dictionaries)+    new_val_args = zipWith cast_arg (map scaledThing arg_tys) val_args+    cast_arg arg_ty arg = mkCast arg (psi_subst arg_ty) +    to_ex_args = map Type to_ex_arg_tys +    dump_doc = vcat [ppr dc, ppr dc_univ_tyvars, ppr dc_ex_tcvars+                    , ppr arg_tys, ppr dc_args+                    , ppr ex_args, ppr val_args, ppr co, ppr from_ty, ppr to_ty, ppr to_tc+                    , ppr $ mkTyConApp to_tc (map exprToType $ takeList dc_univ_tyvars dc_args) ]+ collectBindersPushingCo :: CoreExpr -> ([Var], CoreExpr) -- Collect lambda binders, pushing coercions inside if possible -- E.g.   (\x.e) |> g         g :: <Int> -> blah@@ -3145,15 +3157,12 @@        | otherwise = (reverse bs, mkCast (Lam b e) co) -{---Note [collectBindersPushingCo]+{- Note [collectBindersPushingCo] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ We just look for coercions of form    <type> % w -> blah (and similarly for foralls) to keep this function simple.  We could do more elaborate stuff, but it'd involve substitution etc.- -}  {- *********************************************************************@@ -3246,7 +3255,7 @@       = (subst', eta_id')       where         Scaled mult' ty' = Type.substScaledTyUnchecked subst ty-        eta_id' = uniqAway (getSubstInScope subst) $+        eta_id' = uniqAway (substInScopeSet subst) $                   mkSysLocalOrCoVar (fsLit "eta") (mkBuiltinUnique n) mult' ty'                   -- "OrCoVar" since this can be used to eta-expand                   -- coercion abstractions
GHC/Core/Opt/CSE.hs view
@@ -638,6 +638,9 @@   doing this if there are no RULES; and other things being   equal it delays optimisation to delay inlining (#17409) +* There can be a subtle order-dependency, as described in #25526;+  it may matter whether we end up with f=g or g=f.+  ---- Historical note --- 
GHC/Core/Opt/CallArity.hs view
@@ -23,6 +23,7 @@ import GHC.Utils.Misc  import Control.Arrow ( first, second )+import Data.List.NonEmpty ( NonEmpty (..) )   {-@@ -696,7 +697,7 @@  -- See Note [Trimming arity] trimArity :: Id -> Arity -> Arity-trimArity v a = minimum [a, max_arity_by_type, max_arity_by_strsig]+trimArity v a = minimum (a :| max_arity_by_type : max_arity_by_strsig : [])   where     max_arity_by_type = typeArity (idType v)     max_arity_by_strsig
GHC/Core/Opt/CallerCC/Types.hs view
@@ -19,6 +19,7 @@ import GHC.Utils.Panic import qualified GHC.Utils.Binary as B import Data.Char+import Control.DeepSeq  import Language.Haskell.Syntax.Module.Name @@ -33,6 +34,11 @@   ppr (PWildcard rest) = char '*' <> ppr rest   ppr PEnd = Outputable.empty +instance NFData NamePattern where+  rnf (PChar c n) = rnf c `seq` rnf n+  rnf (PWildcard np) = rnf np+  rnf PEnd = ()+ instance B.Binary NamePattern where   get bh = do     tag <- B.get bh@@ -75,6 +81,9 @@     = CallerCcFilter { ccfModuleName  :: Maybe ModuleName                      , ccfFuncName    :: NamePattern                      }++instance NFData CallerCcFilter where+  rnf (CallerCcFilter mn n) = rnf mn `seq` rnf n  instance Outputable CallerCcFilter where   ppr ccf =
GHC/Core/Opt/ConstantFold.hs view
@@ -20,7 +20,7 @@ {-# LANGUAGE TypeApplications #-} {-# LANGUAGE ViewPatterns #-} -{-# OPTIONS_GHC -optc-DNON_POSIX_SOURCE -Wno-incomplete-uni-patterns #-}+{-# OPTIONS_GHC -optc-DNON_POSIX_SOURCE #-}  -- | Constant Folder module GHC.Core.Opt.ConstantFold@@ -55,7 +55,7 @@ import GHC.Core.Type import GHC.Core.TyCo.Compare( eqType ) import GHC.Core.TyCon-   ( TyCon, tyConDataCons_maybe, tyConDataCons, tyConFamilySize+   ( TyCon, tyConDataCons_maybe, tyConDataCons, tyConSingleDataCon, tyConFamilySize    , isEnumerationTyCon, isValidDTT2TyCon, isNewTyCon ) import GHC.Core.Map.Expr ( eqCoreExpr ) @@ -69,7 +69,6 @@ import GHC.Cmm.Type ( Width(..) )  import GHC.Data.FastString-import GHC.Data.Maybe      ( orElse )  import GHC.Utils.Outputable import GHC.Utils.Misc@@ -1997,6 +1996,14 @@ generate calls in derived instances of Enum.  So we compromise: a rewrite rule rewrites a bad instance of tagToEnum# to an error call, and emits a warning.++We also do something similar if we can see that the argument of tagToEnum is out+of bounds, e.g. `tagToEnum# 99# :: Bool`.+Replacing this with an error expression is better for two reasons:+* It allow us to eliminate more dead code in cases like `case tagToEnum# 99# :: Bool of ...`+* Should we actually end up executing the relevant code at runtime the user will+  see a meaningful error message, instead of a segfault or incorrect result.+See #25976. -}  tagToEnumRule :: RuleM CoreExpr@@ -2008,9 +2015,13 @@     Just (tycon, tc_args) | isEnumerationTyCon tycon -> do       let tag = fromInteger i           correct_tag dc = (dataConTagZ dc) == tag-      (dc:rest) <- return $ filter correct_tag (tyConDataCons_maybe tycon `orElse` [])-      massert (null rest)-      return $ mkTyApps (Var (dataConWorkId dc)) tc_args+      Just dataCons <- pure $ tyConDataCons_maybe tycon+      case filter correct_tag dataCons of+        (dc:rest) -> do+          massert (null rest)+          pure $ mkTyApps (Var (dataConWorkId dc)) tc_args+        -- Literal is out of range, e.g. tagToEnum @Bool #4+        [] -> pure $ mkImpossibleExpr ty "tagToEnum: Argument out of range"      -- See Note [tagToEnum#]     _ -> warnPprTrace True "tagToEnum# on non-enumeration type" (ppr ty) $@@ -2059,7 +2070,7 @@        ; fn <- getFunction        ; let (_, ue) = splitForAllTyCoVars (idType fn)              tc      = tyConAppTyCon ue  -- tycon:    UnsafeEquality-             (dc:_)  = tyConDataCons tc  -- data con: UnsafeRefl+             dc      = tyConSingleDataCon tc  -- data con: UnsafeRefl              -- UnsafeRefl :: forall (r :: RuntimeRep) (a :: TYPE r).              --               UnsafeEquality r a a        ; return (mkTyApps (Var (dataConWrapId dc)) [rep, t1]) }@@ -2635,6 +2646,13 @@ -------------------------------------------------------- -- Note [Constant folding through nested expressions] -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+-- GHC has some support for constant folding through nested expressions (i.e.+-- when constants are not only arguments of the considered App node but to one+-- of its own argument (an App node too), see examples below).+--+-- For performance reason, this optimization is only enabled with -O1 and above.+-- As with all optimizations, it can also be independently enabled with its own+-- command-line flag too: -fnum-constant-folding (grep Opt_NumConstantFolding). -- -- We use rewrites rules to perform constant folding. It means that we don't -- have a global view of the expression we are trying to optimise. As a
GHC/Core/Opt/CprAnal.hs view
@@ -213,7 +213,7 @@   -> (CprType, CoreExpr) -- ^ the updated expression and its 'CprType'  cprAnal env e = -- pprTraceWith "cprAnal" (\res -> ppr (fst (res)) $$ ppr e) $-                  cprAnal' env e+                cprAnal' env e  cprAnal' _ (Lit lit)     = (topCprType, Lit lit) cprAnal' _ (Type ty)     = (topCprType, Type ty)      -- Doesn't happen, in fact@@ -289,7 +289,7 @@             -> extendSigEnvAllSame env ids sig           ForeachField field_cprs             | let sigs = zipWith (mkCprSig . idArity) ids field_cprs-            -> extendSigEnvList env (zipEqual "cprAnalAlt" ids sigs)+            -> extendSigEnvList env (zipEqual ids sigs)       | otherwise       = extendSigEnvAllSame env ids topCprSig     (rhs_ty, rhs') = cprAnal env_alt rhs@@ -304,9 +304,16 @@  -- See Note [Nested CPR] exprTerminates :: CoreExpr -> TermFlag+-- ^ A /very/ simple termination analysis. exprTerminates e-  | exprIsHNF e = Terminates -- A /very/ simple termination analysis.-  | otherwise   = MightDiverge+  | exprIsHNF e            = Terminates+  | exprOkForSpeculation e = Terminates+  | otherwise              = MightDiverge+  -- Annoyingly, we have to check both for HNF and ok-for-spec.+  --   * `I# (x# *# 2#)` is ok-for-spec, but not in HNF. Still worth CPR'ing!+  --   * `lvl` is an HNF if its unfolding is evaluated+  --     (perhaps `lvl = I# 0#` at top-level). But, tiresomely, it is never+  --     ok-for-spec due to Note [exprOkForSpeculation and evaluated variables].  cprAnalApp :: AnalEnv -> CoreExpr -> [(CprType, CoreArg)] -> (CprType, CoreExpr) -- Main function that takes care of /nested/ CPR. See Note [Nested CPR]@@ -347,7 +354,7 @@   | isLocalId id   = assertPpr (isDataStructure id) (ppr id) topCprType   -- See Note [CPR for DataCon wrappers]-  | isDataConWrapId id, let rhs = uf_tmpl (realIdUnfolding id)+  | Just rhs <- dataConWrapUnfolding_maybe id   = fst $ cprAnalApp env rhs args   -- DataCon worker   | Just con <- isDataConWorkId_maybe id@@ -369,14 +376,16 @@ -- | Get a (possibly nested) 'CprType' for an application of a 'DataCon' worker, -- given a saturated number of 'CprType's for its field expressions. -- Implements the Nested part of Note [Nested CPR].-cprTransformDataConWork :: AnalEnv -> DataCon -> [(CprType, CoreArg)] -> CprType+cprTransformDataConWork :: AnalEnv -> DataCon+                        -> [(CprType, CoreArg)]   -- Info about /value/ arguments+                        -> CprType cprTransformDataConWork env con args   | null (dataConExTyCoVars con)  -- No existentials   , wkr_arity <= mAX_CPR_SIZE -- See Note [Trimming to mAX_CPR_SIZE]   , args `lengthIs` wkr_arity   , ae_rec_dc env con /= DefinitelyRecursive -- See Note [CPR for recursive data constructors]-  -- , pprTrace "cprTransformDataConWork" (ppr con <+> ppr wkr_arity <+> ppr args) True-  = CprType 0 (ConCpr (dataConTag con) (strictZipWith extract_nested_cpr args wkr_str_marks))+  = -- pprTraceWith "cprTransformDataConWork" (\r -> ppr con <+> ppr wkr_arity <+> ppr args <+> ppr r) $+    CprType 0 (ConCpr (dataConTag con) (strictZipWith extract_nested_cpr args wkr_str_marks))   | otherwise   = topCprType   where@@ -532,7 +541,8 @@   | isDataStructure id -- Data structure => no code => no need to analyse rhs   = (id,  rhs,  env)   | otherwise-  = (id `setIdCprSig` sig',       rhs', env')+  = -- pprTrace "cprAnalBind" (ppr id <+> ppr sig <+> ppr sig')+    (id `setIdCprSig` sig',       rhs', env')   where     (rhs_ty, rhs')  = cprAnal env rhs     -- possibly trim thunk CPR info
GHC/Core/Opt/DmdAnal.hs view
@@ -23,7 +23,6 @@ import GHC.Core.Utils import GHC.Core.TyCon import GHC.Core.Type-import GHC.Core.Predicate( isEqualityClass, isCTupleClass ) import GHC.Core.FVs      ( rulesRhsFreeIds, bndrRuleAndUnfoldingIds ) import GHC.Core.Coercion ( Coercion ) import GHC.Core.TyCo.FVs     ( coVarsOfCos )@@ -555,7 +554,9 @@     WithDmdType res_ty (Case scrut' case_bndr' ty [Alt alt_con bndrs' rhs'])     where       want_precise_field_dmds (DataAlt dc)-        | Nothing <- tyConSingleAlgDataCon_maybe $ dataConTyCon dc+        | let tc = dataConTyCon dc+        , assertPpr (not (isNewTyCon tc)) (ppr dc) True  -- DataAlt is never newtype+        , Nothing <- tyConSingleDataCon_maybe $ dataConTyCon dc         = False    -- Not a product type, even though this is the                    -- only remaining possible data constructor         | DefinitelyRecursive <- ae_rec_dc env dc@@ -835,6 +836,10 @@ from 'topDiv' to 'conDiv', leading to bugs, performance regressions and complexity that didn't justify the single fixed testcase T13380c. +You might think that we should check for side-effects rather than just for+precise exceptions. Right you are! See Note [Side-effects and strictness]+for why we unfortunately do not.+ Note [Demand analysis for recursive data constructors] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ T11545 features a single-product, recursive data type@@ -1015,7 +1020,7 @@   = -- pprTraceWith "dmdTransform:DataCon" (\ty -> ppr con $$ ppr sd $$ ppr ty) $     dmdTransformDataConSig (dataConRepStrictness con) sd   -- See Note [DmdAnal for DataCon wrappers]-  | isDataConWrapId var, let rhs = uf_tmpl (realIdUnfolding var)+  | Just rhs <- dataConWrapUnfolding_maybe var   , WithDmdType dmd_ty _rhs' <- dmdAnal env sd rhs   = dmd_ty   -- Dictionary component selectors@@ -1162,8 +1167,8 @@     go depth ty sd       | depth <= max_depth       , Just (tc, tc_args, _co) <- normSplitTyConApp_maybe (ae_fam_envs env) ty-      , Just dc <- tyConSingleAlgDataCon_maybe tc-      , null (dataConExTyCoVars dc) -- Can't unbox results with existentials+      , Just [dc] <- canUnboxTyCon tc   -- tc is not a newtype+      , null (dataConExTyCoVars dc)     -- Can't unbox results with existentials       , dataConRepArity dc <= dmd_unbox_width (ae_opts env)       , Just (_, ds) <- viewProd (dataConRepArity dc) sd       , arg_tys <- map scaledThing $ dataConInstArgTys dc tc_args@@ -2026,7 +2031,7 @@   -- The normal case   | otherwise   = -- pprTrace "finaliseArgBoxities" (-    --   vcat [text "function:" <+> ppr fn+    -- vcat [text "function:" <+> ppr fn     --        , text "max" <+> ppr max_wkr_args     --        , text "dmds before:" <+> ppr (map idDemandInfo (filter isId bndrs))     --        , text "dmds after: " <+>  ppr arg_dmds' ]) $@@ -2167,12 +2172,6 @@          -- isMarkedStrict: see Note [Unboxing evaluated arguments] in DmdAnal        -> DontUnbox -       | doNotUnbox ty-       -> DontUnbox  -- See Note [Do not unbox class dictionaries]-                     -- NB: 'ty' has not been normalised, so this will (rightly)-                     --     catch newtype dictionaries too.-                     -- NB: even for bottoming functions, don't unbox dictionaries-        | DefinitelyRecursive <- ae_rec_dc env dc          -- See Note [Which types are unboxed?]          -- and Note [Demand analysis for recursive data constructors]@@ -2182,76 +2181,6 @@        -> DoUnbox (zip3 (dubiousDataConInstArgTys dc tc_args)                         (dataConRepStrictness dc)                         dmds)---doNotUnbox :: Type -> Bool--- Do not unbox class dictionaries, except equality classes and tuples--- Note [Do not unbox class dictionaries]-doNotUnbox arg_ty-  = case tyConAppTyCon_maybe arg_ty of-      Just tc | Just cls <- tyConClass_maybe tc-              -> not (isEqualityClass cls || isCTupleClass cls)-       -- See (DNB2) and (DNB1) in Note [Do not unbox class dictionaries]--      _ -> False--{- Note [Do not unbox class dictionaries]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-We never unbox class dictionaries in worker/wrapper.--1. INLINABLE functions-   If we have-      f :: Ord a => [a] -> Int -> a-      {-# INLINABLE f #-}-   and we worker/wrapper f, we'll get a worker with an INLINABLE pragma-   (see Note [Worker/wrapper for INLINABLE functions] in GHC.Core.Opt.WorkWrap),-   which can still be specialised by the type-class specialiser, something like-      fw :: Ord a => [a] -> Int# -> a--   BUT if f is strict in the Ord dictionary, we might unpack it, to get-      fw :: (a->a->Bool) -> [a] -> Int# -> a-   and the type-class specialiser can't specialise that. An example is #6056.--   Historical note: #14955 describes how I got this fix wrong the first time.-   I got aware of the issue in T5075 by the change in boxity of loop between-   demand analysis runs.--2. -fspecialise-aggressively.  As #21286 shows, the same phenomenon can occur-   occur without INLINABLE, when we use -fexpose-all-unfoldings and-   -fspecialise-aggressively to do vigorous cross-module specialisation.--3. #18421 found that unboxing a dictionary can also make the worker less likely-   to inline; the inlining heuristics seem to prefer to inline a function-   applied to a dictionary over a function applied to a bunch of functions.--TL;DR we /never/ unbox class dictionaries. Unboxing the dictionary, and passing-a raft of higher-order functions isn't a huge win anyway -- you really want to-specialise the function.--Wrinkle (DNB1): we /do/ want to unbox tuple dictionaries (#23398)-     f :: (% Eq a, Show a %) => blah-  with -fdicts-strict it is great to unbox to-     $wf :: Eq a => Show a => blah-  (where I have written out the currying explicitly).  Now we can specialise-  $wf on the Eq or Show dictionary.  Nothing is lost.--  And something is gained.  It is possible that `f` will look like this:-     f = /\a. \d:(% Eq a, Show a %). ... f @a (% sel1 d, sel2 d %)...-  where there is a recurive call to `f`, or to another function that takes the-  same tuple dictionary, but where the tuple is built from the components of-  `d`.  The Simplier does not fix this.  But if we unpacked the dictionary-  we'd get-     $wf = /\a. \(d1:Eq a) (d2:Show a). let d = (% d1, d2 %)-             in ...f @a (% sel1 d, sel2 d %)-  and all the tuple building and taking apart will disappear.--Wrinkle (DNB2): we /do/ want to unbox equality dictionaries,-  for (~), (~~), and Coercible (#23398).  Their payload is a single unboxed-  coercion.  We never want to specialise on `(t1 ~ t2)`.  All that would do is-  to make a copy of the function's RHS with a particular coercion.  Unlike-  normal class methods, that does not unlock any new optimisation-  opportunities in the specialised RHS.--}  {- ********************************************************************* *                                                                      *
GHC/Core/Opt/FloatIn.hs view
@@ -173,7 +173,7 @@   = wrapFloats drop_here $     mkTicks ticks $     mkApps (fiExpr platform fun_drop ann_fun)-           (zipWithEqual "fiExpr" (fiExpr platform) arg_drops ann_args)+           (zipWithEqual (fiExpr platform) arg_drops ann_args)            -- use zipWithEqual, we should have            -- length ann_args = length arg_fvs = length arg_drops   where@@ -543,7 +543,7 @@   = wrapFloats drop_here1 $     wrapFloats drop_here2 $     Case (fiExpr platform scrut_drops scrut) case_bndr ty-         (zipWithEqual "fiExpr" fi_alt alts_drops_s alts)+         (zipWithEqual fi_alt alts_drops_s alts)          -- use zipWithEqual, we should have length alts_drops_s = length alts   where         -- Float into the scrut and alts-considered-together just like App@@ -640,7 +640,7 @@      fi_bind to_drops pairs       = [ (binder, fiRhs platform to_drop binder rhs)-        | ((binder, rhs), to_drop) <- zipEqual "fi_bind" pairs to_drops ]+        | ((binder, rhs), to_drop) <- zipEqual pairs to_drops ]  ------------------ fiRhs :: Platform -> RevFloatInBinds -> CoreBndr -> CoreExprWithFVs -> CoreExpr@@ -821,7 +821,7 @@             | otherwise = floatIsCase bind || n_used_alts > 1                              -- floatIsCase: see Note [Floating primops] -          new_fork_boxes = zipWithEqual "FloatIn.sepBinds" insert_maybe+          new_fork_boxes = zipWithEqual insert_maybe                                         fork_boxes used_in_flags            insert :: DropBox -> DropBox
GHC/Core/Opt/OccurAnal.hs view
@@ -9,9 +9,7 @@ -- many /other/ arguments the function has.  Inconsistent unboxing is very -- bad for performance, so I increased the limit to allow it to unbox -- consistently.--- AK: Seems we no longer unbox OccEnv now anyway so it might be redundant. - {- (c) The GRASP/AQUA Project, Glasgow University, 1992-1998 @@ -39,7 +37,6 @@                           mkCastMCo, mkTicks ) import GHC.Core.Opt.Arity   ( joinRhsArity, isOneShotBndr ) import GHC.Core.Coercion-import GHC.Core.Predicate   ( isDictId ) import GHC.Core.Type import GHC.Core.TyCo.FVs    ( tyCoVarsOfMCo ) @@ -67,6 +64,7 @@ import GHC.Unit.Module( Module )  import Data.List (mapAccumL)+import Data.List.NonEmpty (NonEmpty (..))  {- ************************************************************************@@ -969,12 +967,6 @@   -> ([CoreBind] -> r -> r)          -- How to combine the scope with new binds   -> WithUsageDetails r              -- Of the whole let(rec) --- AK: While not allocating any less inlining occAnalBind turns calls to the--- passed functions into known calls with all the benefits that brings.--- On a version of T26425 with 6k alternatives this improved compile--- by 10-20% with -O.-{-# INLINE occAnalBind #-}- occAnalBind env lvl ire (Rec pairs) thing_inside combine   = addInScopeList env (map fst pairs) $ \env ->     let WUD body_uds body'  = thing_inside env@@ -992,7 +984,7 @@   = -- Analyse the RHS and /then/ the body     let -- Analyse the rhs first, generating rhs_uds         !(rhs_uds_s, bndr', rhs') = occAnalNonRecRhs env lvl ire mb_join bndr rhs-        rhs_uds = foldl1' orUDs rhs_uds_s   -- NB: orUDs.  See (W4) of+        rhs_uds = foldr1 orUDs rhs_uds_s   -- NB: orUDs.  See (W4) of                                            -- Note [Occurrence analysis for join points]          -- Now analyse the body, adding the join point@@ -1034,14 +1026,14 @@ ----------------- occAnalNonRecRhs :: OccEnv -> TopLevelFlag -> ImpRuleEdges                 -> JoinPointHood -> Id -> CoreExpr-                 -> ([UsageDetails], Id, CoreExpr)+                 -> (NonEmpty UsageDetails, Id, CoreExpr) occAnalNonRecRhs !env lvl imp_rule_edges mb_join bndr rhs   | null rules, null imp_rule_infos   =  -- Fast path for common case of no rules. This is only worth      -- 0.1% perf on average, but it's also only a line or two of code-    ( [adj_rhs_uds, adj_unf_uds],              final_bndr_no_rules,   final_rhs )+    ( adj_rhs_uds :| adj_unf_uds : [], final_bndr_no_rules, final_rhs )   | otherwise-  = (adj_rhs_uds : adj_unf_uds : adj_rule_uds, final_bndr_with_rules, final_rhs )+  = ( adj_rhs_uds :| adj_unf_uds : adj_rule_uds, final_bndr_with_rules, final_rhs )   where     --------- Right hand side ---------     -- For join points, set occ_encl to OccVanilla, via setTailCtxt.  If we have@@ -1057,7 +1049,6 @@     -- Match join arity O from mb_join_arity with manifest join arity M as     -- returned by of occAnalLamTail. It's totally OK for them to mismatch;     -- hence adjust the UDs from the RHS-     WUD adj_rhs_uds final_rhs = adjustNonRecRhs mb_join $                                 occAnalLamTail rhs_env rhs     final_bndr_with_rules@@ -1813,7 +1804,7 @@ --   d) adjust each RHS's usage details according to --      the binder's (new) shotness and join-point-hood mkLoopBreakerNodes !env lvl body_uds details_s-  = WUD final_uds (zipWithEqual "mkLoopBreakerNodes" mk_lb_node details_s bndrs')+  = WUD final_uds (zipWithEqual mk_lb_node details_s bndrs')   where     WUD final_uds bndrs' = tagRecBinders lvl body_uds details_s @@ -2063,18 +2054,6 @@    was a loop breaker last time round  Hence the is_lb field of NodeScore--Note [Strictness in the occurrence analyser]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-By carefully making the occurrence analyser strict in some places, we can-dramatically reduce its memory residency. Among other things we:-* Evaluate the result of `tagLamBinder` and friends, so that the binder (or its-  OccInfo) does not retain the entire `UsageDetails`.  Also use `strictMap` in `tagLamBinders`.-* In `combineUsageDetailsWith`, the fields of the data constructor are strict, and we use-  `strictPlusVarEnv` on the maps that are bound to be needed later on to avoid thunks being-  stored in the values.--These measures reduced residency for test T26425 by a factor of at least 5x. -}  {- *********************************************************************@@ -2209,9 +2188,7 @@     go env rev_bndrs body       = addInScope env rev_bndrs $ \env ->         let !(WUD usage body') = occ_anal_lam_tail env body-            -- See Note [Strictness in the occurrence analyser]-            wrap_lam !body !bndr = let !bndr' = tagLamBinder usage bndr-                                   in Lam bndr' body+            wrap_lam body bndr = Lam (tagLamBinder usage bndr) body         in WUD (usage `addLamCoVarOccs` rev_bndrs)                (foldl' wrap_lam body' rev_bndrs) @@ -2523,7 +2500,7 @@       -- For a non-soft tick scope, we can inline lambdas only, so we       -- abandon tail calls, and do markAllInsideLam too: usage_lam -      |  Breakpoint _ _ ids _ <- tickish+      | Breakpoint _ _ ids <- tickish       = -- Never substitute for any of the Ids in a Breakpoint         addManyOccs usage_lam (mkVarSet ids) @@ -2564,8 +2541,7 @@            let alt_env = addBndrSwap scrut' bndr $                          setTailCtxt env  -- Kill off OccRhs                WUD alts_usage alts' = do_alts alt_env alts-               !tagged_bndr = tagLamBinder alts_usage bndr-               -- See Note [Strictness in the occurrence analyser]+               tagged_bndr = tagLamBinder alts_usage bndr            in WUD alts_usage (tagged_bndr, alts')        total_usage = markAllNonTail scrut_usage `andUDs` alts_usage@@ -2583,13 +2559,11 @@     do_alt !env (Alt con bndrs rhs)       = addInScopeList env bndrs $ \ env ->         let WUD rhs_usage rhs' = occAnal env rhs-            !tagged_bndrs = tagLamBinders rhs_usage bndrs-                           -- See Note [Strictness in the occurrence analyser]+            tagged_bndrs = tagLamBinders rhs_usage bndrs         in                 -- See Note [Binders in case alternatives]         WUD rhs_usage (Alt con tagged_bndrs rhs')  occAnal env (Let bind body)-  -- TODO: Would be nice to use a strict version of mkLets here   = occAnalBind env NotTopLevel noImpRuleEdges bind                 (\env -> occAnal env body) mkLets @@ -2670,12 +2644,10 @@   | fun `hasKey` runRWKey   , [t1, t2, arg]  <- args   , WUD usage arg' <- adjustNonRecRhs (JoinPoint 1) $ occAnalLamTail env arg-  = let app_out = mkTicks ticks $ mkApps (Var fun) [t1, t2, arg']-    in WUD usage app_out+  = WUD usage (mkTicks ticks $ mkApps (Var fun) [t1, t2, arg'])  occAnalApp env (Var fun_id, args, ticks)-  = let app_out = mkTicks ticks app'-    in WUD all_uds app_out+  = WUD all_uds (mkTicks ticks app')   where     -- Lots of banged bindings: this is a very heavily bit of code,     -- so it pays not to make lots of thunks here, all of which@@ -2720,9 +2692,8 @@         -- See Note [Sources of one-shot information], bullet point A']  occAnalApp env (fun, args, ticks)-  = let app_out = mkTicks ticks app'-    in WUD (markAllNonTail (fun_uds `andUDs` args_uds)) app_out-+  = WUD (markAllNonTail (fun_uds `andUDs` args_uds))+                     (mkTicks ticks app')   where     !(WUD args_uds app') = occAnalArgs env fun' args []     !(WUD fun_uds fun')  = occAnal (addAppCtxt env args) fun@@ -3356,8 +3327,8 @@ (BS5) We have to apply the occ_bs_env substitution uniformly,       including to (local) rules and unfoldings. -(BS6) We must be very careful with dictionaries.-      See Note [Care with binder-swap on dictionaries]+(BS6) For interest (only),+      see Historical Note [Care with binder-swap on dictionaries]  Note [Case of cast] ~~~~~~~~~~~~~~~~~~~@@ -3367,9 +3338,13 @@ equation (2) in Note [Binder swap].  When we get to the inner case, we inline x, cancel the casts, and away we go. -Note [Care with binder-swap on dictionaries]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-This Note explains why we need isDictId in scrutOkForBinderSwap.+Historical Note [Care with binder-swap on dictionaries]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+This Note is now out-dated; it has been rendered irrelevant by+Note [Unary class magic] in GHC.Core.TyCon.  I'm leaving it here in+case we are every tempted to return to newtype classes.++This (historical) Note explains why we need isDictId in scrutOkForBinderSwap. Consider this tricky example (#21229, #21470):    class Sing (b :: Bool) where sing :: Bool@@ -3415,6 +3390,16 @@  Hence the subtle isDictId in scrutOkForBinderSwap. +Why this Note is now outdated.  Using Note [Unary class magic] in GHC.Core.TyCon+the program above becomes+  h = \ @(a :: Bool) ($dSing :: Sing a)+      case sing @a $dSing of (wild::Bool)+        True  -> f @'True $dSing+        False -> f @a     $dSing+so the issue of binder-swapping doesn't arise.++End of Historical Note.+ Note [Zap case binders in proxy bindings] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ From the original@@ -3458,21 +3443,17 @@ -- If (scrutOkForBinderSwap e = DoBinderSwap v mco, then --    v = e |> mco -- See Note [Case of cast]--- See Note [Care with binder-swap on dictionaries]+-- See Historical Note [Care with binder-swap on dictionaries] -- -- We use this same function in SpecConstr, and Simplify.Iteration, -- when something binder-swap-like is happening-scrutOkForBinderSwap (Var v)    = DoBinderSwap v MRefl-scrutOkForBinderSwap (Cast (Var v) co)-  | not (isDictId v)             = DoBinderSwap v (MCo (mkSymCo co))-        -- Cast: see Note [Case of cast]-        -- isDictId: see Note [Care with binder-swap on dictionaries]-        -- The isDictId rejects a Constraint/Constraint binder-swap, perhaps-        -- over-conservatively. But I have never seen one, so I'm leaving-        -- the code as simple as possible. Losing the binder-swap in a-        -- rare case probably has very low impact.-scrutOkForBinderSwap (Tick _ e) = scrutOkForBinderSwap e  -- Drop ticks-scrutOkForBinderSwap _          = NoBinderSwap+scrutOkForBinderSwap e+  = case e of+      Tick _ e        -> scrutOkForBinderSwap e  -- Drop ticks+      Var v           -> DoBinderSwap v MRefl+      Cast (Var v) co -> DoBinderSwap v (MCo (mkSymCo co))+                         -- Cast: see Note [Case of cast]+      _               -> NoBinderSwap  lookupBndrSwap :: OccEnv -> Id -> (CoreExpr, Id) -- See Note [The binder-swap substitution]@@ -3669,8 +3650,8 @@ ------------------- -- UsageDetails API -andUDs:: UsageDetails -> UsageDetails -> UsageDetails-orUDs :: UsageDetails -> UsageDetails -> UsageDetails+andUDs, orUDs+        :: UsageDetails -> UsageDetails -> UsageDetails andUDs = combineUsageDetailsWith andLocalOcc orUDs  = combineUsageDetailsWith orLocalOcc @@ -3785,13 +3766,10 @@   | isEmptyVarEnv env1 = uds2   | isEmptyVarEnv env2 = uds1   | otherwise-  -- See Note [Strictness in the occurrence analyser]-  -- Using strictPlusVarEnv here speeds up the test T26425 by about 10% by avoiding-  -- intermediate thunks.-  = UD { ud_env       = strictPlusVarEnv_C plus_occ_info env1 env2-       , ud_z_many    = strictPlusVarEnv z_many1   z_many2+  = UD { ud_env       = plusVarEnv_C plus_occ_info env1 env2+       , ud_z_many    = plusVarEnv z_many1   z_many2        , ud_z_in_lam  = plusVarEnv z_in_lam1 z_in_lam2-       , ud_z_tail    = strictPlusVarEnv z_tail1   z_tail2 }+       , ud_z_tail    = plusVarEnv z_tail1   z_tail2 }  lookupLetOccInfo :: UsageDetails -> Id -> OccInfo -- Don't use locally-generated occ_info for exported (visible-elsewhere)@@ -3869,8 +3847,7 @@               -> [Id]                -- Binders               -> [IdWithOccInfo]     -- Tagged binders tagLamBinders usage binders-  -- See Note [Strictness in the occurrence analyser]-  = strictMap (tagLamBinder usage) binders+  = map (tagLamBinder usage) binders  tagLamBinder :: UsageDetails       -- Of scope              -> Id                 -- Binder@@ -3879,7 +3856,6 @@ -- No-op on TyVars -- A lambda binder never has an unfolding, so no need to look for that tagLamBinder usage bndr-  -- See Note [Strictness in the occurrence analyser]   = setBinderOcc (markNonTail occ) bndr       -- markNonTail: don't try to make an argument into a join point   where
GHC/Core/Opt/Pipeline.hs view
@@ -22,7 +22,7 @@  import GHC.Core import GHC.Core.Opt.CSE  ( cseProgram )-import GHC.Core.Rules   ( RuleBase, mkRuleBase, ruleCheckProgram, getRules )+import GHC.Core.Rules   ( RuleBase, ruleCheckProgram, getRules ) import GHC.Core.Ppr     ( pprCoreBindings ) import GHC.Core.Utils   ( dumpIdInfoOfProgram ) import GHC.Core.Lint    ( lintAnnots )@@ -76,7 +76,8 @@ core2core hsc_env guts@(ModGuts { mg_module  = mod                                 , mg_loc     = loc                                 , mg_rdr_env = rdr_env })-  = do { let builtin_passes = getCoreToDo dflags hpt_rule_base extra_vars+  = do { hpt_rule_base <- home_pkg_rules+       ; let builtin_passes = getCoreToDo dflags hpt_rule_base extra_vars              uniq_tag = 's'         ; (guts2, stats) <- runCoreM hsc_env hpt_rule_base uniq_tag mod@@ -96,11 +97,11 @@   where     dflags         = hsc_dflags hsc_env     logger         = hsc_logger hsc_env+    unit_env       = hsc_unit_env hsc_env     extra_vars     = interactiveInScope (hsc_IC hsc_env)-    home_pkg_rules = hptRules hsc_env (moduleUnitId mod) (GWIB { gwib_mod = moduleName mod-                                                               , gwib_isBoot = NotBoot })-    hpt_rule_base  = mkRuleBase home_pkg_rules-    name_ppr_ctx   = mkNamePprCtx ptc (hsc_unit_env hsc_env) rdr_env+    home_pkg_rules = hugRulesBelow hsc_env (moduleUnitId mod)+                      (GWIB { gwib_mod = moduleName mod, gwib_isBoot = NotBoot })+    name_ppr_ctx   = mkNamePprCtx ptc unit_env rdr_env     ptc            = initPromotionTickContext dflags     -- mod: get the module out of the current HscEnv so we can retrieve it from the monad.     -- This is very convienent for the users of the monad (e.g. plugins do not have to
GHC/Core/Opt/SetLevels.hs view
@@ -91,7 +91,6 @@ import GHC.Core.Opt.Arity   ( exprBotStrictness_maybe, isOneShotBndr ) import GHC.Core.FVs     -- all of it import GHC.Core.Subst-import GHC.Core.TyCo.Subst( lookupTyVar ) import GHC.Core.Make    ( sortQuantVars ) import GHC.Core.Type    ( Type, tyCoVarsOfType                         , mightBeUnliftedType, closeOverKindsDSet@@ -467,8 +466,8 @@     ty' = substTyUnchecked (le_subst env) ty      incd_lvl = incMinorLvl (le_ctxt_lvl env)-    dest_lvl = maxFvLevel includeTyVars env scrut_fvs-            -- Don't abstract over type variables, hence includeTyVars+    dest_lvl = maxFvLevel (const True) env scrut_fvs+            -- Don't abstract over type variables, hence const True      lvl_alt alts_env (AnnAlt con bs rhs)       = do { rhs' <- lvlMFE new_env True rhs@@ -615,7 +614,8 @@   = lvlExpr env e     -- See Note [Case MFEs]  lvlMFE env strict_ctxt ann_expr-  | not float_me+  |  notWorthFloating expr abs_vars+  || not float_me   || floatTopLvlOnly env && not (isTopLvl dest_lvl)          -- Only floating to the top level is allowed.   || hasFreeJoin env fvs   -- If there is a free join, don't float@@ -624,9 +624,6 @@          -- We can't let-bind an expression if we don't know          -- how it will be represented at runtime.          -- See Note [Representation polymorphism invariants] in GHC.Core-  || notWorthFloating expr abs_vars-         -- Test notWorhtFloating last;-         -- See Note [Large free-variable sets]   = -- Don't float it out     lvlExpr env ann_expr @@ -699,11 +696,14 @@          -- A decision to float entails let-binding this thing, and we only do         -- that if we'll escape a value lambda, or will go to the top level.+        -- Never float trivial expressions;+        --   notably, save_work might be true of a lone evaluated variable.     float_me = saves_work || saves_alloc || is_mk_static      -- See Note [Saving work]+    is_hnf = exprIsHNF expr     saves_work = escapes_value_lam        -- (a)-                 && not (exprIsHNF expr)  -- (b)+                 && not is_hnf            -- (b)                  && not float_is_new_lam  -- (c)     escapes_value_lam = dest_lvl `ltMajLvl` (le_ctxt_lvl env) @@ -711,7 +711,7 @@     saves_alloc =  isTopLvl dest_lvl                 && floatConsts env                 && (   not strict_ctxt                     -- (a)-                    || exprIsHNF expr                      -- (b)+                    || is_hnf                              -- (b)                     || (is_bot_lam && escapes_value_lam))  -- (c)  hasFreeJoin :: LevelEnv -> DVarSet -> Bool@@ -719,11 +719,8 @@ -- (In the latter case it won't be a join point any more.) -- Not treating top-level ones specially had a massive effect -- on nofib/minimax/Prog.prog-hasFreeJoin env fvs = anyDVarSet bad_join fvs-  where-    bad_join v = isJoinId v &&-                 maxIn True env v tOP_LEVEL /= tOP_LEVEL-+hasFreeJoin env fvs+  = not (maxFvLevel isJoinId env fvs == tOP_LEVEL)  {- Note [Saving work] ~~~~~~~~~~~~~~~~~~~~~@@ -811,7 +808,7 @@ * We don't pay an allocation cost for the floated expression; it   just becomes static data. -* Floating string literal is valuable -- no point in duplicating the+* Floating string literals is valuable -- no point in duplicating the   at each call site!  * Floating bottoming expressions is valuable: they are always cold@@ -872,28 +869,6 @@ important in some nofib programs (gcd is an example).  [SPJ note: I think this is obsolete; the flag seems always on.] -Note [Large free-variable sets]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-In #24471 we had something like-     x1 = I# 1-     ...-     x1000 = I# 1000-     foo = f x1 (f x2 (f x3 ....))-So every sub-expression in `foo` has lots and lots of free variables.  But-none of these sub-expressions float anywhere; the entire float-out pass is a-no-op.--In lvlMFE, we want to find out quickly if the MFE is not-floatable; that is-the common case.  In #24471 it turned out that we were testing `abs_vars` (a-relatively complicated calculation that takes at least O(n-free-vars) time to-compute) for every sub-expression.--Better instead to test `float_me` early. That still involves looking at-dest_lvl, which means looking at every free variable, but the constant factor-is a lot better.--ToDo: find a way to fix the bad asymptotic complexity.- Note [Floating join point bindings] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Mostly we don't float join points at all -- we want them to /stay/ join points.@@ -1139,7 +1114,6 @@ either, so fusion will happen.  It can be a big effect, esp in some artificial benchmarks (e.g. integer, queens), but there is no perfect answer.- -}  annotateBotStr :: Id -> Arity -> Maybe (Arity, DmdSig, CprSig) -> Id@@ -1156,69 +1130,133 @@   = id  notWorthFloating :: CoreExpr -> [Var] -> Bool--- Returns True if the expression would be replaced by--- something bigger than it is now.  For example:---   abs_vars = tvars only:  return True if e is trivial,---                           but False for anything bigger---   abs_vars = [x] (an Id): return True for trivial, or an application (f x)---                           but False for (f x x)------ One big goal is that floating should be idempotent.  Eg if--- we replace e with (lvl79 x y) and then run FloatOut again, don't want--- to replace (lvl79 x y) with (lvl83 x y)!-+--  See Note [notWorthFloating] notWorthFloating e abs_vars-  = go e (count isId abs_vars)+  = go e 0   where-    go (Var {}) n               = n >= 0-    go (Lit lit) n              = assert (n==0) $-                                  litIsTrivial lit   -- Note [Floating literals]-    go (Type {}) _              = True-    go (Coercion {}) _          = True+    n_abs_vars = count isId abs_vars  -- See (NWF5)++    go :: CoreExpr -> Int -> Bool+    -- (go e n) return True if (e x1 .. xn) is not worth floating+    -- where `e` has n trivial value arguments x1..xn+    -- See (NWF4)+    go (Lit lit) n         = (n==0)                 -- See (NWF1b)+                              && litIsTrivial lit   -- See (NWF1a)+    go (Type {}) _         = True+    go (Tick t e) n        = not (tickishIsCode t) && go e n+    go (Cast e _) n        = n==0 || go e n     -- See (NWF3)+    go (Coercion {}) _     = True     go (App e arg) n-       -- See Note [Floating applications to coercions]-       | not (isRuntimeArg arg) = go e n-       | n==0                   = False-       | exprIsTrivial arg      = go e (n-1) -- NB: exprIsTrivial arg = go arg 0-       | otherwise              = False-    go (Tick t e) n             = not (tickishIsCode t) && go e n-    go (Cast e _)  n            = go e n-    go (Case e b _ as) n+       | Type {} <- arg    = go e n    -- Just types, not coercions (NWF2)+       | exprIsTrivial arg = go e (n+1)+       | otherwise         = n==0 && exprIsUnaryClassFun e+                             -- (f non-triv) is worth floating,+                             -- unless if is a unary class fun+    go (Case e b _ as) _+      -- Do not float the `case` part of trivial cases (NWF3)+      -- We'll have a look at the RHS when we get there       | null as-      = go e n     -- See Note [Empty case is trivial]-      | Just rhs <- isUnsafeEqualityCase e b as-      = go rhs n   -- See (U2) of Note [Implementing unsafeCoerce] in base:Unsafe.Coerce-    go _ _                      = False+      = True   -- See Note [Empty case is trivial]+      | Just {} <- isUnsafeEqualityCase e b as+      = True   -- See (U2) of Note [Implementing unsafeCoerce] in base:Unsafe.Coerce+      | otherwise+      = False -{--Note [Floating literals]-~~~~~~~~~~~~~~~~~~~~~~~~-It's important to float Integer literals, so that they get shared,-rather than being allocated every time round the loop.-Hence the litIsTrivial.+    go (Var v) n+      | isUnaryClassId v = n==1   -- (op x) is not worth floating, but (op x y) is!!+                                  --    See (NWF3)+      | n==0             = True   -- Naked variable+      | n <= n_abs_vars  = True   -- (f a b c) is not worth floating if+      | otherwise        = False  -- a,b,c are all abstracted; see (NWF5) -Ditto literal strings (LitString), which we'd like to float to top-level, which is now possible.+    go _ _ = False  -- Let etc is worth floating -Note [Floating applications to coercions]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-We don’t float out variables applied only to type arguments, since the-extra binding would be pointless: type arguments are completely erased.-But *coercion* arguments aren’t (see Note [Coercion tokens] in-"GHC.CoreToStg" and Note [Count coercion arguments in boring contexts] in-"GHC.Core.Unfold"), so we still want to float out variables applied only to-coercion arguments.+{- Note [notWorthFloating]+~~~~~~~~~~~~~~~~~~~~~~~~~~+`notWorthFloating` returns True if the expression would be replaced by something+bigger than it is now.  One big goal is that floating should be idempotent.  Eg+if we replace e with (lvl79 x y) and then run FloatOut again, don't want to+replace (lvl79 x y) with (lvl83 x y)! +For example:+  abs_vars = tvars only:  return True if e is trivial,+                          but False for anything bigger+  abs_vars = [x] (an Id): return True for trivial, or an application (f x)+                          but False for (f x x) -************************************************************************-*                                                                      *-\subsection{Bindings}-*                                                                      *-************************************************************************+(NWF1a) It's important to float Integer literals, so that they get shared, rather+  than being allocated every time round the loop.  Hence the litIsTrivial. -The binding stuff works for top level too.+  Ditto literal strings (LitString), which we'd like to float to top+  level, which is now possible.++(NWF1b) You might think that a literal should never be applied to a value+  (hence n=0) but actually we can get (see test T23024):+      RUBBISH @(a->b) (x::a)+  See Note [Rubbish literals] in GHC.Types.Literal.  (Mind you, we should be+  in dead code at this point!)++(NWF2) We don’t float out variables applied only to type arguments, since the+  extra binding would be pointless: type arguments are completely erased.+  But *coercion* arguments aren’t (see Note [Coercion tokens] in+  "GHC.CoreToStg" and Note [inlineBoringOk] in"GHC.Core.Unfold"),+  so we still want to float out variables applied only to+  coercion arguments.++(NWF3) Some expressions have trivial wrappers:+     - Casts (e |> co)+     - Unary-class applications:+          - Dictionary applications (MkC meth)+          - Class-op applictions    (op dict)+     - Case of empty alts+     - Unsafe-equality case+  In all these cases we say "not worth floating", and we do so /regardless/+  of the wrapped expression.  The SetLevels stuff may subsequently float the+  components of the expression.++  Example:  is it worth floating (f x |> co)?  No!  If we did we'd get+     lvl = f x |> co+     ...lvl....+  Then we'd do cast worker/wrapper and end up with.+     lvl' = f x+     ...(lvl' |> co)...+  Silly!  Better not to float it in the first place.  If we say "no" here,+  we'll subsequently say "yes" for (f x) and get+     lvl = f x+     ....(lvl |> co)...+  which is what we want.  In short: don't float trivial wrappers.++(NWF4) The only non-trivial expression that we say "not worth floating" for+  is an application+             f x y z+  where the number of value arguments is <= the number of abstracted Ids.+  This is what makes floating idempotent.  Hence counting the number of+  value arguments in `go`++(NWF5) In #24471 we had something like+     x1 = I# 1+     ...+     x1000 = I# 1000+     foo = f x1 (f x2 (f x3 ....))+  So every sub-expression in `foo` has lots and lots of free variables.  But+  none of these sub-expressions float anywhere; the entire float-out pass is a+  no-op.++  So `notWorthFloating` tries to avoid evaluating `n_abs_vars`, in cases where+  it obviously /is/ worth floating.  (In #24471 it turned out that we were+  testing `abs_vars` (a relatively complicated calculation that takes at least+  O(n-free-vars) time to compute) for every sub-expression.)++  Hence testing `n_abs_vars only` at the very end. -} +{- *********************************************************************+*                                                                      *+                       Bindings+        This binding stuff works for top level too.+*                                                                      *+********************************************************************* -}+ lvlBind :: LevelEnv         -> CoreBindWithFVs         -> LvlM (LevelledBind, LevelEnv)@@ -1569,10 +1607,10 @@    | otherwise = max_fv_id_level   where-    max_fv_id_level = maxFvLevel idsOnly env fvs -- Max over Ids only; the-                                                 -- tyvars will be abstracted+    max_fv_id_level = maxFvLevel isId env fvs -- Max over Ids only; the+                                              -- tyvars will be abstracted -    as_far_as_poss = maxFvLevel' idsOnly env fvs_ty+    as_far_as_poss = maxFvLevel' isId env fvs_ty                      -- See Note [Floating and kind casts]  {- Note [Floating and kind casts]@@ -1730,47 +1768,28 @@        , le_env     = add_id id_env (case_bndr, scrut_var) } extendCaseBndrEnv env _ _ = env -includeTyVars, idsOnly :: Bool-idsOnly       = False-includeTyVars = True--maxFvLevel :: Bool -> LevelEnv -> DVarSet -> Level-maxFvLevel include_tyvars env var_set-  = nonDetStrictFoldDVarSet (maxIn include_tyvars env) tOP_LEVEL var_set+maxFvLevel :: (Var -> Bool) -> LevelEnv -> DVarSet -> Level+maxFvLevel max_me env var_set+  = nonDetStrictFoldDVarSet (maxIn max_me env) tOP_LEVEL var_set     -- It's OK to use a non-deterministic fold here because maxIn commutes. -maxFvLevel' :: Bool -> LevelEnv -> TyCoVarSet -> Level+maxFvLevel' :: (Var -> Bool) -> LevelEnv -> TyCoVarSet -> Level -- Same but for TyCoVarSet-maxFvLevel' include_tyvars env var_set-  = nonDetStrictFoldUniqSet (maxIn include_tyvars env) tOP_LEVEL var_set+maxFvLevel' max_me env var_set+  = nonDetStrictFoldUniqSet (maxIn max_me env) tOP_LEVEL var_set     -- It's OK to use a non-deterministic fold here because maxIn commutes. -maxIn :: Bool -> LevelEnv -> InVar -> Level -> Level--- True <=> include tyvars-maxIn include_tyvars env@(LE { le_subst = subst, le_env = id_env }) in_var lvl-  | isId in_var+maxIn :: (Var -> Bool) -> LevelEnv -> InVar -> Level -> Level+maxIn max_me (LE { le_lvl_env = lvl_env, le_env = id_env }) in_var lvl   = case lookupVarEnv id_env in_var of-      Nothing            -> maxOut env in_var lvl       Just (abs_vars, _) -> foldr max_out lvl abs_vars-          where-            max_out out_var lvl-              | isTyVar out_var && not include_tyvars-                          = lvl-              | otherwise = maxOut env out_var lvl--  | include_tyvars -- TyVars-  = case lookupTyVar subst in_var of-      Just ty -> nonDetStrictFoldVarSet (maxOut env) lvl (tyCoVarsOfType ty)-      Nothing -> maxOut env in_var lvl--  | otherwise      -- Ignore free tyvars-  = lvl--maxOut :: LevelEnv -> OutVar -> Level -> Level-maxOut (LE { le_lvl_env = lvl_env }) out_var lvl-  = case lookupVarEnv lvl_env out_var of-       Just lvl' -> maxLvl lvl' lvl-       Nothing   -> lvl+      Nothing            -> max_out in_var lvl+  where+    max_out out_var lvl+        | max_me out_var = case lookupVarEnv lvl_env out_var of+                                Just lvl' -> maxLvl lvl' lvl+                                Nothing   -> lvl+        | otherwise = lvl       -- Ignore some vars depending on max_me  lookupVar :: LevelEnv -> Id -> LevelledExpr lookupVar le v = case lookupVarEnv (le_env le) v of@@ -1877,7 +1896,7 @@ cloneCaseBndrs :: LevelEnv -> Level -> [Var] -> LvlM (LevelEnv, [Var]) cloneCaseBndrs env@(LE { le_subst = subst, le_lvl_env = lvl_env, le_env = id_env })                new_lvl vs-  = do { (subst', vs') <- cloneBndrs subst vs+  = do { (subst', vs') <- cloneBndrsM subst vs              -- N.B. We are not moving the body of the case, merely its case              -- binders.  Consequently we should *not* set le_ctxt_lvl.              -- See Note [Setting levels when floating single-alternative cases].@@ -1898,8 +1917,8 @@           dest_lvl vs   = do { let vs1  = map zap vs        ; (subst', vs2) <- case is_rec of-                            NonRecursive -> cloneBndrs      subst vs1-                            Recursive    -> cloneRecIdBndrs subst vs1+                            NonRecursive -> cloneBndrsM      subst vs1+                            Recursive    -> cloneRecIdBndrsM subst vs1         ; let prs  = vs `zip` vs2              env' = env { le_lvl_env = addLvls dest_lvl lvl_env vs2
GHC/Core/Opt/Simplify/Env.hs view
@@ -8,14 +8,13 @@  module GHC.Core.Opt.Simplify.Env (         -- * The simplifier mode-        SimplMode(..), updMode,-        smPedanticBottoms, smPlatform,+        SimplMode(..), updMode, smPlatform,          -- * Environments         SimplEnv(..), pprSimplEnv,   -- Temp not abstract         seArityOpts, seCaseCase, seCaseFolding, seCaseMerge, seCastSwizzle,         seDoEtaReduction, seEtaExpand, seFloatEnable, seInline, seNames,-        seOptCoercionOpts, sePedanticBottoms, sePhase, sePlatform, sePreInline,+        seOptCoercionOpts, sePhase, sePlatform, sePreInline,         seRuleOpts, seRules, seUnfoldingOpts,         mkSimplEnv, extendIdSubst, extendCvIdSubst,         extendTvSubst, extendCvSubst,@@ -25,13 +24,15 @@         getSimplRules, enterRecGroupRHSs,         reSimplifying, +        SimplEnvIS,  checkSimplEnvIS, pprBadSimplEnvIS,+         -- * Substitution results         SimplSR(..), mkContEx, substId, lookupRecBndr,          -- * Simplifying 'Id' binders         simplNonRecBndr, simplNonRecJoinBndr, simplRecBndrs, simplRecJoinBndrs,         simplBinder, simplBinders,-        substTy, substTyVar, getSubst,+        substTy, substTyVar, getFullSubst, getTCvSubst,         substCo, substCoVar,          -- * Floats@@ -59,8 +60,9 @@ import GHC.Core.Rules.Config ( RuleOpts(..) ) import GHC.Core import GHC.Core.Utils+import GHC.Core.Subst( substExprSC ) import GHC.Core.Unfold-import GHC.Core.TyCo.Subst (emptyIdSubstEnv)+import GHC.Core.TyCo.Subst (emptyIdSubstEnv, mkSubst) import GHC.Core.Multiplicity( Scaled(..), mkMultMul ) import GHC.Core.Make            ( mkWildValBinder, mkCoreLet ) import GHC.Core.Type hiding     ( substTy, substTyVar, substTyVarBndr, substCo@@ -202,6 +204,19 @@                                -- See Note [Inline depth]     } +type SimplEnvIS = SimplEnv+     -- Invariant: the substitution is empty+     -- We want this SimplEnv for its InScopeSet and flags++checkSimplEnvIS :: SimplEnvIS -> Bool+-- Check the invariant for SimplEnvIS+checkSimplEnvIS (SimplEnv { seIdSubst = id_env, seTvSubst = tv_env, seCvSubst = cv_env })+  = isEmptyVarEnv id_env && isEmptyVarEnv tv_env && isEmptyVarEnv cv_env++pprBadSimplEnvIS :: SimplEnvIS -> SDoc+-- Print a SimplEnv that fails checkSimplEnvIS+pprBadSimplEnvIS env = ppr (getFullSubst (seInScope env) env)+ seArityOpts :: SimplEnv -> ArityOpts seArityOpts env = sm_arity_opts (seMode env) @@ -235,9 +250,6 @@ seOptCoercionOpts :: SimplEnv -> OptCoercionOpts seOptCoercionOpts env = sm_co_opt_opts (seMode env) -sePedanticBottoms :: SimplEnv -> Bool-sePedanticBottoms env = smPedanticBottoms (seMode env)- sePhase :: SimplEnv -> CompilerPhase sePhase env = sm_phase (seMode env) @@ -292,9 +304,6 @@          where            pp_flag f s = ppUnless f (text "no") <+> s -smPedanticBottoms :: SimplMode -> Bool-smPedanticBottoms opts = ao_ped_bot (sm_arity_opts opts)- smPlatform :: SimplMode -> Platform smPlatform opts = roPlatform (sm_rule_opts opts) @@ -1265,33 +1274,47 @@ ************************************************************************ -} -getSubst :: SimplEnv -> Subst-getSubst (SimplEnv { seInScope = in_scope, seTvSubst = tv_env, seCvSubst = cv_env })-  = mkTCvSubst in_scope tv_env cv_env+getTCvSubst :: SimplEnv -> Subst+getTCvSubst (SimplEnv { seInScope = in_scope, seTvSubst = tv_env, seCvSubst = cv_env })+  = mkSubst in_scope emptyVarEnv tv_env cv_env +getFullSubst :: InScopeSet -> SimplEnv -> Subst+getFullSubst in_scope (SimplEnv { seIdSubst = id_env, seTvSubst = tv_env, seCvSubst = cv_env })+  = mk_full_subst in_scope tv_env cv_env id_env++mk_full_subst :: InScopeSet -> TvSubstEnv -> CvSubstEnv -> SimplIdSubst -> Subst+mk_full_subst in_scope tv_env cv_env id_env+  = mkSubst in_scope (mapVarEnv to_expr id_env) tv_env cv_env+  where+    to_expr :: SimplSR -> CoreExpr+    -- A tiresome impedence-matcher+    to_expr (DoneEx e _)           = e+    to_expr (DoneId v)             = Var v+    to_expr (ContEx tvs cvs ids e) = GHC.Core.Subst.substExprSC (mk_full_subst in_scope tvs cvs ids) e+ substTy :: HasDebugCallStack => SimplEnv -> Type -> Type-substTy env ty = Type.substTy (getSubst env) ty+substTy env ty = Type.substTy (getTCvSubst env) ty  substTyVar :: SimplEnv -> TyVar -> Type-substTyVar env tv = Type.substTyVar (getSubst env) tv+substTyVar env tv = Type.substTyVar (getTCvSubst env) tv  substTyVarBndr :: SimplEnv -> TyVar -> (SimplEnv, TyVar) substTyVarBndr env tv-  = case Type.substTyVarBndr (getSubst env) tv of+  = case Type.substTyVarBndr (getTCvSubst env) tv of         (Subst in_scope' _ tv_env' cv_env', tv')            -> (env { seInScope = in_scope', seTvSubst = tv_env', seCvSubst = cv_env' }, tv')  substCoVar :: SimplEnv -> CoVar -> Coercion-substCoVar env tv = Coercion.substCoVar (getSubst env) tv+substCoVar env tv = Coercion.substCoVar (getTCvSubst env) tv  substCoVarBndr :: SimplEnv -> CoVar -> (SimplEnv, CoVar) substCoVarBndr env cv-  = case Coercion.substCoVarBndr (getSubst env) cv of+  = case Coercion.substCoVarBndr (getTCvSubst env) cv of         (Subst in_scope' _ tv_env' cv_env', cv')            -> (env { seInScope = in_scope', seTvSubst = tv_env', seCvSubst = cv_env' }, cv')  substCo :: SimplEnv -> Coercion -> Coercion-substCo env co = Coercion.substCo (getSubst env) co+substCo env co = Coercion.substCo (getTCvSubst env) co  ------------------ substIdType :: SimplEnv -> Id -> Id@@ -1307,4 +1330,4 @@     no_free_vars = noFreeVarsOfType old_ty && noFreeVarsOfType old_w     subst = Subst in_scope emptyIdSubstEnv tv_env cv_env     old_ty = idType id-    old_w  = varMult id+    old_w  = idMult id
GHC/Core/Opt/Simplify/Iteration.hs view
@@ -8,7 +8,6 @@ {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE MultiWayIf #-} -{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-} module GHC.Core.Opt.Simplify.Iteration ( simplTopBinds, simplExpr, simplImpRules ) where  import GHC.Prelude@@ -31,9 +30,6 @@ import GHC.Core.Coercion.Opt    ( optCoercion ) import GHC.Core.FamInstEnv      ( FamInstEnv, topNormaliseType_maybe ) import GHC.Core.DataCon-   ( DataCon, dataConWorkId, dataConRepStrictness-   , dataConRepArgTys, isUnboxedTupleDataCon-   , StrictnessMark (..), dataConWrapId_maybe ) import GHC.Core.Opt.Stats ( Tick(..) ) import GHC.Core.Ppr     ( pprCoreExpr ) import GHC.Core.Unfold@@ -72,6 +68,7 @@ import GHC.Utils.Misc  import Control.Monad+import Data.List.NonEmpty (NonEmpty (..))  {- The guts of the simplifier is in this module, but the driver loop for@@ -284,7 +281,7 @@   | Just env' <- preInlineUnconditionally env (bindContextLevel bind_cxt)                                           old_bndr rhs env   = {-#SCC "simplRecOrTopPair-pre-inline-uncond" #-}-    simplTrace "SimplBindr:inline-uncond" (ppr old_bndr) $+    simplTrace "SimplBindr:inline-uncond1" (ppr old_bndr) $     do { tick (PreInlineUnconditionally old_bndr)        ; return ( emptyFloats env, env' ) } @@ -474,14 +471,14 @@  Wrinkles -(CWW1) We must /not/ do cast w/w on+1. We must /not/ do cast w/w on      f = g |> co    otherwise it'll just keep repeating forever! You might think this    is avoided because the call to tryCastWorkerWrapper is guarded by-   preInlineUnconditionally, but I'm worried that a loop-breaker or an-   exported Id might say False to preInlineUnconditionally.+   preInlineUnconditinally, but I'm worried that a loop-breaker or an+   exported Id might say False to preInlineUnonditionally. -(CWW2) We need to be careful with inline/noinline pragmas:+2. We need to be careful with inline/noinline pragmas:        rec { {-# NOINLINE f #-}              f = (...g...) |> co            ; g = ...f... }@@ -496,15 +493,15 @@            f = $wf |> co          ; g = ...f... }    and that is bad: the whole point is that we want to inline that-   cast!  We want to transfer the pragma to $wf:+   cast!  We want to transfer the pagma to $wf:       rec { {-# NOINLINE $wf #-}             $wf = ...g...           ; f = $wf |> co           ; g = ...f... }    c.f. Note [Worker/wrapper for NOINLINE functions] in GHC.Core.Opt.WorkWrap. -(CWW3) We should still do cast w/w even if `f` is INLINEABLE.  E.g.-      {- f: Stable unfolding (arity 2) = <stable-big> -}+3. We should still do cast w/w even if `f` is INLINEABLE.  E.g.+      {- f: Stable unfolding = <stable-big> -}       f = (\xy. <big-body>) |> co    Then we want to w/w to       {- $wf: Stable unfolding = <stable-big> |> sym co -}@@ -513,43 +510,15 @@    Notice that the stable unfolding moves to the worker!  Now demand analysis    will work fine on $wf, whereas it has trouble with the original f.    c.f. Note [Worker/wrapper for INLINABLE functions] in GHC.Core.Opt.WorkWrap.--(CWW4) We should /not/ do cast w/w for INLINE functions (hence `hasInlineUnfolding`-   in `tryCastWorkerWrapper`) because they'll definitely be inlined anyway, cast-   and all.+   This point also applies to strong loopbreakers with INLINE pragmas, see+   wrinkle (4). -   Moreover, if we do cast w/w for an INLINE function with arity zero, we get+4. We should /not/ do cast w/w for non-loop-breaker INLINE functions (hence+   hasInlineUnfolding in tryCastWorkerWrapper, which responds False to+   loop-breakers) because they'll definitely be inlined anyway, cast and+   all. And if we do cast w/w for an INLINE function with arity zero, we get    something really silly: we inline that "worker" right back into the wrapper!-   In fact it is Much Worse than a no-op, because we have then lost the stable-   unfolding --- aargh (see #26903).  E.g. similar example to (CWW3)-      {- g: Stable unfolding (arity 0) = <stable-big> -}   NB arity 0!-      g = (\xy. <big-body>) |> co-   If we w/w to this:-      {- $wg: Stable unfolding (arity 0) = <stable-big> |> sym co -}-      $wg = \xy. <big-body>-      g = $wg |> co-   then we'll inline $wg at the call site in `g` giving-      {- $wg: Stable unfolding (arity 0) = <stable-big> |> sym co -}-      $wg = \xy. <big-body>-      g = (<stable-big> |> sym co) |> co-   and now we'll drop `$wg` as dead and we have lost the unfolding on `g`.-   (We could /also/ give the binding `g = $wf |> co` a stable unfolding. Then-   things would work right; but there is also no point in doing the cast-   worker/wrapper in the first place.)--   NB: you might wonder about a loop-breaker with an INLINE pragma; after all, a-   loop breaker won't "definitely be inlined anyway", so arguably we should not-   disable cast w/w/ for it.  But a Rec group can /look/ recursive at an early-   stage, and subsequently /become/ non-recursive after some simplification.-   (This is common in instance decls; see Note [Checking for INLINE loop breakers]-   in GHC.Core.Lint.)  So the danger is that we'll permanently lose that stable-   unfolding that we specifically wanted (#26903).  Simple solution: disable cast-   w/w for /any/ INLINE function.  See the defn-   of `GHC.Types.Id.Info.hasInlineUnfolding`.--   The danger is that an INLINE pragma on a genuninely-recursive function-   will kill worker-wrapper.  Well, so be it.  They are pretty suspicious anyway;-   see Note [Checking for INLINE loop breakers].+   Worse than a no-op, because we have then lost the stable unfolding.  All these wrinkles are exactly like worker/wrapper for strictness analysis:   f is the wrapper and must inline like crazy@@ -614,11 +583,11 @@   | BC_Let top_lvl is_rec <- bind_cxt  -- Not join points   , not (isDFunId bndr) -- nor DFuns; cast w/w is no help, and we can't transform                         --            a DFunUnfolding in mk_worker_unfolding-  , not (exprIsTrivial rhs)          -- Not x = y |> co; see (CWW1)-  , not (hasInlineUnfolding info)    -- Not INLINE things: see (CWW4)-  , typeHasFixedRuntimeRep work_ty   -- Don't peel off a cast if doing so would-                                     -- lose the underlying runtime representation.-                                     -- See Note [Preserve RuntimeRep info in cast w/w]+  , not (exprIsTrivial rhs)        -- Not x = y |> co; Wrinkle 1+  , not (hasInlineUnfolding info)  -- Not INLINE things: Wrinkle 4+  , typeHasFixedRuntimeRep work_ty    -- Don't peel off a cast if doing so would+                                      -- lose the underlying runtime representation.+                                      -- See Note [Preserve RuntimeRep info in cast w/w]   , not (isOpaquePragma (idInlinePragma old_bndr)) -- Not for OPAQUE bindings                                                    -- See Note [OPAQUE pragma]   = do  { uniq <- getUniqueM@@ -665,13 +634,13 @@                               `setArityInfo`      work_arity            -- We do /not/ want to transfer OccInfo, Rules            -- Note [Preserve strictness in cast w/w]-           -- and (CWW2) of Note [Cast worker/wrapper]+           -- and Wrinkle 2 of Note [Cast worker/wrapper]      ----------- Worker unfolding -----------     -- Stable case: if there is a stable unfolding we have to compose with (Sym co);     --   the next round of simplification will do the job     -- Non-stable case: use work_rhs-    -- See (CWW4) of Note [Cast worker/wrapper]+    -- Wrinkle 3 of Note [Cast worker/wrapper]     mk_worker_unfolding top_lvl work_id work_rhs       = case realUnfoldingInfo info of -- NB: the real one, even for loop-breakers            unf@(CoreUnfolding { uf_tmpl = unf_rhs, uf_src = src })@@ -830,8 +799,8 @@ makeTrivialArg env arg@(ValArg { as_arg = e, as_dmd = dmd })   = do { (floats, e') <- makeTrivial env NotTopLevel dmd (fsLit "arg") e        ; return (floats, arg { as_arg = e' }) }-makeTrivialArg _ arg-  = return (emptyLetFloats, arg)  -- CastBy, TyArg+makeTrivialArg _ arg@(TyArg {})+  = return (emptyLetFloats, arg)  makeTrivial :: HasDebugCallStack             => SimplEnv -> TopLevelFlag -> Demand@@ -1190,14 +1159,14 @@            -> SimplM (SimplFloats, OutExpr)  simplExprF !env e !cont -- See Note [Bangs in the Simplifier]-  = {- pprTrace "simplExprF" (vcat-      [ ppr e-      , text "cont =" <+> ppr cont-      , text "inscope =" <+> ppr (seInScope env)-      , text "tvsubst =" <+> ppr (seTvSubst env)-      , text "idsubst =" <+> ppr (seIdSubst env)-      , text "cvsubst =" <+> ppr (seCvSubst env)-      ]) $ -}+  = -- pprTrace "simplExprF" (vcat+    --  [ ppr e+    --  , text "cont =" <+> ppr cont+    --  , text "inscope =" <+> ppr (seInScope env)+    --  , text "tvsubst =" <+> ppr (seTvSubst env)+    --  , text "idsubst =" <+> ppr (seIdSubst env)+    --  , text "cvsubst =" <+> ppr (seCvSubst env)+    --  ]) $     simplExprF1 env e cont  simplExprF1 :: HasDebugCallStack@@ -1210,7 +1179,7 @@     -- The (Type ty) case is handled separately by simplExpr     -- and by the other callers of simplExprF -simplExprF1 env (Var v)        cont = {-#SCC "simplIdF" #-} simplIdF env v cont+simplExprF1 env (Var v)        cont = {-#SCC "simplInId" #-} simplInId env v cont simplExprF1 env (Lit lit)      cont = {-#SCC "rebuild" #-} rebuild env (Lit lit) cont simplExprF1 env (Tick t expr)  cont = {-#SCC "simplTick" #-} simplTick env t expr cont simplExprF1 env (Cast body co) cont = {-#SCC "simplCast" #-} simplCast env body co cont@@ -1283,7 +1252,8 @@   | Just env' <- preInlineUnconditionally env NotTopLevel bndr rhs env     -- Because of the let-can-float invariant, it's ok to     -- inline freely, or to drop the binding if it is dead.-  = do { tick (PreInlineUnconditionally bndr)+  = do { simplTrace "SimplBindr:inline-uncond2" (ppr bndr) $+         tick (PreInlineUnconditionally bndr)        ; simplExprF env' body cont }    -- Now check for a join point.  It's better to do the preInlineUnconditionally@@ -1388,7 +1358,7 @@              -- See Note [Inline depth] in GHC.Core.Opt.Simplify.Env        ; seqCo opt_co `seq` return opt_co }   where-    subst = getSubst env+    subst = getTCvSubst env     opts  = seOptCoercionOpts env  -----------------------------------@@ -1491,8 +1461,8 @@     simplTickish env tickish-    | Breakpoint ext n ids modl <- tickish-          = Breakpoint ext n (mapMaybe (getDoneId . substId env) ids) modl+    | Breakpoint ext bid ids <- tickish+          = Breakpoint ext bid (mapMaybe (getDoneId . substId env) ids)     | otherwise = tickish    -- Push type application and coercion inside a tick@@ -1550,14 +1520,18 @@ -}  rebuild :: SimplEnv -> OutExpr -> SimplCont -> SimplM (SimplFloats, OutExpr)--- At this point the substitution in the SimplEnv should be irrelevant;--- only the in-scope set matters-rebuild env expr cont-  = case cont of+rebuild env expr cont = rebuild_go (zapSubstEnv env) expr cont++rebuild_go :: SimplEnvIS -> OutExpr -> SimplCont -> SimplM (SimplFloats, OutExpr)+-- SimplEnvIS: at this point the substitution in the SimplEnv is irrelevant;+-- only the in-scope set matters, plus the flags.+rebuild_go env expr cont+  = assertPpr (checkSimplEnvIS env) (pprBadSimplEnvIS env) $+    case cont of       Stop {}          -> return (emptyFloats env, expr)-      TickIt t cont    -> rebuild env (mkTick t expr) cont+      TickIt t cont    -> rebuild_go env (mkTick t expr) cont       CastIt { sc_co = co, sc_opt = opt, sc_cont = cont }-        -> rebuild env (mkCast expr co') cont+        -> rebuild_go env (mkCast expr co') cont            -- NB: mkCast implements the (Coercion co |> g) optimisation         where           co' = optOutCoercion env co opt@@ -1566,20 +1540,20 @@         -> rebuildCase (se `setInScopeFromE` env) expr bndr alts cont        StrictArg { sc_fun = fun, sc_cont = cont, sc_fun_ty = fun_ty }-        -> rebuildCall env (addValArgTo fun expr fun_ty ) cont+        -> rebuildCall env (addValArgTo fun expr fun_ty) cont        StrictBind { sc_bndr = b, sc_body = body, sc_env = se                  , sc_cont = cont, sc_from = from_what }         -> completeBindX (se `setInScopeFromE` env) from_what b expr body cont        ApplyToTy  { sc_arg_ty = ty, sc_cont = cont}-        -> rebuild env (App expr (Type ty)) cont+        -> rebuild_go env (App expr (Type ty)) cont        ApplyToVal { sc_arg = arg, sc_env = se, sc_dup = dup_flag                  , sc_cont = cont, sc_hole_ty = fun_ty }         -- See Note [Avoid redundant simplification]         -> do { (_, _, arg') <- simplLazyArg env dup_flag fun_ty Nothing se arg-              ; rebuild env (App expr arg') cont }+              ; rebuild_go env (App expr arg') cont }  completeBindX :: SimplEnv               -> FromWhat@@ -1689,7 +1663,7 @@ -}  -optOutCoercion :: SimplEnv -> OutCoercion -> Bool -> OutCoercion+optOutCoercion :: SimplEnvIS -> OutCoercion -> Bool -> OutCoercion -- See Note [Avoid re-simplifying coercions] optOutCoercion env co already_optimised   | already_optimised = co  -- See Note [Avoid re-simplifying coercions]@@ -1731,7 +1705,6 @@                                    , sc_hole_ty = coercionLKind co }) }                                         -- NB!  As the cast goes past, the                                         -- type of the hole changes (#16312)-         -- (f |> co) e   ===>   (f (e |> co1)) |> co2         -- where   co :: (s1->s2) ~ (t1->t2)         --         co1 :: t1 ~ s1@@ -1740,7 +1713,7 @@                                           , sc_dup = dup, sc_cont = tail                                           , sc_hole_ty = fun_ty })           | not opt  -- pushCoValArg duplicates the coercion, so optimise first-          = addCoerce (optOutCoercion env co opt) True cont+          = addCoerce (optOutCoercion (zapSubstEnv env) co opt) True cont            | Just (m_co1, m_co2) <- pushCoValArg co           , fixed_rep m_co1@@ -1778,7 +1751,8 @@           -- See Note [Representation polymorphism invariants] in GHC.Core           -- test: typecheck/should_run/EtaExpandLevPoly -simplLazyArg :: SimplEnv -> DupFlag+simplLazyArg :: SimplEnvIS              -- ^ Used only for its InScopeSet+             -> DupFlag              -> OutType                 -- ^ Type of the function applied to this arg              -> Maybe ArgInfo           -- ^ Just <=> This arg `ai` occurs in an app                                         --   `f a1 ... an` where we have ArgInfo on@@ -1858,18 +1832,22 @@              --      It's wrong to err in either direction              --      But fun_ty is an OutType, so is fully substituted -       ; if | isSimplified dup  -- Don't re-simplify if we've simplified it once-                                -- Including don't preInlineUnconditionally-                                -- See Note [Avoiding simplifying repeatedly]-            -> completeBindX env from_what bndr arg body cont--            | Just env' <- preInlineUnconditionally env NotTopLevel bndr arg arg_se+       ; if | Just env' <- preInlineUnconditionally env NotTopLevel bndr arg arg_se             , not (needsCaseBindingL arg_levity arg)               -- Ok to test arg::InExpr in needsCaseBinding because               -- exprOkForSpeculation is stable under simplification-            -> do { tick (PreInlineUnconditionally bndr)+            , not ( isSimplified dup &&  -- See (SR2) in Note [Avoiding simplifying repeatedly]+                    not (exprIsTrivial arg) &&+                    not (isDeadOcc (idOccInfo bndr)) )+            -> do { simplTrace "SimplBindr:inline-uncond3" (ppr bndr) $+                    tick (PreInlineUnconditionally bndr)                   ; simplLam env' body cont } +            | isSimplified dup  -- Don't re-simplify if we've simplified it once+                                -- Including don't preInlineUnconditionally+                                -- See Note [Avoiding simplifying repeatedly]+            -> completeBindX env from_what bndr arg body cont+             | otherwise             -> simplNonRecE env from_what bndr (arg, arg_se) body cont } @@ -2026,15 +2004,22 @@ * We go to some efforts to avoid unnecessarily simplifying ApplyToVal,   in at least two places     - In simplCast/addCoerce, where we check for isReflCo-    - In rebuildCall we avoid simplifying arguments before we have to-      (see Note [Trying rewrite rules])+    - We sometimes try rewrite RULES befoe simplifying arguments;+      see Note [tryRules: plan (BEFORE)] -All that said /postInlineUnconditionally/ (called in `completeBind`) does-fire in the above (f BIG) situation.  See Note [Post-inline for single-use-things] in Simplify.Utils.  This certainly risks repeated simplification, but-in practice seems to be a small win.+Wrinkles: +(SR1) All that said /postInlineUnconditionally/ (called in `completeBind`) does+    fire in the above (f BIG) situation.  See Note [Post-inline for single-use+    things] in Simplify.Utils.  This certainly risks repeated simplification,+    but in practice seems to be a small win. +(SR2) When considering preInlineUnconditionally in `simpl_lam`, if the+   expression is trivial, or it is dead (the binder doesn't occur), then there+   is no danger of simplifying repeatedly. But there is a benefit: it can save+   a simplifier iteration.  So we check for that.++ ************************************************************************ *                                                                      *                      Join points@@ -2233,25 +2218,29 @@ We'll clone the inner \x, adding x->x' in the id_subst Then when we inline y, we must *not* replace x by x' in the inlined copy!! -Note [Fast path for data constructors]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-For applications of a data constructor worker, the full glory of+Note [Fast path for lazy data constructors]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+For applications of a /lazy/ data constructor worker, the full glory of rebuildCall is a waste of effort; * They never inline, obviously * They have no rewrite rules-* They are not strict (see Note [Data-con worker strictness]-  in GHC.Core.DataCon)+* Lazy constructors don't need the `StrictArg` treatment. So it's fine to zoom straight to `rebuild` which just rebuilds the call in a very straightforward way. +For a data constructor worker that is strict (see Note [Strict fields in Core])+we take the slow path, so that we'll transform+  K (case x of (a,b) -> a)  -->   case x of (a,b) -> K a+via the StrictArg case of rebuildCall+ Some programs have a /lot/ of data constructors in the source program (compiler/perf/T9961 is an example), so this fast path can be very valuable. -} -simplVar :: SimplEnv -> InVar -> SimplM OutExpr+simplInVar :: SimplEnv -> InVar -> SimplM OutExpr -- Look up an InVar in the environment-simplVar env var+simplInVar env var   -- Why $! ? See Note [Bangs in the Simplifier]   | isTyVar var = return $! Type $! (substTyVar env var)   | isCoVar var = return $! Coercion $! (substCoVar env var)@@ -2262,10 +2251,11 @@         DoneId var1          -> return (Var var1)         DoneEx e _           -> return e -simplIdF :: SimplEnv -> InId -> SimplCont -> SimplM (SimplFloats, OutExpr)-simplIdF env var cont-  | isDataConWorkId var         -- See Note [Fast path for data constructors]-  = rebuild env (Var var) cont+simplInId :: SimplEnv -> InId -> SimplCont -> SimplM (SimplFloats, OutExpr)+simplInId env var cont+  | Just dc <- isDataConWorkId_maybe var+  , isLazyDataConRep dc                    -- See Note [Fast path for lazy data constructors]+  = rebuild zapped_env (Var var) cont   | otherwise   = case substId env var of       ContEx tvs cvs ids e -> simplExprF env' e cont@@ -2274,113 +2264,39 @@         where           env' = setSubstEnv env tvs cvs ids -      DoneId var1 ->-        do { rule_base <- getSimplRules-           ; let cont' = trimJoinCont var1 (idJoinPointHood var1) cont-                 info  = mkArgInfo env rule_base var1 cont'-           ; rebuildCall env info cont' }+      DoneId out_id -> simplOutId zapped_env out_id cont'+        where+          cont' = trimJoinCont out_id (idJoinPointHood out_id) cont -      DoneEx e mb_join -> simplExprF env' e cont'+      DoneEx e mb_join -> simplExprF zapped_env e cont'         where           cont' = trimJoinCont var mb_join cont-          env'  = zapSubstEnv env  -- See Note [zapSubstEnv]--------------------------------------------------------------      Dealing with a call site--rebuildCall :: SimplEnv -> ArgInfo -> SimplCont-            -> SimplM (SimplFloats, OutExpr)------------ Bottoming applications ---------------rebuildCall env (ArgInfo { ai_fun = fun, ai_args = rev_args, ai_dmds = [] }) cont-  -- When we run out of strictness args, it means-  -- that the call is definitely bottom; see GHC.Core.Opt.Simplify.Utils.mkArgInfo-  -- Then we want to discard the entire strict continuation.  E.g.-  --    * case (error "hello") of { ... }-  --    * (error "Hello") arg-  --    * f (error "Hello") where f is strict-  --    etc-  -- Then, especially in the first of these cases, we'd like to discard-  -- the continuation, leaving just the bottoming expression.  But the-  -- type might not be right, so we may have to add a coerce.-  | not (contIsTrivial cont)     -- Only do this if there is a non-trivial-                                 -- continuation to discard, else we do it-                                 -- again and again!-  = seqType cont_ty `seq`        -- See Note [Avoiding space leaks in OutType]-    return (emptyFloats env, castBottomExpr res cont_ty)   where-    res     = argInfoExpr fun rev_args-    cont_ty = contResultType cont------------ Try inlining, if ai_rewrite = TryInlining ----------- In the TryInlining case we try inlining immediately, before simplifying--- any (more) arguments. Why?  See Note [Rewrite rules and inlining].------ If there are rewrite rules we'll skip this case until we have--- simplified enough args to satisfy nr_wanted==0 in the TryRules case below--- Then we'll try the rules, and if that fails, we'll do TryInlining-rebuildCall env info@(ArgInfo { ai_fun = fun, ai_args = rev_args-                              , ai_rewrite = TryInlining }) cont-  = do { logger <- getLogger-       ; let full_cont = pushSimplifiedRevArgs env rev_args cont-       ; mb_inline <- tryInlining env logger fun full_cont-       ; case mb_inline of-            Just expr -> do { checkedTick (UnfoldingDone fun)-                            ; let env1 = zapSubstEnv env-                            ; simplExprF env1 expr full_cont }-            Nothing -> rebuildCall env (info { ai_rewrite = TryNothing }) cont-       }------------ Try rewrite RULES, if ai_rewrite = TryRules ----------------- See Note [Rewrite rules and inlining]--- See also Note [Trying rewrite rules]-rebuildCall env info@(ArgInfo { ai_fun = fun, ai_args = rev_args-                              , ai_rewrite = TryRules nr_wanted rules }) cont-  | nr_wanted == 0 || no_more_args-  = -- We've accumulated a simplified call in <fun,rev_args>-    -- so try rewrite rules; see Note [RULES apply to simplified arguments]-    -- See also Note [Rules for recursive functions]-    do { mb_match <- tryRules env rules fun (reverse rev_args) cont-       ; case mb_match of-             Just (env', rhs, cont') -> simplExprF env' rhs cont'-             Nothing -> rebuildCall env (info { ai_rewrite = TryInlining }) cont }-  where-    -- If we have run out of arguments, just try the rules; there might-    -- be some with lower arity.  Casts get in the way -- they aren't-    -- allowed on rule LHSs-    no_more_args = case cont of-                      ApplyToTy  {} -> False-                      ApplyToVal {} -> False-                      _             -> True------------ Simplify type applications and casts ---------------rebuildCall env info (CastIt { sc_co = co, sc_opt = opt, sc_cont = cont })-  = rebuildCall env (addCastTo info co') cont-  where-    co' = optOutCoercion env co opt+    zapped_env =  zapSubstEnv env  -- See Note [zapSubstEnv] -rebuildCall env info (ApplyToTy { sc_arg_ty = arg_ty, sc_hole_ty = hole_ty, sc_cont = cont })-  = rebuildCall env (addTyArgTo info arg_ty hole_ty) cont+---------------------------------------------------------+simplOutId :: SimplEnvIS -> OutId -> SimplCont -> SimplM (SimplFloats, OutExpr) ----------- The runRW# rule. Do this after absorbing all arguments ------+---------- The runRW# rule ------ -- See Note [Simplification of runRW#] in GHC.CoreToSTG.Prep. -- -- runRW# :: forall (r :: RuntimeRep) (o :: TYPE r). (State# RealWorld -> o) -> o--- K[ runRW# rr ty body ]   -->   runRW rr' ty' (\s. K[ body s ])-rebuildCall env (ArgInfo { ai_fun = fun_id, ai_args = rev_args })-            (ApplyToVal { sc_arg = arg, sc_env = arg_se-                        , sc_cont = cont, sc_hole_ty = fun_ty })-  | fun_id `hasKey` runRWKey-  , [ TyArg { as_arg_ty = hole_ty }, TyArg {} ] <- rev_args+-- K[ runRW# @rr @hole_ty body ]   -->   runRW @rr' @ty' (\s. K[ body s ])+simplOutId env fun cont+  | fun `hasKey` runRWKey+  , ApplyToTy  { sc_cont = cont1 } <- cont+  , ApplyToTy  { sc_cont = cont2, sc_arg_ty = hole_ty } <- cont1+  , ApplyToVal { sc_cont = cont3, sc_arg = arg+               , sc_env = arg_se, sc_hole_ty = fun_ty } <- cont2   -- Do this even if (contIsStop cont), or if seCaseCase is off.   -- See Note [No eta-expansion in runRW#]   = do { let arg_env = arg_se `setInScopeFromE` env -             overall_res_ty  = contResultType cont+             overall_res_ty = contResultType cont3              -- hole_ty is the type of the current runRW# application              (outer_cont, new_runrw_res_ty, inner_cont)-                | seCaseCase env = (mkBoringStop overall_res_ty, overall_res_ty, cont)-                | otherwise      = (cont, hole_ty, mkBoringStop hole_ty)+                | seCaseCase env = (mkBoringStop overall_res_ty, overall_res_ty, cont3)+                | otherwise      = (cont3, hole_ty, mkBoringStop hole_ty)                 -- Only when case-of-case is on. See GHC.Driver.Config.Core.Opt.Simplify                 --    Note [Case-of-case and full laziness] @@ -2407,9 +2323,76 @@                    ; return (Lam s' body') }         ; let rr'   = getRuntimeRep new_runrw_res_ty-             call' = mkApps (Var fun_id) [mkTyArg rr', mkTyArg new_runrw_res_ty, arg']+             call' = mkApps (Var fun) [mkTyArg rr', mkTyArg new_runrw_res_ty, arg']        ; rebuild env call' outer_cont } +-- Normal case for (f e1 .. en)+simplOutId env fun cont+  = -- Try rewrite rules: Plan (BEFORE) in Note [When to apply rewrite rules]+    do { rule_base <- getSimplRules+       ; let rules_for_me = getRules rule_base fun+             out_args     = contOutArgs env cont :: [OutExpr]+       ; mb_match <- if not (null rules_for_me) &&+                        (isClassOpId fun || activeUnfolding (seMode env) fun)+                     then tryRules env rules_for_me fun out_args+                     else return Nothing+       ; case mb_match of {+             Just (rule_arity, rhs) -> simplExprF env rhs $+                                       dropContArgs rule_arity cont ;+             Nothing ->++    -- Try inlining+    do { logger <- getLogger+       ; mb_inline <- tryInlining env logger fun cont+       ; case mb_inline of{+            Just expr -> do { checkedTick (UnfoldingDone fun)+                            ; simplExprF env expr cont } ;+            Nothing ->++    -- Neither worked, so just rebuild+    do { let arg_info = mkArgInfo env fun rules_for_me cont+       ; rebuildCall env arg_info cont+    } } } } }++---------------------------------------------------------+--      Dealing with a call site++rebuildCall :: SimplEnvIS -> ArgInfo -> SimplCont+            -> SimplM (SimplFloats, OutExpr)+-- SimplEnvIS: at this point the substitution in the SimplEnv is irrelevant;+-- it is usually empty, and regardless should be ignored.+-- Only the in-scope set matters, plus the seMode flags++-- Check the invariant+rebuildCall env arg_info _cont+  | assertPpr (checkSimplEnvIS env) (pprBadSimplEnvIS env $$ ppr arg_info) False+  = pprPanic "rebuildCall" empty++---------- Bottoming applications --------------+rebuildCall env (ArgInfo { ai_fun = fun, ai_args = rev_args, ai_dmds = [] }) cont+  -- When we run out of strictness args, it means+  -- that the call is definitely bottom; see GHC.Core.Opt.Simplify.Utils.mkArgInfo+  -- Then we want to discard the entire strict continuation.  E.g.+  --    * case (error "hello") of { ... }+  --    * (error "Hello") arg+  --    * f (error "Hello") where f is strict+  --    etc+  -- Then, especially in the first of these cases, we'd like to discard+  -- the continuation, leaving just the bottoming expression.  But the+  -- type might not be right, so we may have to add a coerce.+  | not (contIsTrivial cont)     -- Only do this if there is a non-trivial+                                 -- continuation to discard, else we do it+                                 -- again and again!+  = seqType cont_ty `seq`        -- See Note [Avoiding space leaks in OutType]+    return (emptyFloats env, castBottomExpr res cont_ty)+  where+    res     = argInfoExpr fun rev_args+    cont_ty = contResultType cont++---------- Simplify type applications --------------+rebuildCall env info (ApplyToTy { sc_arg_ty = arg_ty, sc_hole_ty = hole_ty, sc_cont = cont })+  = rebuildCall env (addTyArgTo info arg_ty hole_ty) cont+ ---------- Simplify value arguments -------------------- rebuildCall env fun_info             (ApplyToVal { sc_arg = arg, sc_env = arg_se@@ -2440,8 +2423,16 @@         ; rebuildCall env (addValArgTo fun_info  arg' fun_ty) cont }  ---------- No further useful info, revert to generic rebuild -------------rebuildCall env (ArgInfo { ai_fun = fun, ai_args = rev_args }) cont+rebuildCall env (ArgInfo { ai_fun = fun, ai_args = rev_args, ai_rules = rules }) cont+  | null rules   = rebuild env (argInfoExpr fun rev_args) cont+  | otherwise  -- Try rules again: Plan (AFTER) in Note [When to apply rewrite rules]+  = do { let args = reverse rev_args+       ; mb_match <- tryRules env rules fun (map argSpecArg args)+       ; case mb_match of+           Just (rule_arity, rhs) -> simplExprF env rhs $+                                     pushSimplifiedArgs env (drop rule_arity args) cont+           Nothing -> rebuild env (argInfoExpr fun rev_args) cont }  ----------------------------------- tryInlining :: SimplEnv -> Logger -> OutId -> SimplCont -> SimplM (Maybe OutExpr)@@ -2475,83 +2466,102 @@                               text "Cont:  " <+> ppr cont])]  -{- Note [Trying rewrite rules]+{- Note [When to apply rewrite rules]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+Should we apply rewrite rules before simplifying the arguments, or after?+Each is highly desirable in some cases, and in fact we do both!++  - Plan (BEFORE) selectively, in `simplOutId`+    See Note [tryRules: plan (BEFORE)]++  - Plan (AFTER) always, in the finishing-up case of `rebuildCall`+    See Note [tryRules: plan (AFTER)]++Historical note.  Pre-2025, GHC only did tryRules once, when it had simplified+enough arguments to saturate all the RULEs it had in hand.  But alas, if a new+unrelated RULE showed up (but did not fire), it could nevertheless change the+simplifier's behaviour a bit; and that messed up deterministic compilation+(#25170).  (This was particularly nasty if the rule wasn't even transitively+below the module being compiled.)  Current solution: ensure that adding a new,+unrelated rule that never fires does not change the simplifier behaviour.  End+of historical note.++Note [tryRules: plan (BEFORE)] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-Consider an application (f e1 e2 e3) where the e1,e2,e3 are not yet-simplified.  We want to simplify enough arguments to allow the rules-to apply, but it's more efficient to avoid simplifying e2,e3 if e1 alone-is sufficient.  Example: class ops-   (+) dNumInt e2 e3-If we rewrite ((+) dNumInt) to plusInt, we can take advantage of the-latter's strictness when simplifying e2, e3.  Moreover, suppose we have-  RULE  f Int = \x. x True+It is sometimes desirable to apply RULES before simplifying the function+arguments.  We do so in `simplOutId`. -Then given (f Int e1) we rewrite to-   (\x. x True) e1-without simplifying e1.  Now we can inline x into its unique call site,-and absorb the True into it all in the same pass.  If we simplified-e1 first, we couldn't do that; see Note [Avoiding simplifying repeatedly].+We do so /selectively/ (see (BF2)), in two particular cases: -So we try to apply rules if either-  (a) no_more_args: we've run out of argument that the rules can "see"-  (b) nr_wanted: none of the rules wants any more arguments+* Class ops+     (+) dNumInt e2 e3+  If we rewrite ((+) dNumInt) to plusInt, we can take advantage of the+  latter's strictness when simplifying e2, e3.  Moreover, if+      (+) dNumInt e2 e3   -->    (\x y -> ....) e2 e3+  Frequently `x` is used just once in the body of the (\x y -> ...).+  If `e2` is un-simplified we can preInlineUnconditinally and that saves+  simplifying `e2` twice. See Note [Avoiding simplifying repeatedly]. +* Specialisation RULES.  In general we try to arrange that inlining is disabled+  (via a pragma) if a rewrite rule should apply, so that the rule has a decent+  chance to fire before we inline the function. -Note [RULES apply to simplified arguments]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-It's very desirable to try RULES once the arguments have been simplified, because-doing so ensures that rule cascades work in one pass.  Consider-   {-# RULES g (h x) = k x-             f (k x) = x #-}-   ...f (g (h x))...-Then we want to rewrite (g (h x)) to (k x) and only then try f's rules. If-we match f's rules against the un-simplified RHS, it won't match.  This-makes a particularly big difference when superclass selectors are involved:-        op ($p1 ($p2 (df d)))-We want all this to unravel in one sweep.+  But it turns out that (especially when type-class specialisation or+  SpecConstr is involved) it is very helpful for the the rewrite rule to+  "win" over inlining when both are active at once: see #21851, #22097. -Note [Rewrite rules and inlining]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-In general we try to arrange that inlining is disabled (via a pragma) if-a rewrite rule should apply, so that the rule has a decent chance to fire-before we inline the function.+  So if the Id has an unfolding, we want to try RULES before we try inlining. -But it turns out that (especially when type-class specialisation or-SpecConstr is involved) it is very helpful for the the rewrite rule to-"win" over inlining when both are active at once: see #21851, #22097.+Wrinkles: -The simplifier arranges to do this, as follows. In effect, the ai_rewrite-field of the ArgInfo record is the state of a little state-machine:+(BF1) Each un-simplified argument has its own static environment, stored+  in its `ApplyToVal` nodes.   So we can't just match on the un-simplified+  arguments: we  have to apply that static environment as a substitution+  first!  This is done lazily in `GHC.Core.Opt.Simplify.Utils.contOutArgs`,+  so it'll be done just enough to allow the rule to match, or not. -* mkArgInfo sets the ai_rewrite field to TryRules if there are any rewrite-  rules avaialable for that function.+(BF2) The "selectively" in Plan (BEFORE) is a bit ad-hoc: -* rebuildCall simplifies arguments until enough are simplified to match the-  rule with greatest arity.  See Note [RULES apply to simplified arguments]-  and the first field of `TryRules`.+  * We want Plan (BEFORE) for class ops (see above in this Note) -  But no more! As soon as we have simplified enough arguments to satisfy the-  maximum-arity rules, we try the rules; see Note [Trying rewrite rules].+  * But we do NOT want Plan (BEFORE) for primops, because the constant-folding+    rules are quite complicated and expensive, and we don't want to try them+    twice.  Moreover the benefts of Plan (BEFORE), described in the Note, don't+    apply to primops. -* Once we have tried rules (or immediately if there are no rules) set-  ai_rewrite to TryInlining, and the Simplifier will try to inline the-  function.  We want to try this immediately (before simplifying any (more)-  arguments). Why? Consider-      f BIG      where   f = \x{OneOcc}. ...x...-  If we inline `f` before simplifying `BIG` well use preInlineUnconditionally,-  and we'll simplify BIG once, at x's occurrence, rather than twice.+Note [tryRules: plan (AFTER)]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+It's very desirable to try RULES once the arguments have been simplified,+because doing so ensures that rule cascades work in one pass. We do this+in the finishing-up case of `rebuildCall`. -* GHC.Core.Opt.Simplify.Utils. mkRewriteCall: if there are no rules, and no-  unfolding, we can skip both TryRules and TryInlining, which saves work.+Consider+   {-# RULES g (h x) = k x+             f (k x) = x #-}+   ...f (g (h x))...+Then we want to rewrite (g (h x)) to (k x) and only then try f's rules. If+we match f's rules against the un-simplified RHS, it won't match.  This+makes a particularly big difference for +* Superclass selectors+        op ($p1 ($p2 (df d)))+  We want all this to unravel in one sweep++* Constant folding+        +# 3# (+# 4# 5#)+  We want this to happen in one pass+ Note [Avoid redundant simplification] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-Because RULES apply to simplified arguments, there's a danger of repeatedly-simplifying already-simplified arguments.  An important example is that of-        (>>=) d e1 e2-Here e1, e2 are simplified before the rule is applied, but don't really-participate in the rule firing. So we mark them as Simplified to avoid-re-simplifying them.+Because RULES often apply to simplified arguments (see Note [Plan (AFTER)]),+there's a danger of simplifying already-simplified arguments.  For example,+suppose we have+   RULE f (x,y) = $sf x  y+and the expression+   f (p,q) e1 e2+With Plan (AFTER) by the time the rule fires, we will have already simplified e1, e2,+and we want to avoid doing so a second time.  So ApplyToVal records if the argument+is already Simplified.  Note [Shadowing in the Simplifier] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~@@ -2601,33 +2611,19 @@ -}  tryRules :: SimplEnv -> [CoreRule]-         -> Id-         -> [ArgSpec]   -- In /normal, forward/ order-         -> SimplCont-         -> SimplM (Maybe (SimplEnv, CoreExpr, SimplCont))--tryRules env rules fn args call_cont-  | null rules-  = return Nothing+         -> OutId -> [OutExpr]+         -> SimplM (Maybe (FullArgCount, CoreExpr)) -  | Just (rule, rule_rhs) <- lookupRule ropts (getUnfoldingInRuleMatch env)-                                        (activeRule (seMode env)) fn-                                        (argInfoAppArgs args) rules+tryRules env rules fn args+  | Just (rule, rule_rhs) <- lookupRule ropts in_scope_env+                                        act_fun fn args rules   -- Fire a rule for the function   = do { logger <- getLogger        ; checkedTick (RuleFired (ruleName rule))-       ; let cont' = pushSimplifiedArgs zapped_env-                                        (drop (ruleArity rule) args)-                                        call_cont-                     -- (ruleArity rule) says how-                     -- many args the rule consumed--             occ_anald_rhs = occurAnalyseExpr rule_rhs+       ; let occ_anald_rhs = occurAnalyseExpr rule_rhs                  -- See Note [Occurrence-analyse after rule firing]        ; dump logger rule rule_rhs-       ; return (Just (zapped_env, occ_anald_rhs, cont')) }-            -- The occ_anald_rhs and cont' are all Out things-            -- hence zapping the environment+       ; return (Just (ruleArity rule, occ_anald_rhs)) }    | otherwise  -- No rule fires   = do { logger <- getLogger@@ -2635,8 +2631,9 @@        ; return Nothing }    where-    ropts      = seRuleOpts env-    zapped_env = zapSubstEnv env  -- See Note [zapSubstEnv]+    ropts        = seRuleOpts env :: RuleOpts+    in_scope_env = getUnfoldingInRuleMatch env :: InScopeEnv+    act_fun      = activeRule (seMode env) :: Activation -> Bool      printRuleModule rule       = parens (maybe (text "BUILTIN")@@ -2648,10 +2645,9 @@       = log_rule Opt_D_dump_rule_rewrites "Rule fired" $ vcat           [ text "Rule:" <+> ftext (ruleName rule)           , text "Module:" <+>  printRuleModule rule+          , text "Full arity:" <+>  ppr (ruleArity rule)           , text "Before:" <+> hang (ppr fn) 2 (sep (map ppr args))-          , text "After: " <+> hang (pprCoreExpr rule_rhs) 2-                               (sep $ map ppr $ drop (ruleArity rule) args)-          , text "Cont:  " <+> ppr call_cont ]+          , text "After: " <+> pprCoreExpr rule_rhs ]        | logHasDumpFlag logger Opt_D_dump_rule_firings       = log_rule Opt_D_dump_rule_firings "Rule fired:" $@@ -2683,13 +2679,23 @@ trySeqRules :: SimplEnv             -> OutExpr -> InExpr   -- Scrutinee and RHS             -> SimplCont-            -> SimplM (Maybe (SimplEnv, CoreExpr, SimplCont))+            -> SimplM (Maybe (CoreExpr, SimplCont)) -- See Note [User-defined RULES for seq]+-- `in_env` applies to `rhs :: InExpr` but not to `scrut :: OutExpr` trySeqRules in_env scrut rhs cont   = do { rule_base <- getSimplRules-       ; tryRules in_env (getRules rule_base seqId) seqId out_args rule_cont }+       ; let seq_rules = getRules rule_base seqId+       ; mb_match <- tryRules in_env seq_rules seqId out_args+       ; case mb_match of+            Nothing                -> return Nothing+            Just (rule_arity, rhs) -> return (Just (rhs, cont'))+                where+                  cont' = pushSimplifiedArgs in_env (drop rule_arity out_arg_specs) rule_cont+       }   where     no_cast_scrut = drop_casts scrut++    -- All these are OutTypes     scrut_ty  = exprType no_cast_scrut     seq_id_ty = idType seqId                    -- forall r a (b::TYPE r). a -> b -> b     res1_ty   = piResultTy seq_id_ty rhs_rep    -- forall a (b::TYPE rhs_rep). a -> b -> b@@ -2698,21 +2704,23 @@     res4_ty   = funResultTy res3_ty             -- rhs_ty -> rhs_ty     rhs_ty    = substTy in_env (exprType rhs)     rhs_rep   = getRuntimeRep rhs_ty-    out_args  = [ TyArg { as_arg_ty  = rhs_rep++    out_args = [Type rhs_rep, Type scrut_ty, Type rhs_ty, no_cast_scrut]+               -- Cheaper than (map argSpecArg out_arg_specs)+    out_arg_specs  = [ TyArg { as_arg_ty  = rhs_rep                         , as_hole_ty = seq_id_ty }-                , TyArg { as_arg_ty  = scrut_ty-                        , as_hole_ty = res1_ty }-                , TyArg { as_arg_ty  = rhs_ty-                        , as_hole_ty = res2_ty }-                , ValArg { as_arg = no_cast_scrut-                         , as_dmd = seqDmd-                         , as_hole_ty = res3_ty } ]+                     , TyArg { as_arg_ty  = scrut_ty+                             , as_hole_ty = res1_ty }+                     , TyArg { as_arg_ty  = rhs_ty+                             , as_hole_ty = res2_ty }+                     , ValArg { as_arg = no_cast_scrut+                              , as_dmd = seqDmd+                              , as_hole_ty = res3_ty } ]     rule_cont = ApplyToVal { sc_dup = NoDup, sc_arg = rhs                            , sc_env = in_env, sc_cont = cont                            , sc_hole_ty = res4_ty }      -- Lazily evaluated, so we don't do most of this-     drop_casts (Cast e _) = drop_casts e     drop_casts e          = e @@ -3188,8 +3196,8 @@   | is_plain_seq   = do { mb_rule <- trySeqRules env scrut rhs cont        ; case mb_rule of-           Just (env', rule_rhs, cont') -> simplExprF env' rule_rhs cont'-           Nothing                      -> reallyRebuildCase env scrut case_bndr alts cont }+           Just (rule_rhs, cont') -> simplExprF (zapSubstEnv env) rule_rhs cont'+           Nothing                -> reallyRebuildCase env scrut case_bndr alts cont }  -------------------------------------------------- --      3. Primop-related case-rules@@ -3240,7 +3248,7 @@                             --    Note [Case-of-case and full laziness]   = do { case_expr <- simplAlts env scrut case_bndr alts                                 (mkBoringStop (contHoleType cont))-       ; rebuild env case_expr cont }+       ; rebuild (zapSubstEnv env) case_expr cont }    | otherwise   = do { (floats, env', cont') <- mkDupableCaseCont env alts cont@@ -3490,7 +3498,7 @@  We really must record that b is already evaluated so that we don't go and re-evaluate it when constructing the result.-See Note [Data-con worker strictness] in GHC.Core.DataCon+See Note [Strict fields in Core] in GHC.Core.  NB: simplLamBndrs preserves this eval info @@ -3753,7 +3761,7 @@       | exprIsTrivial scrut = return (emptyFloats env                                      , extendIdSubst env bndr (DoneEx scrut NotJoinPoint))                               -- See Note [Do not duplicate constructor applications]-      | otherwise           = do { dc_args <- mapM (simplVar env) bs+      | otherwise           = do { dc_args <- mapM (simplInVar env) bs                                          -- dc_ty_args are already OutTypes,                                          -- but bs are InBndrs                                  ; let con_app = Var (dataConWorkId dc)@@ -3844,13 +3852,17 @@                                        --   extra let/join-floats and in-scope variables                         , SimplCont)   -- dup_cont: duplicable continuation mkDupableCont env cont-  = mkDupableContWithDmds env (repeat topDmd) cont+  = mkDupableContWithDmds (zapSubstEnv env) (repeat topDmd) cont  mkDupableContWithDmds-   :: SimplEnv  -> [Demand]  -- Demands on arguments; always infinite+   :: SimplEnvIS  -> [Demand]  -- Demands on arguments; always infinite    -> SimplCont -> SimplM ( SimplFloats, SimplCont)  mkDupableContWithDmds env _ cont+  -- Check the invariant+  | assertPpr (checkSimplEnvIS env) (pprBadSimplEnvIS env) False+  = pprPanic "mkDupableContWithDmds" empty+   | contIsDupable cont   = return (emptyFloats env, cont) @@ -3893,7 +3905,7 @@   , thumbsUpPlanA cont   = -- Use Plan A of Note [Duplicating StrictArg] --    pprTrace "Using plan A" (ppr (ai_fun fun) $$ text "args" <+> ppr (ai_args fun) $$ text "cont" <+> ppr cont) $-    do { let (_ : dmds) = ai_dmds fun+    do { let _ :| dmds = expectNonEmpty $ ai_dmds fun        ; (floats1, cont')  <- mkDupableContWithDmds env dmds cont                               -- Use the demands from the function to add the right                               -- demand info on any bindings we make for further args@@ -3939,7 +3951,7 @@         --              let a = ...arg...         --              in [...hole...] a         -- NB: sc_dup /= OkToDup; that is caught earlier by contIsDupable-    do  { let (dmd:cont_dmds) = dmds   -- Never fails+    do  { let dmd:|cont_dmds = expectNonEmpty dmds         ; (floats1, cont') <- mkDupableContWithDmds env cont_dmds cont         ; let env' = env `setInScopeFromF` floats1         ; (_, se', arg') <- simplLazyArg env' dup hole_ty Nothing se arg@@ -4014,7 +4026,7 @@   | otherwise   = do { join_bndr <- newJoinId [arg_bndr] res_ty        ; let arg_info = ArgInfo { ai_fun   = join_bndr-                                , ai_rewrite = TryNothing, ai_args  = []+                                , ai_rules = [], ai_args  = []                                 , ai_encl  = False, ai_dmds  = repeat topDmd                                 , ai_discs = repeat 0 }        ; return ( addJoinFloats (emptyFloats env) $@@ -4199,17 +4211,40 @@       K g y -> blah[g,y]  But now we have to make `blah` into a join point, /abstracted/-over `g` and `y`.   In contrast, if we /don't/ inline $j we-don't need a join point for `blah` and we'll get-    join $j x = let g=f, y=x in blah[g,y]+over `g` and `y`. We get+    join $j2 g y = blah     in case v of-       p1 -> $j x1-       p2 -> $j x2-       p3 -> $j x3+         p1 -> $j2 f x1+         p2 -> $j2 f x2+         p3 -> $j2 f x3+So now we can't see that `g` is always `f` in `blah`. +In contrast, if we /don't/ inline $j we+don't need a new join point for `blah` and we'll get+    join $j' x = let g=f, y=x in blah[g,y]+    in case v of+       p1 -> $j' x1+       p2 -> $j' x2+       p3 -> $j' x3+ This can make a /massive/ difference, because `blah` can see what `f` is, instead of lambda-abstracting over it. +If instead the RHS of the join point is a simple application that has no free+variables, as in++    case (join $j x f = K f x )+         (in case v of      )+         (     p1 -> $j x1 f1 ) of+         (     p2 -> $j x2 f2 )+         (     p3 -> $j x3 f3 )+      K g y -> blah[g,y]++then no information can be gained by preserving the join point (c.f. `f` being+free in the join point above and being useful to `blah`). In this case, it's+more beneficial to inline the join point (see (DJ3)(c)) to allow further+optimisations to fire. An example where failing to do this went wrong is #25723.+ Beyond this, not-inlining join points reduces duplication.  In the above example, if `blah` was small enough we'd inline it, but that duplicates code, for no gain.  Best just to keep not-inline the join point in the first place.@@ -4234,11 +4269,26 @@    case-of-case friendly.  (DJ3) When should `uncondInlineJoin` return True?-   * (exprIsTrivial rhs); this includes uses of unsafeEqualityProof etc; see+   (a) (exprIsTrivial rhs); this includes uses of unsafeEqualityProof etc; see      the defn of exprIsTrivial.  Also nullary constructors. -   * The RHS is a call ($j x y z), where the arguments are all trivial and $j+   (b) The RHS is a call ($j x y z), where the arguments are all trivial and $j      is a join point: there is no point in creating an indirection.++   (c) The RHS is a data constructor application (K x y z) where++      - all the args x,y,z are trivial+      - the free LocalIds of `f x y z` are a subset of the join point binders++      Examples that return True+        $j x y = K y (x |> co)+        $j x y = x (y @Int)+      Examples that return False+        $j x = K y x    -- y is free+        $j y = f y      -- f is free++      Not duplicating these join points has no benefits and blocks other important+      optimisations from firing (see #25723)  (DJ4) By the same token we want to use Plan B in Note [Duplicating StrictArg] when    the RHS of the new join point is a data constructor application.  See the
GHC/Core/Opt/Simplify/Utils.hs view
@@ -25,15 +25,15 @@         isSimplified, contIsStop,         contIsDupable, contResultType, contHoleType, contHoleScaling,         contIsTrivial, contArgs, contIsRhs,-        countArgs,+        countArgs, contOutArgs, dropContArgs,         mkBoringStop, mkRhsStop, mkLazyArgStop,         interestingCallContext,          -- ArgInfo-        ArgInfo(..), ArgSpec(..), RewriteCall(..), mkArgInfo,-        addValArgTo, addCastTo, addTyArgTo,-        argInfoExpr, argInfoAppArgs,-        pushSimplifiedArgs, pushSimplifiedRevArgs,+        ArgInfo(..), ArgSpec(..), mkArgInfo,+        addValArgTo, addTyArgTo,+        argInfoExpr, argSpecArg,+        pushSimplifiedArgs,         isStrictArgInfo, lazyArgContext,          abstractFloats,@@ -55,7 +55,6 @@ import GHC.Core.TyCo.Ppr ( pprParendType ) import GHC.Core.FVs import GHC.Core.Utils-import GHC.Core.Rules( RuleEnv, getRules ) import GHC.Core.Opt.Arity import GHC.Core.Unfold import GHC.Core.Unfold.Make@@ -73,7 +72,6 @@ import GHC.Types.Demand import GHC.Types.Var.Set import GHC.Types.Basic-import GHC.Types.Name.Env  import GHC.Data.OrdList ( isNilOL ) import GHC.Data.FastString ( fsLit )@@ -83,9 +81,9 @@ import GHC.Utils.Outputable import GHC.Utils.Panic -import Control.Monad    ( guard, when )+import Control.Monad    ( when ) import Data.List        ( sortBy )-import Data.Maybe+import GHC.Types.Name.Env import Data.Graph  {- *********************************************************************@@ -285,7 +283,7 @@   ppr (ApplyToTy  { sc_arg_ty = ty, sc_cont = cont })     = (text "ApplyToTy" <+> pprParendType ty) $$ ppr cont   ppr (ApplyToVal { sc_arg = arg, sc_dup = dup, sc_cont = cont, sc_hole_ty = hole_ty })-    = (hang (text "ApplyToVal" <+> ppr dup <+> text "hole" <+> ppr hole_ty)+    = (hang (text "ApplyToVal" <+> ppr dup <+> text "hole-ty:" <+> pprParendType hole_ty)           2 (pprParendExpr arg))       $$ ppr cont   ppr (StrictBind { sc_bndr = b, sc_cont = cont })@@ -325,11 +323,10 @@   = ArgInfo {         ai_fun   :: OutId,      -- The function         ai_args  :: [ArgSpec],  -- ...applied to these args (which are in *reverse* order)--        ai_rewrite :: RewriteCall,  -- What transformation to try next for this call-             -- See Note [Rewrite rules and inlining] in GHC.Core.Opt.Simplify.Iteration+                                -- NB: all these argumennts are already simplified -        ai_encl :: Bool,        -- Flag saying whether this function+        ai_rules :: [CoreRule], -- Rules for this function+        ai_encl  :: Bool,       -- Flag saying whether this function                                 -- or an enclosing one has rules (recursively)                                 --      True => be keener to inline in all args @@ -343,12 +340,6 @@                                 --   Always infinite     } -data RewriteCall  -- What rewriting to try next for this call-                  -- See Note [Rewrite rules and inlining] in GHC.Core.Opt.Simplify.Iteration-  = TryRules FullArgCount [CoreRule]-  | TryInlining-  | TryNothing- data ArgSpec   = ValArg { as_dmd  :: Demand        -- Demand placed on this argument            , as_arg  :: OutExpr       -- Apply to this (coercion or value); c.f. ApplyToVal@@ -357,62 +348,46 @@   | TyArg { as_arg_ty  :: OutType     -- Apply to this type; c.f. ApplyToTy           , as_hole_ty :: OutType }   -- Type of the function (presumably forall a. blah) -  | CastBy OutCoercion                -- Cast by this; c.f. CastIt-                                      -- Coercion is optimised- instance Outputable ArgInfo where-  ppr (ArgInfo { ai_fun = fun, ai_args = args, ai_dmds = dmds })+  ppr (ArgInfo { ai_fun = fun, ai_args = args, ai_dmds = dmds, ai_rules = rules })     = text "ArgInfo" <+> braces          (sep [ text "fun =" <+> ppr fun               , text "dmds(first 10) =" <+> ppr (take 10 dmds)-              , text "args =" <+> ppr args ])+              , text "args =" <+> ppr args+              , text "rewrite =" <+> ppr rules ])  instance Outputable ArgSpec where   ppr (ValArg { as_arg = arg })  = text "ValArg" <+> ppr arg   ppr (TyArg { as_arg_ty = ty }) = text "TyArg" <+> ppr ty-  ppr (CastBy c)                 = text "CastBy" <+> ppr c  addValArgTo :: ArgInfo ->  OutExpr -> OutType -> ArgInfo addValArgTo ai arg hole_ty-  | ArgInfo { ai_dmds = dmd:dmds, ai_discs = _:discs, ai_rewrite = rew } <- ai+  | ArgInfo { ai_dmds = dmd:dmds, ai_discs = _:discs } <- ai       -- Pop the top demand and and discounts off   , let arg_spec = ValArg { as_arg = arg, as_hole_ty = hole_ty, as_dmd = dmd }   = ai { ai_args    = arg_spec : ai_args ai        , ai_dmds    = dmds-       , ai_discs   = discs-       , ai_rewrite = decArgCount rew }+       , ai_discs   = discs }   | otherwise   = pprPanic "addValArgTo" (ppr ai $$ ppr arg)     -- There should always be enough demands and discounts  addTyArgTo :: ArgInfo -> OutType -> OutType -> ArgInfo-addTyArgTo ai arg_ty hole_ty = ai { ai_args    = arg_spec : ai_args ai-                                  , ai_rewrite = decArgCount (ai_rewrite ai) }+addTyArgTo ai arg_ty hole_ty = ai { ai_args    = arg_spec : ai_args ai }   where     arg_spec = TyArg { as_arg_ty = arg_ty, as_hole_ty = hole_ty } -addCastTo :: ArgInfo -> OutCoercion -> ArgInfo-addCastTo ai co = ai { ai_args = CastBy co : ai_args ai }- isStrictArgInfo :: ArgInfo -> Bool -- True if the function is strict in the next argument isStrictArgInfo (ArgInfo { ai_dmds = dmds })   | dmd:_ <- dmds = isStrUsedDmd dmd   | otherwise     = False -argInfoAppArgs :: [ArgSpec] -> [OutExpr]-argInfoAppArgs []                              = []-argInfoAppArgs (CastBy {}                : _)  = []  -- Stop at a cast-argInfoAppArgs (ValArg { as_arg = arg }  : as) = arg     : argInfoAppArgs as-argInfoAppArgs (TyArg { as_arg_ty = ty } : as) = Type ty : argInfoAppArgs as--pushSimplifiedArgs, pushSimplifiedRevArgs-  :: SimplEnv-  -> [ArgSpec]   -- In normal, forward order for pushSimplifiedArgs,-                 -- in /reverse/ order for pushSimplifiedRevArgs-  -> SimplCont -> SimplCont-pushSimplifiedArgs    env args cont = foldr  (pushSimplifiedArg env)             cont args-pushSimplifiedRevArgs env args cont = foldl' (\k a -> pushSimplifiedArg env a k) cont args+pushSimplifiedArgs :: SimplEnv+                   -> [ArgSpec]   -- In normal, forward order+                   -> SimplCont -> SimplCont+pushSimplifiedArgs env args cont = foldr (pushSimplifiedArg env) cont args+-- pushSimplifiedRevArgs env args cont = foldl' (\k a -> pushSimplifiedArg env a k) cont args  pushSimplifiedArg :: SimplEnv -> ArgSpec -> SimplCont -> SimplCont pushSimplifiedArg _env (TyArg { as_arg_ty = arg_ty, as_hole_ty = hole_ty }) cont@@ -421,9 +396,11 @@   = ApplyToVal { sc_arg = arg, sc_env = env, sc_dup = Simplified                  -- The SubstEnv will be ignored since sc_dup=Simplified                , sc_hole_ty = hole_ty, sc_cont = cont }-pushSimplifiedArg _ (CastBy c) cont-  = CastIt { sc_co = c, sc_cont = cont, sc_opt = True } +argSpecArg :: ArgSpec -> OutExpr+argSpecArg (ValArg { as_arg = arg })   = arg+argSpecArg (TyArg  { as_arg_ty = ty }) = Type ty+ argInfoExpr :: OutId -> [ArgSpec] -> OutExpr -- NB: the [ArgSpec] is reversed so that the first arg -- in the list is the last one in the application@@ -433,29 +410,7 @@     go []                              = Var fun     go (ValArg { as_arg = arg }  : as) = go as `App` arg     go (TyArg { as_arg_ty = ty } : as) = go as `App` Type ty-    go (CastBy co                : as) = mkCast (go as) co -decArgCount :: RewriteCall -> RewriteCall-decArgCount (TryRules n rules) = TryRules (n-1) rules-decArgCount rew                = rew--mkRewriteCall :: Id -> RuleEnv -> RewriteCall--- See Note [Rewrite rules and inlining] in GHC.Core.Opt.Simplify.Iteration--- We try to skip any unnecessary stages:---    No rules     => skip TryRules---    No unfolding => skip TryInlining--- This skipping is "just" for efficiency.  But rebuildCall is--- quite a heavy hammer, so skipping stages is a good plan.--- And it's extremely simple to do.-mkRewriteCall fun rule_env-  | not (null rules) = TryRules n_required rules-  | canUnfold unf    = TryInlining-  | otherwise        = TryNothing-  where-    n_required = maximum (map ruleArity rules)-    rules = getRules rule_env fun-    unf   = idUnfolding fun- {- ************************************************************************ *                                                                      *@@ -593,6 +548,34 @@                    -- Do *not* use short-cutting substitution here                    -- because we want to get as much IdInfo as possible +contOutArgs :: SimplEnv -> SimplCont -> [OutExpr]+-- Get the leading arguments from the `SimplCont`, as /OutExprs/+contOutArgs env cont+  = go cont+  where+    in_scope = seInScope env++    go (ApplyToTy { sc_arg_ty = ty, sc_cont = cont })+      = Type ty : go cont++    go (ApplyToVal { sc_dup = dup, sc_arg = arg, sc_env = env, sc_cont = cont })+      | isSimplified dup = arg : go cont+      | otherwise        = GHC.Core.Subst.substExpr (getFullSubst in_scope env) arg : go cont+        -- Make sure we apply the static environment `sc_env` as a substitution+        --   to get an OutExpr.  See (BF1) in Note [tryRules: plan (BEFORE)]+        --   in GHC.Core.Opt.Simplify.Iteration+        -- NB: we use substExpr, not substExprSC: we want to get the benefit of+        --     knowing what is evaluated etc, via the in-scope set++    -- No more arguments+    go _ = []++dropContArgs :: FullArgCount -> SimplCont -> SimplCont+dropContArgs 0 cont = cont+dropContArgs n (ApplyToTy  { sc_cont = cont }) = dropContArgs (n-1) cont+dropContArgs n (ApplyToVal { sc_cont = cont }) = dropContArgs (n-1) cont+dropContArgs n cont = pprPanic "dropContArgs" (ppr n $$ ppr cont)+ -- | Describes how the 'SimplCont' will evaluate the hole as a 'SubDemand'. -- This can be more insightful than the limited syntactic context that -- 'SimplCont' provides, because the 'Stop' constructor might carry a useful@@ -624,29 +607,26 @@     -- and case binder dmds, see addCaseBndrDmd. No priority right now.  --------------------mkArgInfo :: SimplEnv -> RuleEnv -> Id -> SimplCont -> ArgInfo--mkArgInfo env rule_base fun cont+mkArgInfo :: SimplEnv -> Id -> [CoreRule] -> SimplCont -> ArgInfo+mkArgInfo env fun rules_for_fun cont   | n_val_args < idArity fun            -- Note [Unsaturated functions]   = ArgInfo { ai_fun = fun, ai_args = []-            , ai_rewrite = fun_rewrite+            , ai_rules = rules_for_fun             , ai_encl = False             , ai_dmds = vanilla_dmds             , ai_discs = vanilla_discounts }   | otherwise   = ArgInfo { ai_fun   = fun             , ai_args  = []-            , ai_rewrite = fun_rewrite+            , ai_rules = rules_for_fun             , ai_encl  = fun_has_rules || contHasRules cont             , ai_dmds  = add_type_strictness (idType fun) arg_dmds             , ai_discs = arg_discounts }   where-    n_val_args    = countValArgs cont-    fun_rewrite   = mkRewriteCall fun rule_base-    fun_has_rules = case fun_rewrite of-                      TryRules {} -> True-                      _           -> False+    n_val_args  = countValArgs cont +    fun_has_rules = not (null rules_for_fun)+     vanilla_discounts, arg_discounts :: [Int]     vanilla_discounts = repeat 0     arg_discounts = case idUnfolding fun of@@ -873,7 +853,7 @@ got too much fruitless inlining, which led to regressions (#22317 is an example).  A good example of a function where this 'small incentive' is important is-GHC.Num.Integer where we ended up with calls like this:+GHC.Internal.Bignum.Integer where we ended up with calls like this:      case (integerSignum a b) of r -> ... but were failing to inline integerSignum, even though it always returns a single constructor, so it is very helpful to inline it. There is also an@@ -1069,7 +1049,7 @@    (a) NonTrivArg for an arg with an OtherCon [] unfolding    (b) ValueArg for an arg with an OtherCon [c1,c2..] unfolding. -Reason for (a): I found (in the GHC.Num.Integer library) that I was+Reason for (a): I found (in the GHC.Internal.Bignum.Integer module) that I was inlining a pretty big function when all we knew was that its arguments were evaluated, nothing more.  That in turn make the enclosing function too big to inline elsewhere.@@ -1516,6 +1496,10 @@     canInlineInLam (Lit _)    = True     canInlineInLam (Lam b e)  = isRuntimeVar b || canInlineInLam e     canInlineInLam (Tick t e) = not (tickishIsCode t) && canInlineInLam e+    canInlineInLam (Var v)    = case idOccInfo v of+                                  OneOcc { occ_in_lam = IsInsideLam } -> True+                                  ManyOccs {}                         -> True+                                  _                                   -> False     canInlineInLam _          = False       -- not ticks.  Counting ticks cannot be duplicated, and non-counting       -- ticks around a Lam will disappear anyway.@@ -2472,27 +2456,7 @@                 True  -> True;                 False -> False -and similar friends.  There are some tricky wrinkles:--(EIC1) Casts. We've seen this:-            case e of x { _ -> x `cast` c }-       And we definitely want to eliminate this case, to give-            e `cast` c-(EIC2) Ticks. Similarly-            case e of x { _ -> Tick t x }-       At least if the tick is 'floatable' we want to eliminate the case-       to give-            Tick t e--So `check_eq` strips off enclosing casts and ticks from the RHS of the-alternative, returning a wrapper function that will rebuild them around-the scrutinee if case-elim is successful.--(EIC3) What if there are many alternatives, all identities. If casts-  are involved they must be the same cast, to make the types line up.-  In principle there could be different ticks in each RHS, but we just-  pick the ticks from the first alternative.  (In the common case there-  is only one alternative.)+and similar friends.  Note [Scrutinee Constant Folding] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~@@ -2686,47 +2650,45 @@ --         See Note [Eliminate Identity Case] -------------------------------------------------- -mkCase1 _mode scrut case_bndr _ (alt1 : alts)      -- Identity case-  | Just wrap <- identity_alt alt1   -- `wrap`: see (EIC1) and (EIC2)-  , all (isJust . identity_alt) alts -- See (EIC3) in Note [Eliminate Identity Case]+mkCase1 _mode scrut case_bndr _ alts@(Alt _ _ rhs1 : alts')      -- Identity case+  | all identity_alt alts   = do { tick (CaseIdentity case_bndr)-       ; return (wrap scrut) }+       ; return (mkTicks ticks $ re_cast scrut rhs1) }   where-    identity_alt :: CoreAlt -> Maybe (CoreExpr -> CoreExpr)-    identity_alt (Alt con args rhs) = check_eq con args rhs+    ticks = concatMap (\(Alt _ _ rhs) -> stripTicksT tickishFloatable rhs) alts'+    identity_alt (Alt con args rhs) = check_eq rhs con args -    check_eq :: AltCon -> [Var] -> CoreExpr -> Maybe (CoreExpr -> CoreExpr)-    -- (check_eq con args e) return True if-    --       e   looks like   (Tick (Cast (Tick (con args))))-    -- where (con args) is the LHS of the alternative-    -- In that case it returns (\e. Tick (Cast (Tick e))),-    -- a wrapper function that can rebuild the tick/cast stuff-    -- See (EIC1) and (EIC2) in Note [Eliminate Identity Case]-    check_eq alt_con args (Cast e co)         -- See (EIC1)-      = do { guard (not (any (`elemVarSet` tyCoVarsOfCo co) args))-           ; wrap <- check_eq alt_con args e-           ; return (flip mkCast co . wrap) }-    check_eq alt_con args (Tick t e)          -- See (EIC2)-      = do { guard (tickishFloatable t)-           ; wrap <- check_eq alt_con args e-           ; return (Tick t . wrap) }-    check_eq alt_con args e-      | is_id alt_con args e = Just (\e -> e)-      | otherwise            = Nothing+    check_eq (Cast rhs co) con args        -- See Note [RHS casts]+      = not (any (`elemVarSet` tyCoVarsOfCo co) args) && check_eq rhs con args+    check_eq (Tick t e) alt args+      = tickishFloatable t && check_eq e alt args -    is_id :: AltCon -> [Var] -> CoreExpr -> Bool-    is_id _ _  (Var v) | v == case_bndr = True-    is_id (LitAlt lit') _ (Lit lit)     = lit == lit'-    is_id (DataAlt con) args rhs-      | Var v <- rhs   -- Optimisation only-      , null arg_tys-      , null args      = v == dataConWorkId con-      | otherwise      = cheapEqExpr' tickishFloatable rhs $-                         mkConApp2 con arg_tys args-    is_id _ _ _ = False+    check_eq (Lit lit) (LitAlt lit') _     = lit == lit'+    check_eq (Var v) _ _  | v == case_bndr = True+    check_eq (Var v)   (DataAlt con) args+      | null arg_tys, null args            = v == dataConWorkId con+                                             -- Optimisation only+    check_eq rhs        (DataAlt con) args = cheapEqExpr' tickishFloatable rhs $+                                             mkConApp2 con arg_tys args+    check_eq _          _             _    = False      arg_tys = tyConAppArgs (idType case_bndr) +        -- Note [RHS casts]+        -- ~~~~~~~~~~~~~~~~+        -- We've seen this:+        --      case e of x { _ -> x `cast` c }+        -- And we definitely want to eliminate this case, to give+        --      e `cast` c+        -- So we throw away the cast from the RHS, and reconstruct+        -- it at the other end.  All the RHS casts must be the same+        -- if (all identity_alt alts) holds.+        --+        -- Don't worry about nested casts, because the simplifier combines them++    re_cast scrut (Cast rhs co) = Cast (re_cast scrut rhs) co+    re_cast scrut _             = scrut+ mkCase1 mode scrut bndr alts_ty alts = mkCase2 mode scrut bndr alts_ty alts  @@ -2842,8 +2804,9 @@ isExitJoinId :: Var -> Bool isExitJoinId id   = isJoinId id-  && isOneOcc (idOccInfo id)-  && occ_in_lam (idOccInfo id) == IsInsideLam+  && case idOccInfo id of+        OneOcc { occ_in_lam = IsInsideLam } -> True+        _                                   -> False  {- Note [Dead binders]
GHC/Core/Opt/SpecConstr.hs view
@@ -1,7 +1,4 @@-{-# LANGUAGE CPP, LambdaCase #-}-#if __GLASGOW_HASKELL__ < 905-{-# LANGUAGE PatternSynonyms #-}-#endif+{-# LANGUAGE LambdaCase #-} {- ToDo [Oct 2013] ~~~~~~~~~~~~~~~@@ -14,10 +11,6 @@ \section[SpecConstr]{Specialise over constructors} -} ---{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-}- module GHC.Core.Opt.SpecConstr(         specConstrProgram,         SpecConstrAnnotation(..),@@ -42,7 +35,7 @@ import GHC.Core.Class( classTyVars ) import GHC.Core.Coercion hiding( substCo ) import GHC.Core.Rules-import GHC.Core.Predicate ( typeDeterminesValue )+import GHC.Core.Predicate ( scopedSort, typeDeterminesValue ) import GHC.Core.Type     hiding ( substTy ) import GHC.Core.TyCon   (TyCon, tyConName ) import GHC.Core.Multiplicity@@ -68,7 +61,7 @@ import GHC.Types.Unique.FM import GHC.Types.Unique( hasKey ) -import GHC.Data.Maybe     ( orElse, catMaybes, isJust, isNothing )+import GHC.Data.Maybe     ( fromMaybe, orElse, catMaybes, isJust, isNothing ) import GHC.Data.FastString  import GHC.Utils.Misc@@ -84,6 +77,7 @@  import Control.Monad import Data.List ( sortBy, partition, dropWhileEnd, mapAccumL )+import Data.List.NonEmpty ( NonEmpty (..) ) import Data.Maybe( mapMaybe ) import Data.Ord( comparing ) import Data.Tuple@@ -1042,16 +1036,7 @@ scSubstId env v = lookupIdSubst (sc_subst env) v  --- Solo is only defined in base starting from ghc-9.2-#if !(MIN_VERSION_base(4, 16, 0))-data Solo a = Solo a-#endif --- The Solo constructor was renamed to MkSolo in ghc 9.5-#if __GLASGOW_HASKELL__ < 905-pattern MkSolo :: a -> Solo a-pattern MkSolo a = Solo a-#endif  -- The !subst ensures that we force the selection `(sc_subst env)`, which avoids -- retaining all of `env` when we only need `subst`.  The `Solo` means that the@@ -1314,13 +1299,12 @@                            scu_occs  = plusVarEnv_C combineOcc (scu_occs u1) (scu_occs u2) }  combineUsages :: [ScUsage] -> ScUsage-combineUsages [] = nullUsage-combineUsages us = foldr1 combineUsage us+combineUsages = foldr1WithDefault nullUsage combineUsage -lookupOccs :: ScUsage -> [OutVar] -> (ScUsage, [ArgOcc])+lookupOccs :: Traversable f => ScUsage -> f OutVar -> (ScUsage, f ArgOcc) lookupOccs (SCU { scu_calls = sc_calls, scu_occs = sc_occs }) bndrs   = (SCU {scu_calls = sc_calls, scu_occs = delVarEnvList sc_occs bndrs},-     [lookupVarEnv sc_occs b `orElse` NoOcc | b <- bndrs])+    fromMaybe NoOcc . lookupVarEnv sc_occs <$> bndrs)  data ArgOcc = NoOcc     -- Doesn't occur at all; or a type argument             | UnkOcc    -- Used in some unknown way@@ -1383,7 +1367,7 @@ combineOcc UnkOcc        UnkOcc        = UnkOcc  combineOccs :: [ArgOcc] -> [ArgOcc] -> [ArgOcc]-combineOccs xs ys = zipWithEqual "combineOccs" combineOcc xs ys+combineOccs xs ys = zipWithEqual combineOcc xs ys  setScrutOcc :: ScEnv -> ScUsage -> OutExpr -> ArgOcc -> ScUsage -- _Overwrite_ the occurrence info for the scrutinee, if the scrutinee@@ -1490,7 +1474,7 @@          ; let all_usg = (spec_usg `combineUsage` body_usg)  -- Note [spec_usg includes rhs_usg]                         `delCallsFor` bndrs'-              bind'   = Rec (concat (zipWithEqual "scExpr'" ruleInfoBinds rhs_infos specs))+              bind'   = Rec (concat (zipWithEqual ruleInfoBinds rhs_infos specs))                         -- zipWithEqual: length of returned [SpecInfo]                         -- should be the same as incoming [RhsInfo] @@ -1596,7 +1580,7 @@      = do { let (env1, bs1) = extendBndrsWith RecArg env bs                 (env2, bs2) = extendCaseBndrs env1 scrut' b' con bs1           ; (usg, rhs', ws) <- scExpr env2 rhs-          ; let (usg', b_occ:arg_occs) = lookupOccs usg (b':bs2)+          ; let (usg', b_occ:|arg_occs) = lookupOccs usg (b':|bs2)                 scrut_occ = case con of                                DataAlt dc -- See Note [Do not specialise evals]                                   | not (single_alt && all deadArgOcc arg_occs)@@ -2465,7 +2449,7 @@               good_pats :: [CallPat]               good_pats = catMaybes mb_pats -              in_scope = getSubstInScope (sc_subst env)+              in_scope = substInScopeSet (sc_subst env)                -- Remove patterns we have already done               new_pats = filterOut is_done good_pats@@ -2512,35 +2496,32 @@     partitionByWorkerSize worker_size pats = go pats [] []       where         go [] small warnings = (small, warnings)-        go (p:ps) small warnings-          | WorkerSmallEnough <- worker_size p-          = go ps (p:small) warnings-          | WorkerTooLarge <- worker_size p-          = go ps small warnings-          | WorkerTooLargeForced name <- worker_size p-          = go ps small (SpecFailForcedArgCount name : warnings)+        go (p:ps) small warnings =+          case worker_size p of+            WorkerSmallEnough -> go ps (p:small) warnings+            WorkerTooLarge -> go ps small warnings+            WorkerTooLargeForced name -> go ps small (SpecFailForcedArgCount name : warnings)   trim_pats :: ScEnv -> Id -> SpecInfo -> [CallPat] -> (Bool, [CallPat]) -- True <=> some patterns were discarded -- See Note [Choosing patterns] trim_pats env fn (SI { si_n_specs = done_spec_count }) pats-  | sc_force env-    || isNothing mb_scc-    || n_remaining >= n_pats-  = -- pprTrace "trim_pats: no-trim" (ppr (sc_force env) $$ ppr mb_scc $$ ppr n_remaining $$ ppr n_pats)-    (False, pats)          -- No need to trim+  | False <- sc_force env+  , Just max_specs <- mb_scc+  , let n_remaining = max_specs - done_spec_count+  , n_remaining < n_pats+  = emit_trace max_specs n_remaining $  -- Need to trim, so keep the best ones+    (True, take n_remaining sorted_pats)    | otherwise-  = emit_trace $  -- Need to trim, so keep the best ones-    (True, take n_remaining sorted_pats)+  = -- pprTrace "trim_pats: no-trim" (ppr (sc_force env) $$ ppr mb_scc $$ ppr n_remaining $$ ppr n_pats)+    (False, pats)          -- No need to trim    where     n_pats         = length pats     spec_count'    = n_pats + done_spec_count-    n_remaining    = max_specs - done_spec_count     mb_scc         = sc_count $ sc_opts env-    Just max_specs = mb_scc      sorted_pats = map fst $                   sortBy (comparing snd) $@@ -2563,21 +2544,24 @@           n_cons (Lit {})    = 1           n_cons _           = 0 -    emit_trace result+    emit_trace max_specs n_remaining result        | debugIsOn || sc_debug (sc_opts env)          -- Suppress this scary message for ordinary users!  #5125        = pprTrace "SpecConstr" msg result        | otherwise        = result-    msg = vcat [ sep [ text "Function" <+> quotes (ppr fn)-                     , nest 2 (text "has" <+>-                               speakNOf spec_count' (text "call pattern") <> comma <+>-                               text "but the limit is" <+> int max_specs) ]-               , text "Use -fspec-constr-count=n to set the bound"-               , text "done_spec_count =" <+> int done_spec_count-               , text "Keeping " <+> int n_remaining <> text ", out of" <+> int n_pats-               , text "Discarding:" <+> ppr (drop n_remaining sorted_pats) ]-+      where+        msg = vcat+          [ sep+              [ text "Function" <+> quotes (ppr fn)+              , nest 2+                  ( text "has" <+>+                    speakNOf spec_count' (text "call pattern") <> comma <+>+                    text "but the limit is" <+> int max_specs ) ]+          , text "Use -fspec-constr-count=n to set the bound"+          , text "done_spec_count =" <+> int done_spec_count+          , text "Keeping " <+> int n_remaining <> text ", out of" <+> int n_pats+          , text "Discarding:" <+> ppr (drop n_remaining sorted_pats) ]  callToPat :: ScEnv -> [ArgOcc] -> Call -> UniqSM (Maybe CallPat)         -- The [Var] is the variables to quantify over in the rule@@ -2585,7 +2569,7 @@         --      over the following term variables         -- The [CoreExpr] are the argument patterns for the rule callToPat env bndr_occs call@(Call fn args con_env)-  = do  { let in_scope = getSubstInScope (sc_subst env)+  = do  { let in_scope = substInScopeSet (sc_subst env)          ; arg_triples <- zipWith3M (argToPat env in_scope con_env) args bndr_occs (map (const NotMarkedStrict) args)                    -- This zip trims the args to be no longer than@@ -2842,8 +2826,11 @@                -- but that doesn't take account of which branch of a                -- case we are in, which is the whole point -  | not (isLocalId v) && isCheapUnfolding unf-  = isValue env (unfoldingTemplate unf)+  | not (isLocalId v)+  , isCheapUnfolding unf+  , Just rhs <- maybeUnfoldingTemplate unf  -- Succeds if isCheapUnfolding does+  = isValue env rhs   -- Can't use isEvaldUnfolding because+                      -- we want to consult the `env`   where     unf = idUnfolding v         -- However we do want to consult the unfolding
GHC/Core/Opt/Specialise.hs view
@@ -1,3531 +1,3660 @@-{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-}--{--(c) The GRASP/AQUA Project, Glasgow University, 1993-1998--\section[Specialise]{Stamping out overloading, and (optionally) polymorphism}--}--module GHC.Core.Opt.Specialise ( specProgram, specUnfolding ) where--import GHC.Prelude--import GHC.Driver.DynFlags-import GHC.Driver.Config-import GHC.Driver.Config.Diagnostic-import GHC.Driver.Config.Core.Rules ( initRuleOpts )--import GHC.Core.Type  hiding( substTy, substCo, extendTvSubst, zapSubst )-import GHC.Core.Multiplicity-import GHC.Core.SimpleOpt( defaultSimpleOpts, simpleOptExprWith )-import GHC.Core.Predicate-import GHC.Core.Coercion( Coercion )-import GHC.Core.Opt.Monad-import qualified GHC.Core.Subst as Core-import GHC.Core.Unfold.Make-import GHC.Core-import GHC.Core.Make      ( mkLitRubbish )-import GHC.Core.Unify     ( tcMatchTy )-import GHC.Core.Rules-import GHC.Core.Utils     ( exprIsTrivial, exprIsTopLevelBindable-                          , mkCast, exprType-                          , stripTicksTop, mkInScopeSetBndrs )-import GHC.Core.FVs-import GHC.Core.TyCo.FVs ( tyCoVarsOfTypeList )-import GHC.Core.Opt.Arity( collectBindersPushingCo )--- import GHC.Core.Ppr( pprIds )--import GHC.Builtin.Types  ( unboxedUnitTy )--import GHC.Data.Maybe     ( maybeToList, isJust )-import GHC.Data.Bag-import GHC.Data.OrdList-import GHC.Data.List.SetOps--import GHC.Types.Basic-import GHC.Types.Unique.Supply-import GHC.Types.Unique.DFM-import GHC.Types.Name-import GHC.Types.Tickish-import GHC.Types.Id.Make  ( voidArgId, voidPrimId )-import GHC.Types.Var      ( PiTyBinder(..), isLocalVar, isInvisibleFunArg, mkLocalVar )-import GHC.Types.Var.Set-import GHC.Types.Var.Env-import GHC.Types.Id-import GHC.Types.Id.Info-import GHC.Types.Error--import GHC.Utils.Error ( mkMCDiagnostic )-import GHC.Utils.Monad    ( foldlM )-import GHC.Utils.Misc-import GHC.Utils.Outputable-import GHC.Utils.Panic--import GHC.Unit.Module( Module )-import GHC.Unit.Module.ModGuts-import GHC.Core.Unfold--import Data.List( partition )-import Data.List.NonEmpty ( NonEmpty (..) )-import GHC.Core.Subst (substTickish)--{--************************************************************************-*                                                                      *-\subsection[notes-Specialise]{Implementation notes [SLPJ, Aug 18 1993]}-*                                                                      *-************************************************************************--These notes describe how we implement specialisation to eliminate-overloading.--The specialisation pass works on Core-syntax, complete with all the explicit dictionary application,-abstraction and construction as added by the type checker.  The-existing type checker remains largely as it is.--One important thought: the {\em types} passed to an overloaded-function, and the {\em dictionaries} passed are mutually redundant.-If the same function is applied to the same type(s) then it is sure to-be applied to the same dictionary(s)---or rather to the same {\em-values}.  (The arguments might look different but they will evaluate-to the same value.)--Second important thought: we know that we can make progress by-treating dictionary arguments as static and worth specialising on.  So-we can do without binding-time analysis, and instead specialise on-dictionary arguments and no others.--The basic idea-~~~~~~~~~~~~~~-Suppose we have--        let f = <f_rhs>-        in <body>--and suppose f is overloaded.--STEP 1: CALL-INSTANCE COLLECTION--We traverse <body>, accumulating all applications of f to types and-dictionaries.--(Might there be partial applications, to just some of its types and-dictionaries?  In principle yes, but in practice the type checker only-builds applications of f to all its types and dictionaries, so partial-applications could only arise as a result of transformation, and even-then I think it's unlikely.  In any case, we simply don't accumulate such-partial applications.)---STEP 2: EQUIVALENCES--So now we have a collection of calls to f:-        f t1 t2 d1 d2-        f t3 t4 d3 d4-        ...-Notice that f may take several type arguments.  To avoid ambiguity, we-say that f is called at type t1/t2 and t3/t4.--We take equivalence classes using equality of the *types* (ignoring-the dictionary args, which as mentioned previously are redundant).--STEP 3: SPECIALISATION--For each equivalence class, choose a representative (f t1 t2 d1 d2),-and create a local instance of f, defined thus:--        f@t1/t2 = <f_rhs> t1 t2 d1 d2--f_rhs presumably has some big lambdas and dictionary lambdas, so lots-of simplification will now result.  However we don't actually *do* that-simplification.  Rather, we leave it for the simplifier to do.  If we-*did* do it, though, we'd get more call instances from the specialised-RHS.  We can work out what they are by instantiating the call-instance-set from f's RHS with the types t1, t2.--Add this new id to f's IdInfo, to record that f has a specialised version.--Before doing any of this, check that f's IdInfo doesn't already-tell us about an existing instance of f at the required type/s.-(This might happen if specialisation was applied more than once, or-it might arise from user SPECIALIZE pragmas.)--Recursion-~~~~~~~~~-Wait a minute!  What if f is recursive?  Then we can't just plug in-its right-hand side, can we?--But it's ok.  The type checker *always* creates non-recursive definitions-for overloaded recursive functions.  For example:--        f x = f (x+x)           -- Yes I know its silly--becomes--        f a (d::Num a) = let p = +.sel a d-                         in-                         letrec fl (y::a) = fl (p y y)-                         in-                         fl--We still have recursion for non-overloaded functions which we-specialise, but the recursive call should get specialised to the-same recursive version.---Polymorphism 1-~~~~~~~~~~~~~~--All this is crystal clear when the function is applied to *constant-types*; that is, types which have no type variables inside.  But what if-it is applied to non-constant types?  Suppose we find a call of f at type-t1/t2.  There are two possibilities:--(a) The free type variables of t1, t2 are in scope at the definition point-of f.  In this case there's no problem, we proceed just as before.  A common-example is as follows.  Here's the Haskell:--        g y = let f x = x+x-              in f y + f y--After typechecking we have--        g a (d::Num a) (y::a) = let f b (d'::Num b) (x::b) = +.sel b d' x x-                                in +.sel a d (f a d y) (f a d y)--Notice that the call to f is at type type "a"; a non-constant type.-Both calls to f are at the same type, so we can specialise to give:--        g a (d::Num a) (y::a) = let f@a (x::a) = +.sel a d x x-                                in +.sel a d (f@a y) (f@a y)---(b) The other case is when the type variables in the instance types-are *not* in scope at the definition point of f.  The example we are-working with above is a good case.  There are two instances of (+.sel a d),-but "a" is not in scope at the definition of +.sel.  Can we do anything?-Yes, we can "common them up", a sort of limited common sub-expression deal.-This would give:--        g a (d::Num a) (y::a) = let +.sel@a = +.sel a d-                                    f@a (x::a) = +.sel@a x x-                                in +.sel@a (f@a y) (f@a y)--This can save work, and can't be spotted by the type checker, because-the two instances of +.sel weren't originally at the same type.--Further notes on (b)--* There are quite a few variations here.  For example, the defn of-  +.sel could be floated outside the \y, to attempt to gain laziness.-  It certainly mustn't be floated outside the \d because the d has to-  be in scope too.--* We don't want to inline f_rhs in this case, because-that will duplicate code.  Just commoning up the call is the point.--* Nothing gets added to +.sel's IdInfo.--* Don't bother unless the equivalence class has more than one item!--Not clear whether this is all worth it.  It is of course OK to-simply discard call-instances when passing a big lambda.--Polymorphism 2 -- Overloading-~~~~~~~~~~~~~~-Consider a function whose most general type is--        f :: forall a b. Ord a => [a] -> b -> b--There is really no point in making a version of g at Int/Int and another-at Int/Bool, because it's only instantiating the type variable "a" which-buys us any efficiency. Since g is completely polymorphic in b there-ain't much point in making separate versions of g for the different-b types.--That suggests that we should identify which of g's type variables-are constrained (like "a") and which are unconstrained (like "b").-Then when taking equivalence classes in STEP 2, we ignore the type args-corresponding to unconstrained type variable.  In STEP 3 we make-polymorphic versions.  Thus:--        f@t1/ = /\b -> <f_rhs> t1 b d1 d2--We do this.---Dictionary floating-~~~~~~~~~~~~~~~~~~~-Consider this--        f a (d::Num a) = let g = ...-                         in-                         ...(let d1::Ord a = Num.Ord.sel a d in g a d1)...--Here, g is only called at one type, but the dictionary isn't in scope at the-definition point for g.  Usually the type checker would build a-definition for d1 which enclosed g, but the transformation system-might have moved d1's defn inward.  Solution: float dictionary bindings-outwards along with call instances.--Consider--        f x = let g p q = p==q-                  h r s = (r+s, g r s)-              in-              h x x---Before specialisation, leaving out type abstractions we have--        f df x = let g :: Eq a => a -> a -> Bool-                     g dg p q = == dg p q-                     h :: Num a => a -> a -> (a, Bool)-                     h dh r s = let deq = eqFromNum dh-                                in (+ dh r s, g deq r s)-              in-              h df x x--After specialising h we get a specialised version of h, like this:--                    h' r s = let deq = eqFromNum df-                             in (+ df r s, g deq r s)--But we can't naively make an instance for g from this, because deq is not in scope-at the defn of g.  Instead, we have to float out the (new) defn of deq-to widen its scope.  Notice that this floating can't be done in advance -- it only-shows up when specialisation is done.--User SPECIALIZE pragmas-~~~~~~~~~~~~~~~~~~~~~~~-Specialisation pragmas can be digested by the type checker, and implemented-by adding extra definitions along with that of f, in the same way as before--        f@t1/t2 = <f_rhs> t1 t2 d1 d2--Indeed the pragmas *have* to be dealt with by the type checker, because-only it knows how to build the dictionaries d1 and d2!  For example--        g :: Ord a => [a] -> [a]-        {-# SPECIALIZE f :: [Tree Int] -> [Tree Int] #-}--Here, the specialised version of g is an application of g's rhs to the-Ord dictionary for (Tree Int), which only the type checker can conjure-up.  There might not even *be* one, if (Tree Int) is not an instance of-Ord!  (All the other specialisation has suitable dictionaries to hand-from actual calls.)--Problem.  The type checker doesn't have to hand a convenient <f_rhs>, because-it is buried in a complex (as-yet-un-desugared) binding group.-Maybe we should say--        f@t1/t2 = f* t1 t2 d1 d2--where f* is the Id f with an IdInfo which says "inline me regardless!".-Indeed all the specialisation could be done in this way.-That in turn means that the simplifier has to be prepared to inline absolutely-any in-scope let-bound thing.---Again, the pragma should permit polymorphism in unconstrained variables:--        h :: Ord a => [a] -> b -> b-        {-# SPECIALIZE h :: [Int] -> b -> b #-}--We *insist* that all overloaded type variables are specialised to ground types,-(and hence there can be no context inside a SPECIALIZE pragma).-We *permit* unconstrained type variables to be specialised to-        - a ground type-        - or left as a polymorphic type variable-but nothing in between.  So--        {-# SPECIALIZE h :: [Int] -> [c] -> [c] #-}--is *illegal*.  (It can be handled, but it adds complication, and gains the-programmer nothing.)---SPECIALISING INSTANCE DECLARATIONS-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-Consider--        instance Foo a => Foo [a] where-                ...-        {-# SPECIALIZE instance Foo [Int] #-}--The original instance decl creates a dictionary-function-definition:--        dfun.Foo.List :: forall a. Foo a -> Foo [a]--The SPECIALIZE pragma just makes a specialised copy, just as for-ordinary function definitions:--        dfun.Foo.List@Int :: Foo [Int]-        dfun.Foo.List@Int = dfun.Foo.List Int dFooInt--The information about what instance of the dfun exist gets added to-the dfun's IdInfo in the same way as a user-defined function too.---Automatic instance decl specialisation?-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-Can instance decls be specialised automatically?  It's tricky.-We could collect call-instance information for each dfun, but-then when we specialised their bodies we'd get new call-instances-for ordinary functions; and when we specialised their bodies, we might get-new call-instances of the dfuns, and so on.  This all arises because of-the unrestricted mutual recursion between instance decls and value decls.--Still, there's no actual problem; it just means that we may not do all-the specialisation we could theoretically do.--Furthermore, instance decls are usually exported and used non-locally,-so we'll want to compile enough to get those specialisations done.--Lastly, there's no such thing as a local instance decl, so we can-survive solely by spitting out *usage* information, and then reading that-back in as a pragma when next compiling the file.  So for now,-we only specialise instance decls in response to pragmas.---SPITTING OUT USAGE INFORMATION-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~--To spit out usage information we need to traverse the code collecting-call-instance information for all imported (non-prelude?) functions-and data types. Then we equivalence-class it and spit it out.--This is done at the top-level when all the call instances which escape-must be for imported functions and data types.--*** Not currently done ***---Partial specialisation by pragmas-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-What about partial specialisation:--        k :: (Ord a, Eq b) => [a] -> b -> b -> [a]-        {-# SPECIALIZE k :: Eq b => [Int] -> b -> b -> [a] #-}--or even--        {-# SPECIALIZE k :: Eq b => [Int] -> [b] -> [b] -> [a] #-}--Seems quite reasonable.  Similar things could be done with instance decls:--        instance (Foo a, Foo b) => Foo (a,b) where-                ...-        {-# SPECIALIZE instance Foo a => Foo (a,Int) #-}-        {-# SPECIALIZE instance Foo b => Foo (Int,b) #-}--Ho hum.  Things are complex enough without this.  I pass.---Requirements for the simplifier-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-The simplifier has to be able to take advantage of the specialisation.--* When the simplifier finds an application of a polymorphic f, it looks in-f's IdInfo in case there is a suitable instance to call instead.  This converts--        f t1 t2 d1 d2   ===>   f_t1_t2--Note that the dictionaries get eaten up too!--* Dictionary selection operations on constant dictionaries must be-  short-circuited:--        +.sel Int d     ===>  +Int--The obvious way to do this is in the same way as other specialised-calls: +.sel has inside it some IdInfo which tells that if it's applied-to the type Int then it should eat a dictionary and transform to +Int.--In short, dictionary selectors need IdInfo inside them for constant-methods.--* Exactly the same applies if a superclass dictionary is being-  extracted:--        Eq.sel Int d   ===>   dEqInt--* Something similar applies to dictionary construction too.  Suppose-dfun.Eq.List is the function taking a dictionary for (Eq a) to-one for (Eq [a]).  Then we want--        dfun.Eq.List Int d      ===> dEq.List_Int--Where does the Eq [Int] dictionary come from?  It is built in-response to a SPECIALIZE pragma on the Eq [a] instance decl.--In short, dfun Ids need IdInfo with a specialisation for each-constant instance of their instance declaration.--All this uses a single mechanism: the SpecEnv inside an Id---What does the specialisation IdInfo look like?-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~--The SpecEnv of an Id maps a list of types (the template) to an expression--        [Type]  |->  Expr--For example, if f has this RuleInfo:--        [Int, a]  ->  \d:Ord Int. f' a--it means that we can replace the call--        f Int t  ===>  (\d. f' t)--This chucks one dictionary away and proceeds with the-specialised version of f, namely f'.---What can't be done this way?-~~~~~~~~~~~~~~~~~~~~~~~~~~~~-There is no way, post-typechecker, to get a dictionary for (say)-Eq a from a dictionary for Eq [a].  So if we find--        ==.sel [t] d--we can't transform to--        eqList (==.sel t d')--where-        eqList :: (a->a->Bool) -> [a] -> [a] -> Bool--Of course, we currently have no way to automatically derive-eqList, nor to connect it to the Eq [a] instance decl, but you-can imagine that it might somehow be possible.  Taking advantage-of this is permanently ruled out.--Still, this is no great hardship, because we intend to eliminate-overloading altogether anyway!--A note about non-tyvar dictionaries-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-Some Ids have types like--        forall a,b,c. Eq a -> Ord [a] -> tau--This seems curious at first, because we usually only have dictionary-args whose types are of the form (C a) where a is a type variable.-But this doesn't hold for the functions arising from instance decls,-which sometimes get arguments with types of form (C (T a)) for some-type constructor T.--Should we specialise wrt this compound-type dictionary?  We used to say-"no", saying:-        "This is a heuristic judgement, as indeed is the fact that we-        specialise wrt only dictionaries.  We choose *not* to specialise-        wrt compound dictionaries because at the moment the only place-        they show up is in instance decls, where they are simply plugged-        into a returned dictionary.  So nothing is gained by specialising-        wrt them."--But it is simpler and more uniform to specialise wrt these dicts too;-and in future GHC is likely to support full fledged type signatures-like-        f :: Eq [(a,b)] => ...---Note [Specialisation and overlapping instances]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-Here is at tricky case (see a comment in MR !8916):--    module A where-      class C a where-        meth :: a -> String-      instance {-# OVERLAPPABLE #-} C (Maybe a) where-        meth _ = "Maybe"--      {-# SPECIALISE f :: Maybe a -> Bool -> String #-}-      f :: C a => a -> Bool -> String-      f a True = f a False-      f a _    = meth a--    module B where-      import A--      instance C (Maybe Int) where-        meth _ = "Int"--      main = putStrLn $ f (Just 42 :: Maybe Int) True--Running main without optimisations yields "Int", the correct answer.-Activating optimisations yields "Maybe" due to a rewrite rule in module-A generated by the SPECIALISE pragma:--    RULE "USPEC f" forall a (d :: C a). f @a d = $sf--In B we get the call (f @(Maybe Int) (d :: C (Maybe Int))), and-that rewrites to $sf, but that isn't really right.--Overlapping instances mean that `C (Maybe Int)` is not a singleton-type: there two distinct dictionaries that have this type.  And that-spells trouble for specialistion, which really asssumes singleton-types.--For now, we just accept this problem, but it may bite us one day.-One solution would be to decline to expose any specialisation rules-to an importing module -- but that seems a bit drastic.---************************************************************************-*                                                                      *-\subsubsection{The new specialiser}-*                                                                      *-************************************************************************--Our basic game plan is this.  For let(rec) bound function-        f :: (C a, D c) => (a,b,c,d) -> Bool--* Find any specialised calls of f, (f ts ds), where-  ts are the type arguments t1 .. t4, and-  ds are the dictionary arguments d1 .. d2.--* Add a new definition for f1 (say):--        f1 = /\ b d -> (..body of f..) t1 b t3 d d1 d2--  Note that we abstract over the unconstrained type arguments.--* Add the mapping--        [t1,b,t3,d]  |->  \d1 d2 -> f1 b d--  to the specialisations of f.  This will be used by the-  simplifier to replace calls-                (f t1 t2 t3 t4) da db-  by-                (\d1 d1 -> f1 t2 t4) da db--  All the stuff about how many dictionaries to discard, and what types-  to apply the specialised function to, are handled by the fact that the-  SpecEnv contains a template for the result of the specialisation.--We don't build *partial* specialisations for f.  For example:--  f :: Eq a => a -> a -> Bool-  {-# SPECIALISE f :: (Eq b, Eq c) => (b,c) -> (b,c) -> Bool #-}--Here, little is gained by making a specialised copy of f.-There's a distinct danger that the specialised version would-first build a dictionary for (Eq b, Eq c), and then select the (==)-method from it!  Even if it didn't, not a great deal is saved.--We do, however, generate polymorphic, but not overloaded, specialisations:--  f :: Eq a => [a] -> b -> b -> b-  ... SPECIALISE f :: [Int] -> b -> b -> b ...--Hence, the invariant is this:--        *** no specialised version is overloaded ***---************************************************************************-*                                                                      *-\subsubsection{The exported function}-*                                                                      *-************************************************************************--}---- | Specialise calls to type-class overloaded functions occurring in a program.-specProgram :: ModGuts -> CoreM ModGuts-specProgram guts@(ModGuts { mg_module = this_mod-                          , mg_rules  = local_rules-                          , mg_binds  = binds })-  = do { dflags   <- getDynFlags-       ; rule_env <- initRuleEnv guts-                     -- See Note [Fire rules in the specialiser]--              -- We need to start with a Subst that knows all the things-              -- that are in scope, so that the substitution engine doesn't-              -- accidentally re-use a unique that's already in use-              -- Easiest thing is to do it all at once, as if all the top-level-              -- decls were mutually recursive-       ; let top_env = SE { se_subst = Core.mkEmptySubst $-                                       mkInScopeSetBndrs binds-                          , se_module = this_mod-                          , se_rules  = rule_env-                          , se_dflags = dflags }--             go []           = return ([], emptyUDs)-             go (bind:binds) = do (bind', binds', uds') <- specBind TopLevel top_env bind $ \_ ->-                                                           go binds-                                  return (bind' ++ binds', uds')--             -- Specialise the bindings of this module-       ; (binds', uds) <- runSpecM (go binds)--       ; (spec_rules, spec_binds) <- specImports top_env uds--       ; return (guts { mg_binds = spec_binds ++ binds'-                      , mg_rules = spec_rules ++ local_rules }) }--{--Note [Wrap bindings returned by specImports]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-'specImports' returns a set of specialized bindings. However, these are lacking-necessary floated dictionary bindings, which are returned by-UsageDetails(ud_binds). These dictionaries need to be brought into scope with-'wrapDictBinds' before the bindings returned by 'specImports' can be used. See,-for instance, the 'specImports' call in 'specProgram'.---Note [Disabling cross-module specialisation]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-Since GHC 7.10 we have performed specialisation of INLINABLE bindings living-in modules outside of the current module. This can sometimes uncover user code-which explodes in size when aggressively optimized. The--fno-cross-module-specialise option was introduced to allow users to being-bitten by such instances to revert to the pre-7.10 behavior.--See #10491--}---{- *********************************************************************-*                                                                      *-                   Specialising imported functions-*                                                                      *-********************************************************************* -}--{- Note [Specialising imported functions]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-specImports specialises imported functions, based on calls in this module.--When -fspecialise-aggressively is on, we specialise any imported-function for which we have an unfolding.  The--fspecialise-aggressively flag is usually off, because we risk lots of-orphan modules from over-vigorous specialisation.  (See Note [Orphans]-in GHC.Core.) However it's not a big deal: anything non-recursive with-an unfolding-template will probably have been inlined already.--When -fspecialise-aggressively is off, we are more selective about-specialisation (see canSpecImport):--(1) Without -fspecialise-aggressively, do not specialise-    DFunUnfoldings. Note [Do not specialise imported DFuns].--(2) Without -fspecialise-aggressively, specialise only imported things-    that have a /user-supplied/ INLINE or INLINABLE pragma (hence-    isAnyInlinePragma rather than isStableSource).--    In particular, we don't want to specialise workers created by-    worker/wrapper (for functions with no pragma) because they won't-    specialise usefully, and they generate quite a bit of useless code-    bloat.--    Specialise even INLINE things; it hasn't inlined yet, so perhaps-    it never will.  Moreover it may have calls inside it that we want-    to specialise--Wrinkle (W1): If we specialise an imported Id M.foo, we make a /local/-binding $sfoo.  But specImports may further specialise $sfoo. So we end up-with RULES for both M.foo (imported) and $sfoo (local).  Rules for local-Ids should be attached to the Ids themselves (see GHC.HsToCore-Note [Attach rules to local ids]); so we must partition the rules and-attach the local rules.  That is done in specImports, via addRulesToId.--Note [Glom the bindings if imported functions are specialised]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-Suppose we have an imported, *recursive*, INLINABLE function-   f :: Eq a => a -> a-   f = /\a \d x. ...(f a d)...-In the module being compiled we have-   g x = f (x::Int)-Now we'll make a specialised function-   f_spec :: Int -> Int-   f_spec = \x -> ...(f Int dInt)...-   {-# RULE  f Int _ = f_spec #-}-   g = \x. f Int dInt x-Note that f_spec doesn't look recursive-After rewriting with the RULE, we get-   f_spec = \x -> ...(f_spec)...-BUT since f_spec was non-recursive before it'll *stay* non-recursive.-The occurrence analyser never turns a NonRec into a Rec.  So we must-make sure that f_spec is recursive.  Easiest thing is to make all-the specialisations for imported bindings recursive.--}--specImports :: SpecEnv-            -> UsageDetails-            -> CoreM ([CoreRule], [CoreBind])-specImports top_env (MkUD { ud_binds = dict_binds, ud_calls = calls })-  | not $ gopt Opt_CrossModuleSpecialise (se_dflags top_env)-    -- See Note [Disabling cross-module specialisation]-  = return ([], wrapDictBinds dict_binds [])--  | otherwise-  = do { let env_w_dict_bndrs = top_env `bringFloatedDictsIntoScope` dict_binds-       ; (_env, spec_rules, spec_binds) <- spec_imports env_w_dict_bndrs [] dict_binds calls--             -- Make a Rec: see Note [Glom the bindings if imported functions are specialised]-             ---             -- wrapDictBinds: don't forget to wrap the specialized bindings with-             --   bindings for the needed dictionaries.-             --   See Note [Wrap bindings returned by specImports]-             ---             -- addRulesToId: see Wrinkle (W1) in Note [Specialising imported functions]-             --               c.f. GHC.HsToCore.addExportFlagsAndRules-       ; let (rules_for_locals, rules_for_imps) = partition isLocalRule spec_rules-             local_rule_base = extendRuleBaseList emptyRuleBase rules_for_locals-             final_binds-               | null spec_binds = wrapDictBinds dict_binds []-               | otherwise       = [Rec $ mapFst (addRulesToId local_rule_base) $-                                          flattenBinds                          $-                                          wrapDictBinds dict_binds              $-                                          spec_binds]--       ; return (rules_for_imps, final_binds)-    }---- | Specialise a set of calls to imported bindings-spec_imports :: SpecEnv          -- Passed in so that all top-level Ids are in scope-                                 ---In-scope set includes the FloatedDictBinds-             -> [Id]             -- Stack of imported functions being specialised-                                 -- See Note [specImport call stack]-             -> FloatedDictBinds -- Dict bindings, used /only/ for filterCalls-                                 -- See Note [Avoiding loops in specImports]-             -> CallDetails      -- Calls for imported things-             -> CoreM ( SpecEnv      -- Env contains the new rules-                      , [CoreRule]   -- New rules-                      , [CoreBind] ) -- Specialised bindings-spec_imports env callers dict_binds calls-  = do { let import_calls = dVarEnvElts calls---       ; debugTraceMsg (text "specImports {" <+>---                         vcat [ text "calls:" <+> ppr import_calls---                              , text "dict_binds:" <+> ppr dict_binds ])-       ; (env, rules, spec_binds) <- go env import_calls---       ; debugTraceMsg (text "End specImports }" <+> ppr import_calls)--       ; return (env, rules, spec_binds) }-  where-    go :: SpecEnv -> [CallInfoSet] -> CoreM (SpecEnv, [CoreRule], [CoreBind])-    go env [] = return (env, [], [])-    go env (cis : other_calls)-      = do {---             debugTraceMsg (text "specImport {" <+> vcat [ ppr cis---                                                         , text "callers" <+> ppr callers---                                                         , text "dict_binds" <+> ppr dict_binds ])-           ; (env, rules1, spec_binds1) <- spec_import env callers dict_binds cis---           ; debugTraceMsg (text "specImport }" <+> ppr cis)--           ; (env, rules2, spec_binds2) <- go env other_calls-           ; return (env, rules1 ++ rules2, spec_binds1 ++ spec_binds2) }--spec_import :: SpecEnv               -- Passed in so that all top-level Ids are in scope-                                     ---In-scope set includes the FloatedDictBinds-            -> [Id]                  -- Stack of imported functions being specialised-                                     -- See Note [specImport call stack]-            -> FloatedDictBinds      -- Dict bindings, used /only/ for filterCalls-                                     -- See Note [Avoiding loops in specImports]-            -> CallInfoSet           -- Imported function and calls for it-            -> CoreM ( SpecEnv-                     , [CoreRule]    -- New rules-                     , [CoreBind] )  -- Specialised bindings-spec_import env callers dict_binds cis@(CIS fn _)-  | isIn "specImport" fn callers-  = do {---         debugTraceMsg (text "specImport1-bad" <+> (ppr fn $$ text "callers" <+> ppr callers))-       ; return (env, [], []) }-    -- No warning.  This actually happens all the time-    -- when specialising a recursive function, because-    -- the RHS of the specialised function contains a recursive-    -- call to the original function--  | null good_calls-  = do {---        debugTraceMsg (text "specImport1-no-good" <+> (ppr cis $$ text "dict_binds" <+> ppr dict_binds))-       ; return (env, [], []) }--  | Just rhs <- canSpecImport dflags fn-  = do {     -- Get rules from the external package state-             -- We keep doing this in case we "page-fault in"-             -- more rules as we go along-       ; eps_rules <- getExternalRuleBase-       ; let rule_env = se_rules env `updExternalPackageRules` eps_rules----       ; debugTraceMsg (text "specImport1" <+> vcat---           [ text "function:" <+> ppr fn---           , text "good calls:" <+> ppr good_calls---           , text "existing rules:" <+> ppr (getRules rule_env fn)---           , text "rhs:" <+> ppr rhs---           , text "dict_binds:" <+> ppr dict_binds ])--       ; (rules1, spec_pairs, MkUD { ud_binds = dict_binds1, ud_calls = new_calls })-            <- runSpecM $ specCalls True env (getRules rule_env fn) good_calls fn rhs--       ; let spec_binds1 = [NonRec b r | (b,r) <- spec_pairs]-             -- After the rules kick in, via fireRewriteRules, we may get recursion,-             -- but we rely on a global GlomBinds to sort that out later-             -- See Note [Glom the bindings if imported functions are specialised]-             -- Meanwhile, though, bring the binders into scope--             new_subst = se_subst env `Core.extendSubstInScopeList` map fst spec_pairs-             new_env   = env { se_rules = rule_env `addLocalRules` rules1-                             , se_subst = new_subst }-                         `bringFloatedDictsIntoScope` dict_binds1--       -- Now specialise any cascaded calls---       ; debugTraceMsg (text "specImport 2" <+> vcat---           [ text "function:" <+> ppr fn---           , text "rules1:" <+> ppr rules1---           , text "spec_binds1" <+> ppr spec_binds1---           , text "dict_binds1" <+> ppr dict_binds1---           , text "new_calls" <+> ppr new_calls ])--       ; (env, rules2, spec_binds2)-            <- spec_imports new_env (fn:callers)-                                    (dict_binds `thenFDBs` dict_binds1)-                                    new_calls--       ; let final_binds = wrapDictBinds dict_binds1 $-                           spec_binds2 ++ spec_binds1--       ; return (env, rules2 ++ rules1, final_binds) }--  | otherwise-  = do {---         debugTraceMsg (hang (text "specImport1-missed")---                          2 (vcat [ppr cis, text "can-spec" <+> ppr (canSpecImport dflags fn)]))-       ; tryWarnMissingSpecs dflags callers fn good_calls-       ; return (env, [], [])}--  where-    dflags = se_dflags env-    good_calls = filterCalls cis dict_binds-       -- SUPER IMPORTANT!  Drop calls that (directly or indirectly) refer to fn-       -- See Note [Avoiding loops in specImports]--canSpecImport :: DynFlags -> Id -> Maybe CoreExpr-canSpecImport dflags fn-  | isDataConWrapId fn-  = Nothing   -- Don't specialise data-con wrappers, even if they-              -- have dict args; there is no benefit.--  | CoreUnfolding { uf_tmpl = rhs } <- unf-    -- CoreUnfolding: see Note [Specialising imported functions] point (1).-  , isAnyInlinePragma (idInlinePragma fn)-    -- See Note [Specialising imported functions] point (2).-  = Just rhs--  | gopt Opt_SpecialiseAggressively dflags-  = maybeUnfoldingTemplate unf-    -- With -fspecialise-aggressively, specialise anything-    -- with an unfolding, stable or not, DFun or not--  | otherwise = Nothing-  where-    unf = realIdUnfolding fn   -- We want to see the unfolding even for loop breakers---- | Returns whether or not to show a missed-spec warning.--- If -Wall-missed-specializations is on, show the warning.--- Otherwise, if -Wmissed-specializations is on, only show a warning--- if there is at least one imported function being specialized,--- and if all imported functions are marked with an inline pragma--- Use the most specific warning as the reason.-tryWarnMissingSpecs :: DynFlags -> [Id] -> Id -> [CallInfo] -> CoreM ()--- See Note [Warning about missed specialisations]-tryWarnMissingSpecs dflags callers fn calls_for_fn-  | isClassOpId fn = return () -- See Note [Missed specialisation for ClassOps]-  | wopt Opt_WarnMissedSpecs dflags-    && not (null callers)-    && allCallersInlined                  = doWarn $ WarningWithFlag Opt_WarnMissedSpecs-  | wopt Opt_WarnAllMissedSpecs dflags    = doWarn $ WarningWithFlag Opt_WarnAllMissedSpecs-  | otherwise                             = return ()-  where-    allCallersInlined = all (isAnyInlinePragma . idInlinePragma) callers-    diag_opts = initDiagOpts dflags-    doWarn reason =-      msg (mkMCDiagnostic diag_opts reason Nothing)-        (vcat [ hang (text ("Could not specialise imported function") <+> quotes (ppr fn))-                2 (vcat [ text "when specialising" <+> quotes (ppr caller)-                        | caller <- callers])-          , whenPprDebug (text "calls:" <+> vcat (map (pprCallInfo fn) calls_for_fn))-          , text "Probable fix: add INLINABLE pragma on" <+> quotes (ppr fn) ])--{- Note [Missed specialisation for ClassOps]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-In #19592 I saw a number of missed specialisation warnings-which were the result of things like:--    case isJumpishInstr @X86.Instr $dInstruction_s7f8 eta3_a78C of { ...--where isJumpishInstr is part of the Instruction class and defined like-this:--    class Instruction instr where-        ...-        isJumpishInstr :: instr -> Bool-        ...--isJumpishInstr is a ClassOp which will select the right method-from within the dictionary via our built in rules. See also-Note [ClassOp/DFun selection] in GHC.Tc.TyCl.Instance.--We don't give these unfoldings, and as a result the specialiser-complains. But usually this doesn't matter. The simplifier will-apply the rule and we end up with--    case isJumpishInstrImplX86 eta3_a78C of { ...--Since isJumpishInstrImplX86 is defined for a concrete instance (given-by the dictionary) it is usually already well specialised!-Theoretically the implementation of a method could still be overloaded-over a different type class than what it's a method of. But I wasn't able-to make this go wrong, and SPJ thinks this should be fine as well.--So I decided to remove the warnings for failed specialisations on ClassOps-alltogether as they do more harm than good.--}--{- Note [Do not specialise imported DFuns]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-Ticket #18223 shows that specialising calls of DFuns is can cause a huge-and entirely unnecessary blowup in program size.  Consider a call to-    f @[[[[[[[[T]]]]]]]] d1 x-where df :: C a => C [a]-      d1 :: C [[[[[[[[T]]]]]]]] = dfC[] @[[[[[[[T]]]]]]] d1-      d2 :: C [[[[[[[T]]]]]]]   = dfC[] @[[[[[[T]]]]]] d3-      ...-Now we'll specialise f's RHS, which may give rise to calls to 'g',-also overloaded, which we will specialise, and so on.  However, if-we specialise the calls to dfC[], we'll generate specialised copies of-all methods of C, at all types; and the same for C's superclasses.--And many of these specialised functions will never be called.  We are-going to call the specialised 'f', and the specialised 'g', but DFuns-group functions into a tuple, many of whose elements may never be used.--With deeply-nested types this can lead to a simply overwhelming number-of specialisations: see #18223 for a simple example (from the wild).-I measured the number of specialisations for various numbers of calls-of `flip evalStateT ()`, and got this--                       Size after one simplification-  #calls    #SPEC rules    Terms     Types-      5         56          3100     10600-      9        108         13660     77206--The real tests case has 60+ calls, which blew GHC out of the water.--Solution: don't specialise DFuns.  The downside is that if we end-up with (h (dfun d)), /and/ we don't specialise 'h', then we won't-pass to 'h' a tuple of specialised functions.--However, the flag -fspecialise-aggressively (experimental, off by default)-allows DFuns to specialise as well.--Note [Avoiding loops in specImports]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-We must take great care when specialising instance declarations-(DFuns like $fOrdList) lest we accidentally build a recursive-dictionary. See Note [Avoiding loops (DFuns)].--The basic strategy of Note [Avoiding loops (DFuns)] is to use filterCalls-to discard loopy specialisations.  But to do that we must ensure-that the in-scope dict-binds (passed to filterCalls) contains-all the needed dictionary bindings.  In particular, in the recursive-call to spec_imports in spec_import, we must include the dict-binds-from the parent.  Lacking this caused #17151, a really nasty bug.--Here is what happened.-* Class structure:-    Source is a superclass of Mut-    Index is a superclass of Source--* We started with these dict binds-    dSource = $fSourcePix @Int $fIndexInt-    dIndex  = sc_sel dSource-    dMut    = $fMutPix @Int dIndex-  and these calls to specialise-    $fMutPix @Int dIndex-    $fSourcePix @Int $fIndexInt--* We specialised the call ($fMutPix @Int dIndex)-  ==> new call ($fSourcePix @Int dIndex)-      (because Source is a superclass of Mut)--* We specialised ($fSourcePix @Int dIndex)-  ==> produces specialised dict $s$fSourcePix,-      a record with dIndex as a field-      plus RULE forall d. ($fSourcePix @Int d) = $s$fSourcePix-  *** This is the bogus step ***--* Now we decide not to specialise the call-    $fSourcePix @Int $fIndexInt-  because we alredy have a RULE that matches it--* Finally the simplifer rewrites-    dSource = $fSourcePix @Int $fIndexInt-    ==>  dSource = $s$fSourcePix--Disaster. Now we have--Rewrite dSource's RHS to $s$fSourcePix   Disaster-    dSource = $s$fSourcePix-    dIndex  = sc_sel dSource-    $s$fSourcePix = MkSource dIndex ...--Solution: filterCalls should have stopped the bogus step,-by seeing that dIndex transitively uses $fSourcePix. But-it can only do that if it sees all the dict_binds.  Wow.-----------------Here's another example (#13429).  Suppose we have-  class Monoid v => C v a where ...--We start with a call-   f @ [Integer] @ Integer $fC[]Integer--Specialising call to 'f' gives dict bindings-   $dMonoid_1 :: Monoid [Integer]-   $dMonoid_1 = M.$p1C @ [Integer] $fC[]Integer--   $dC_1 :: C [Integer] (Node [Integer] Integer)-   $dC_1 = M.$fCvNode @ [Integer] $dMonoid_1--...plus a recursive call to-   f @ [Integer] @ (Node [Integer] Integer) $dC_1--Specialising that call gives-   $dMonoid_2  :: Monoid [Integer]-   $dMonoid_2  = M.$p1C @ [Integer] $dC_1--   $dC_2 :: C [Integer] (Node [Integer] Integer)-   $dC_2 = M.$fCvNode @ [Integer] $dMonoid_2--Now we have two calls to the imported function-  M.$fCvNode :: Monoid v => C v a-  M.$fCvNode @v @a m = C m some_fun--But we must /not/ use the call (M.$fCvNode @ [Integer] $dMonoid_2)-for specialisation, else we get:--  $dC_1 = M.$fCvNode @ [Integer] $dMonoid_1-  $dMonoid_2 = M.$p1C @ [Integer] $dC_1-  $s$fCvNode = C $dMonoid_2 ...-    RULE M.$fCvNode [Integer] _ _ = $s$fCvNode--Now use the rule to rewrite the call in the RHS of $dC_1-and we get a loop!---Note [specImport call stack]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-When specialising an imports function 'f', we may get new calls-of an imported function 'g', which we want to specialise in turn,-and similarly specialising 'g' might expose a new call to 'h'.--We track the stack of enclosing functions. So when specialising 'h' we-have a specImport call stack of [g,f]. We do this for two reasons:-* Note [Warning about missed specialisations]-* Note [Avoiding recursive specialisation]--Note [Warning about missed specialisations]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-Suppose- * In module Lib, you carefully mark a function 'foo' INLINABLE- * Import Lib(foo) into another module M- * Call 'foo' at some specialised type in M-Then you jolly well expect it to be specialised in M.  But what if-'foo' calls another function 'Lib.bar'.  Then you'd like 'bar' to be-specialised too.  But if 'bar' is not marked INLINABLE it may well-not be specialised.  The warning Opt_WarnMissedSpecs warns about this.--It's more noisy to warning about a missed specialisation opportunity-for /every/ overloaded imported function, but sometimes useful. That-is what Opt_WarnAllMissedSpecs does.--ToDo: warn about missed opportunities for local functions.--Note [Avoiding recursive specialisation]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-When we specialise 'f' we may find new overloaded calls to 'g', 'h' in-'f's RHS.  So we want to specialise g,h.  But we don't want to-specialise f any more!  It's possible that f's RHS might have a-recursive yet-more-specialised call, so we'd diverge in that case.-And if the call is to the same type, one specialisation is enough.-Avoiding this recursive specialisation loop is one reason for the-'callers' stack passed to specImports and specImport.---************************************************************************-*                                                                      *-\subsubsection{@specExpr@: the main function}-*                                                                      *-************************************************************************--}--data SpecEnv-  = SE { se_subst :: Core.Subst-             -- We carry a substitution down:-             -- a) we must clone any binding that might float outwards,-             --    to avoid name clashes-             -- b) we carry a type substitution to use when analysing-             --    the RHS of specialised bindings (no type-let!)--       , se_module :: Module-       , se_rules  :: RuleEnv  -- From the home package and this module-       , se_dflags :: DynFlags-     }--instance Outputable SpecEnv where-  ppr (SE { se_subst = subst })-    = text "SE" <+> braces (text "subst =" <+> ppr subst)--specVar :: SpecEnv -> InId -> SpecM (OutExpr, UsageDetails)-specVar env@(SE { se_subst = Core.Subst in_scope ids _ _ }) v-  | not (isLocalId v)                   = return (Var v, emptyUDs)-  | Just e  <- lookupVarEnv ids       v = specExpr (zapSubst env) e  -- Note (1)-  | Just v' <- lookupInScope in_scope v = return (Var v', emptyUDs)-  | otherwise = pprPanic "specVar" (ppr v $$ ppr in_scope)-  -- c.f. GHC.Core.Subst.lookupIdSubst-  -- Note (1): we recurse so we do the lookupInScope thing on any Vars in e-  --           probably has little effect, but it's the right thing.-  --           We need zapSubst because `e` is an OutExpr--specExpr :: SpecEnv -> CoreExpr -> SpecM (CoreExpr, UsageDetails)------------------ First the easy cases ---------------------specExpr env (Var v)       = specVar env v-specExpr env (Type ty)     = return (Type     (substTy env ty), emptyUDs)-specExpr env (Coercion co) = return (Coercion (substCo env co), emptyUDs)-specExpr _   (Lit lit)     = return (Lit lit,                   emptyUDs)-specExpr env (Cast e co)-  = do { (e', uds) <- specExpr env e-       ; return ((mkCast e' (substCo env co)), uds) }-specExpr env (Tick tickish body)-  = do { (body', uds) <- specExpr env body-       ; return (Tick (specTickish env tickish) body', uds) }------------------ Applications might generate a call instance ---------------------specExpr env expr@(App {})-  = do { let (fun_in, args_in) = collectArgs expr-       ; (args_out, uds_args) <- mapAndCombineSM (specExpr env) args_in-       ; let env_args = env `bringFloatedDictsIntoScope` ud_binds uds_args-                -- Some dicts may have floated out of args_in;-                -- they should be in scope for fireRewriteRules (#21689)-             (fun_in', args_out') = fireRewriteRules env_args fun_in args_out-       ; (fun_out', uds_fun) <- specExpr env fun_in'-       ; let uds_call = mkCallUDs env fun_out' args_out'-       ; return (fun_out' `mkApps` args_out', uds_fun `thenUDs` uds_call `thenUDs` uds_args) }------------------ Lambda/case require dumping of usage details ---------------------specExpr env e@(Lam {})-  = specLam env' bndrs' body-  where-    (bndrs, body)  = collectBinders e-    (env', bndrs') = substBndrs env bndrs-        -- More efficient to collect a group of binders together all at once-        -- and we don't want to split a lambda group with dumped bindings--specExpr env (Case scrut case_bndr ty alts)-  = do { (scrut', scrut_uds) <- specExpr env scrut-       ; (scrut'', case_bndr', alts', alts_uds)-             <- specCase env scrut' case_bndr alts---       ; pprTrace "specExpr:case" (vcat---            [ text "scrut" <+> ppr scrut, text "scrut'" <+> ppr scrut'---            , text "case_bndr'" <+> ppr case_bndr'---            , text "alts_uds" <+> ppr alts_uds---            ])-       ; return (Case scrut'' case_bndr' (substTy env ty) alts'-                , scrut_uds `thenUDs` alts_uds) }------------------ Finally, let is the interesting case ---------------------specExpr env (Let bind body)-  = do { (binds', body', uds) <- specBind NotTopLevel env bind $ \body_env ->-                                 -- pprTrace "specExpr:let" (ppr (se_subst body_env) $$ ppr body) $-                                 specExpr body_env body-         -- All done-       ; return (foldr Let body' binds', uds) }---- See Note [Specialisation modulo dictionary selectors]---     Note [ClassOp/DFun selection]---     Note [Fire rules in the specialiser]-fireRewriteRules :: SpecEnv -> InExpr -> [OutExpr] -> (InExpr, [OutExpr])-fireRewriteRules env (Var f) args-  | Just (rule, expr) <- specLookupRule env f args InitialPhase (getRules (se_rules env) f)-  , let rest_args    = drop (ruleArity rule) args -- See Note [Extra args in the target]-        zapped_subst = Core.zapSubst (se_subst env)-        expr'        = simpleOptExprWith defaultSimpleOpts zapped_subst expr-                       -- simplOptExpr needed because lookupRule returns-                       --   (\x y. rhs) arg1 arg2-  , (fun, args) <- collectArgs expr'-  = fireRewriteRules env fun (args++rest_args)-fireRewriteRules _ fun args = (fun, args)-----------------specLam :: SpecEnv -> [OutBndr] -> InExpr -> SpecM (OutExpr, UsageDetails)--- The binders have been substituted, but the body has not-specLam env bndrs body-  | null bndrs-  = specExpr env body-  | otherwise-  = do { (body', uds) <- specExpr env body-       ; let (free_uds, dumped_dbs) = dumpUDs bndrs uds-       ; return (mkLams bndrs (wrapDictBindsE dumped_dbs body'), free_uds) }-----------------specTickish :: SpecEnv -> CoreTickish -> CoreTickish-specTickish (SE { se_subst = subst }) bp = substTickish subst bp-----------------specCase :: SpecEnv-         -> OutExpr             -- Scrutinee, already done-         -> InId -> [InAlt]-         -> SpecM ( OutExpr     -- New scrutinee-                  , OutId-                  , [OutAlt]-                  , UsageDetails)-specCase env scrut' case_bndr [Alt con args rhs]-  | -- See Note [Floating dictionaries out of cases]-    interestingDict scrut' (idType case_bndr)-  , not (isDeadBinder case_bndr && null sc_args')-  = do { case_bndr_flt :| sc_args_flt <- mapM clone_me (case_bndr' :| sc_args')--       ; let case_bndr_flt' = case_bndr_flt `addDictUnfolding` scrut'-             scrut_bind     = mkDB (NonRec case_bndr_flt scrut')--             sc_args_flt' = zipWith addDictUnfolding sc_args_flt sc_rhss-             sc_rhss      = [ Case (Var case_bndr_flt') case_bndr' (idType sc_arg')-                                   [Alt con args' (Var sc_arg')]-                            | sc_arg' <- sc_args' ]-             cb_set       = unitVarSet case_bndr_flt'-             sc_binds     = [ DB { db_bind = NonRec sc_arg_flt sc_rhs, db_fvs  = cb_set }-                            | (sc_arg_flt, sc_rhs) <- sc_args_flt' `zip` sc_rhss ]--             flt_binds    = scrut_bind : sc_binds--             -- Extend the substitution for RHS to map the *original* binders-             -- to their floated versions.-             mb_sc_flts :: [Maybe DictId]-             mb_sc_flts = map (lookupVarEnv clone_env) args'-             clone_env  = zipVarEnv sc_args' sc_args_flt'--             subst_prs  = (case_bndr, Var case_bndr_flt)-                        : [ (arg, Var sc_flt)-                          | (arg, Just sc_flt) <- args `zip` mb_sc_flts ]-             subst'   = se_subst env_rhs-                        `Core.extendSubstInScopeList` (case_bndr_flt' : sc_args_flt')-                        `Core.extendIdSubstList`      subst_prs-             env_rhs' = env_rhs { se_subst = subst' }--       ; (rhs', rhs_uds)   <- specExpr env_rhs' rhs-       ; let (free_uds, dumped_dbs) = dumpUDs (case_bndr':args') rhs_uds-             all_uds = flt_binds `consDictBinds` free_uds-             alt'    = Alt con args' (wrapDictBindsE dumped_dbs rhs')---       ; pprTrace "specCase" (ppr case_bndr $$ ppr scrut_bind) $-       ; return (Var case_bndr_flt, case_bndr', [alt'], all_uds) }-  where-    (env_rhs, (case_bndr':args')) = substBndrs env (case_bndr:args)-    sc_args' = filter is_flt_sc_arg args'--    clone_me bndr = do { uniq <- getUniqueM-                       ; return (mkUserLocalOrCoVar occ uniq wght ty loc) }-       where-         name = idName bndr-         wght = idMult bndr-         ty   = idType bndr-         occ  = nameOccName name-         loc  = getSrcSpan name--    arg_set = mkVarSet args'-    is_flt_sc_arg var =  isId var-                      && not (isDeadBinder var)-                      && isDictTy var_ty-                      && tyCoVarsOfType var_ty `disjointVarSet` arg_set-       where-         var_ty = idType var---specCase env scrut case_bndr alts-  = do { (alts', uds_alts) <- mapAndCombineSM spec_alt alts-       ; return (scrut, case_bndr', alts', uds_alts) }-  where-    (env_alt, case_bndr') = substBndr env case_bndr-    spec_alt (Alt con args rhs)-      = do { (rhs', uds) <- specExpr env_rhs rhs-           ; let (free_uds, dumped_dbs) = dumpUDs (case_bndr' : args') uds---           ; unless (isNilOL dumped_dbs) $---             pprTrace "specAlt" (vcat---                 [text "case_bndr', args" <+> (ppr case_bndr' $$ ppr args)---                 ,text "dumped" <+> ppr dumped_dbs ]) return ()-           ; return (Alt con args' (wrapDictBindsE dumped_dbs rhs'), free_uds) }-        where-          (env_rhs, args') = substBndrs env_alt args--{- Note [Fire rules in the specialiser]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-Consider this (#21851)--    module A where-      f :: Num b => b -> (b, b)-      f x = (x + 1, snd (f x))-      {-# SPECIALIZE f :: Int -> (Int, Int) #-}--    module B (g') where-      import A--      g :: Num a => a -> a-      g x = fst (f x)-      {-# NOINLINE[99] g #-}--      h :: Int -> Int-      h = g--Note that `f` has the CPR property, and so will worker/wrapper.--The call to `g` in `h` will make us specialise `g @Int`. And the specialised-version of `g` will contain the call `f @Int`; but in the subsequent run of-the Simplifier, there will be a competition between:-* The user-supplied SPECIALISE rule for `f`-* The inlining of the wrapper for `f`-In fact, the latter wins -- see Note [Rewrite rules and inlining] in-GHC.Core.Opt.Simplify.Iteration.  However, it a bit fragile.--Moreover consider (test T21851_2):--    module A-      f :: (Ord a, Show b) => a -> b -> blah-      {-# RULE forall b. f @Int @b = wombat #-}--      wombat :: Show b => Int -> b -> blah-      wombat = blah--    module B-      import A-      g :: forall a. Ord a => blah-      g @a = ...g...f @a @Char....--      h = ....g @Int....--Now, in module B, GHC will specialise `g @Int`, which will lead to a-call `f @Int @Char`.  If we immediately (in the specialiser) rewrite-that to `womabat @Char`, we have a chance to specialise `wombat`.--Conclusion: it's treat if the Specialiser fires RULEs itself.-It's not hard to achieve: see `fireRewriteRules`. The only tricky bit is-making sure that we have a reasonably up to date EPS rule base. Currently-we load it up just once, in `initRuleEnv`, called at the beginning of-`specProgram`.--NB: you might wonder if running rules in the specialiser (this Note)-renders Note [Rewrite rules and inlining] in the Simplifier redundant.-That is, if we run rules in the specialiser, does it matter if we make-rules "win" over inlining in the Simplifier?  Yes, it does!  See the-discussion in #21851.--Note [Floating dictionaries out of cases]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-Consider-   g = \d. case d of { MkD sc ... -> ...(f sc)... }-Naively we can't float d2's binding out of the case expression,-because 'sc' is bound by the case, and that in turn means we can't-specialise f, which seems a pity.--So we invert the case, by floating out a binding-for 'sc_flt' thus:-    sc_flt = case d of { MkD sc ... -> sc }-Now we can float the call instance for 'f'.  Indeed this is just-what'll happen if 'sc' was originally bound with a let binding,-but case is more efficient, and necessary with equalities. So it's-good to work with both.--You might think that this won't make any difference, because the-call instance will only get nuked by the \d.  BUT if 'g' itself is-specialised, then transitively we should be able to specialise f.--In general, given-   case e of cb { MkD sc ... -> ...(f sc)... }-we transform to-   let cb_flt = e-       sc_flt = case cb_flt of { MkD sc ... -> sc }-   in-   case cb_flt of bg { MkD sc ... -> ....(f sc_flt)... }--The "_flt" things are the floated binds; we use the current substitution-to substitute sc -> sc_flt in the RHS--************************************************************************-*                                                                      *-                     Dealing with a binding-*                                                                      *-************************************************************************--}--bringFloatedDictsIntoScope :: SpecEnv -> FloatedDictBinds -> SpecEnv-bringFloatedDictsIntoScope env (FDB { fdb_bndrs = dx_bndrs })-  = -- pprTrace "brought into scope" (ppr dx_bndrs) $-    env {se_subst=subst'}-  where-   subst' = se_subst env `Core.extendSubstInScopeSet` dx_bndrs--specBind :: TopLevelFlag-         -> SpecEnv    -- At top-level only, this env already has the-                       -- top level binders in scope-         -> InBind-         -> (SpecEnv -> SpecM (body, UsageDetails))    -- Process the body-         -> SpecM ( [OutBind]           -- New bindings-                  , body                -- Body-                  , UsageDetails)       -- And info to pass upstream---- Returned UsageDetails:---    No calls for binders of this bind-specBind top_lvl env (NonRec fn rhs) do_body-  = do { (rhs', rhs_uds) <- specExpr env rhs--       ; (body_env1, fn1) <- case top_lvl of-                               TopLevel    -> return (env, fn)-                               NotTopLevel -> cloneBndrSM env fn--       ; let fn2 | isStableUnfolding (idUnfolding fn1) = fn1-                 | otherwise = fn1 `setIdUnfolding` mkSimpleUnfolding defaultUnfoldingOpts rhs'-             -- Update the unfolding with the perhaps-simpler or more specialised rhs'-             -- This is important: see Note [Update unfolding after specialisation]-             -- And in any case cloneBndrSM discards non-Stable unfoldings--             fn3 = floatifyIdDemandInfo fn2-             -- We zap the demand info because the binding may float,-             -- which would invalidate the demand info (see #17810 for example).-             -- Destroying demand info is not terrible; specialisation is-             -- always followed soon by demand analysis.-             -- See Note [Floatifying demand info when floating] in GHC.Core.Opt.SetLevels--             body_env2 = body_env1 `bringFloatedDictsIntoScope` ud_binds rhs_uds-                                   `extendInScope` fn3-                                   -- bringFloatedDictsIntoScope: see #23567--       ; (body', body_uds) <- do_body body_env2--       ; (fn4, spec_defns, body_uds1) <- specDefn env body_uds fn3 rhs--       ; let can_float_this_one = exprIsTopLevelBindable rhs (idType fn)-                 -- exprIsTopLevelBindable: see Note [Care with unlifted bindings]-             (free_uds, dump_dbs, float_all) = dumpBindUDs can_float_this_one [fn4] body_uds1-             all_free_uds                    = free_uds `thenUDs` rhs_uds--             pairs = spec_defns ++ [(fn4, rhs')]-                        -- fn4 mentions the spec_defns in its rules,-                        -- so put the latter first--             final_binds :: [DictBind]-             -- See Note [From non-recursive to recursive]-             final_binds | not (isNilOL dump_dbs)-                         , not (null spec_defns)-                         = [recWithDumpedDicts pairs dump_dbs]-                         | otherwise-                         = [mkDB $ NonRec b r | (b,r) <- pairs]-                           ++ fromOL dump_dbs---       ; if float_all then-             -- Rather than discard the calls mentioning the bound variables-             -- we float this (dictionary) binding along with the others-              return ([], body', all_free_uds `snocDictBinds` final_binds)-         else-             -- No call in final_uds mentions bound variables,-             -- so we can just leave the binding here-              return (map db_bind final_binds, body', all_free_uds) }---specBind top_lvl env (Rec pairs) do_body-       -- Note [Specialising a recursive group]-  = do { let (bndrs,rhss) = unzip pairs--       ; (rec_env, bndrs1) <- case top_lvl of-                                 TopLevel    -> return (env, bndrs)-                                 NotTopLevel -> cloneRecBndrsSM env bndrs--       ; (rhss', rhs_uds)  <- mapAndCombineSM (specExpr rec_env) rhss-       ; (body', body_uds) <- do_body rec_env--       ; let scope_uds = body_uds `thenUDs` rhs_uds-                       -- Includes binds and calls arising from rhss--       ; (bndrs2, spec_defns2, uds2) <- specDefns rec_env scope_uds (bndrs1 `zip` rhss)-         -- bndrs2 is like bndrs1, but with RULES added--       ; (bndrs3, spec_defns3, uds3)-             <- if null spec_defns2  -- Common case: no specialisation-                then return (bndrs2, [], uds2)-                else do {            -- Specialisation occurred; do it again-                          (bndrs3, spec_defns3, uds3)-                              <- specDefns rec_env uds2 (bndrs2 `zip` rhss)-                        ; return (bndrs3, spec_defns3 ++ spec_defns2, uds3) }--       ; let (final_uds, dumped_dbs, float_all) = dumpBindUDs True bndrs1 uds3-             final_bind = recWithDumpedDicts (spec_defns3 ++ zip bndrs3 rhss')-                                             dumped_dbs--       ; if float_all then-              return ([], body', final_uds `snocDictBind` final_bind)-         else-              return ([db_bind final_bind], body', final_uds) }-------------------------------specDefns :: SpecEnv-          -> UsageDetails               -- Info on how it is used in its scope-          -> [(OutId,InExpr)]           -- The things being bound and their un-processed RHS-          -> SpecM ([OutId],            -- Original Ids with RULES added-                    [(OutId,OutExpr)],  -- Extra, specialised bindings-                    UsageDetails)       -- Stuff to fling upwards from the specialised versions---- Specialise a list of bindings (the contents of a Rec), but flowing usages--- upwards binding by binding.  Example: { f = ...g ...; g = ...f .... }--- Then if the input CallDetails has a specialised call for 'g', whose specialisation--- in turn generates a specialised call for 'f', we catch that in this one sweep.--- But not vice versa (it's a fixpoint problem).--specDefns _env uds []-  = return ([], [], uds)-specDefns env uds ((bndr,rhs):pairs)-  = do { (bndrs1, spec_defns1, uds1) <- specDefns env uds  pairs-       ; (bndr1, spec_defns2, uds2)  <- specDefn  env uds1 bndr rhs-       ; return (bndr1 : bndrs1, spec_defns1 ++ spec_defns2, uds2) }------------------------------specDefn :: SpecEnv-         -> UsageDetails                -- Info on how it is used in its scope-         -> OutId -> InExpr             -- The thing being bound and its un-processed RHS-         -> SpecM (Id,                  -- Original Id with added RULES-                   [(Id,CoreExpr)],     -- Extra, specialised bindings-                   UsageDetails)        -- Stuff to fling upwards from the specialised versions--specDefn env body_uds fn rhs-  = do { let (body_uds_without_me, calls_for_me) = callsForMe fn body_uds-             rules_for_me = idCoreRules fn-             -- Bring into scope the binders from the floated dicts-             env_w_dict_bndrs = bringFloatedDictsIntoScope env (ud_binds body_uds)--       ; (rules, spec_defns, spec_uds) <- specCalls False env_w_dict_bndrs-                                                    rules_for_me calls_for_me fn rhs--       ; return ( fn `addIdSpecialisations` rules-                , spec_defns-                , body_uds_without_me `thenUDs` spec_uds) }-                -- It's important that the `thenUDs` is this way-                -- round, because body_uds_without_me may bind-                -- dictionaries that are used in calls_for_me passed-                -- to specDefn.  So the dictionary bindings in-                -- spec_uds may mention dictionaries bound in-                -- body_uds_without_me------------------------------specCalls :: Bool              -- True  =>  specialising imported fn-                               -- False =>  specialising local fn-          -> SpecEnv-          -> [CoreRule]        -- Existing RULES for the fn-          -> [CallInfo]-          -> OutId -> InExpr-          -> SpecM SpecInfo    -- New rules, specialised bindings, and usage details---- This function checks existing rules, and does not create--- duplicate ones. So the caller does not need to do this filtering.--- See 'already_covered'--type SpecInfo = ( [CoreRule]       -- Specialisation rules-                , [(Id,CoreExpr)]  -- Specialised definition-                , UsageDetails )   -- Usage details from specialised RHSs--specCalls spec_imp env existing_rules calls_for_me fn rhs-        -- The first case is the interesting one-  |  notNull calls_for_me               -- And there are some calls to specialise-  && not (isNeverActive (idInlineActivation fn))-        -- Don't specialise NOINLINE things-        -- See Note [Auto-specialisation and RULES]-        ---        -- Don't specialise OPAQUE things, see Note [OPAQUE pragma].-        -- Since OPAQUE things are always never-active (see-        -- GHC.Parser.PostProcess.mkOpaquePragma) this guard never fires for-        -- OPAQUE things.----   && not (certainlyWillInline (idUnfolding fn))      -- And it's not small---      See Note [Inline specialisations] for why we do not---      switch off specialisation for inline functions--  = -- pprTrace "specCalls: some" (vcat-    --   [ text "function" <+> ppr fn-    --   , text "calls:" <+> ppr calls_for_me-    --   , text "subst" <+> ppr (se_subst env) ]) $-    foldlM spec_call ([], [], emptyUDs) calls_for_me--  | otherwise   -- No calls or RHS doesn't fit our preconceptions-  = warnPprTrace (not (exprIsTrivial rhs) && notNull calls_for_me && not (isClassOpId fn))-          "Missed specialisation opportunity for" (ppr fn $$ trace_doc) $-          -- isClassOpId: class-op Ids never inline; we specialise them-          -- through fireRewriteRules. So don't complain about missed opportunities-          -- Note [Specialisation shape]-    -- pprTrace "specCalls: none" (ppr fn <+> ppr calls_for_me) $-    return ([], [], emptyUDs)-  where-    trace_doc = sep [ ppr rhs_bndrs, ppr (idInlineActivation fn) ]--    fn_type   = idType fn-    fn_arity  = idArity fn-    fn_unf    = realIdUnfolding fn  -- Ignore loop-breaker-ness here-    inl_prag  = idInlinePragma fn-    inl_act   = inlinePragmaActivation inl_prag-    is_local  = isLocalId fn-    is_dfun   = isDFunId fn-    dflags    = se_dflags env-    this_mod  = se_module env-        -- Figure out whether the function has an INLINE pragma-        -- See Note [Inline specialisations]--    (rhs_bndrs, rhs_body) = collectBindersPushingCo rhs-                            -- See Note [Account for casts in binding]--    already_covered :: SpecEnv -> [CoreRule] -> [CoreExpr] -> Bool-    already_covered env new_rules args      -- Note [Specialisations already covered]-       = isJust (specLookupRule env fn args (beginPhase inl_act)-                                (new_rules ++ existing_rules))-         -- Rules: we look both in the new_rules (generated by this invocation-         --   of specCalls), and in existing_rules (passed in to specCalls)-         -- inl_act: is the activation we are going to put in the new SPEC-         --   rule; so we want to see if it is covered by another rule with-         --   that same activation.--    -----------------------------------------------------------        -- Specialise to one particular call pattern-    spec_call :: SpecInfo                         -- Accumulating parameter-              -> CallInfo                         -- Call instance-              -> SpecM SpecInfo-    spec_call spec_acc@(rules_acc, pairs_acc, uds_acc) _ci@(CI { ci_key = call_args })-      = -- See Note [Specialising Calls]-        do { let all_call_args | is_dfun   = saturating_call_args -- See Note [Specialising DFuns]-                               | otherwise = call_args-                 saturating_call_args = call_args ++ map mk_extra_dfun_arg (dropList call_args rhs_bndrs)-                 mk_extra_dfun_arg bndr | isTyVar bndr = UnspecType-                                        | otherwise = UnspecArg--           ; ( useful, rhs_env2, leftover_bndrs-             , rule_bndrs, rule_lhs_args-             , spec_bndrs1, dx_binds, spec_args) <- specHeader env rhs_bndrs all_call_args----           ; pprTrace "spec_call" (vcat---                [ text "fun:       "  <+> ppr fn---                , text "call info: "  <+> ppr _ci---                , text "useful:    "  <+> ppr useful---                , text "rule_bndrs:"  <+> ppr rule_bndrs---                , text "lhs_args:  "  <+> ppr rule_lhs_args---                , text "spec_bndrs1:" <+> ppr spec_bndrs1---                , text "leftover_bndrs:" <+> pprIds leftover_bndrs---                , text "spec_args: "  <+> ppr spec_args---                , text "dx_binds:  "  <+> ppr dx_binds---                , text "rhs_bndrs"     <+> ppr rhs_bndrs---                , text "rhs_body"     <+> ppr rhs_body---                , text "rhs_env2:  "  <+> ppr (se_subst rhs_env2)---                , ppr dx_binds ]) $---             return ()--           ; if not useful  -- No useful specialisation-                || already_covered rhs_env2 rules_acc rule_lhs_args-             then return spec_acc-             else-        do { -- Run the specialiser on the specialised RHS-             -- The "1" suffix is before we maybe add the void arg-           ; (rhs_body', rhs_uds) <- specExpr rhs_env2 rhs_body-                -- Add the { d1' = dx1; d2' = dx2 } usage stuff-                -- to the rhs_uds; see Note [Specialising Calls]-           ; let rhs_uds_w_dx   = dx_binds `consDictBinds` rhs_uds-                 spec_rhs_bndrs = spec_bndrs1 ++ leftover_bndrs-                 (spec_uds, dumped_dbs) = dumpUDs spec_rhs_bndrs rhs_uds_w_dx-                 spec_rhs1 = mkLams spec_rhs_bndrs $-                             wrapDictBindsE dumped_dbs rhs_body'--                 spec_fn_ty1 = exprType spec_rhs1--                 -- Maybe add a void arg to the specialised function,-                 -- to avoid unlifted bindings-                 -- See Note [Specialisations Must Be Lifted]-                 -- C.f. GHC.Core.Opt.WorkWrap.Utils.needsVoidWorkerArg-                 add_void_arg = isUnliftedType spec_fn_ty1 && not (isJoinId fn)-                 (spec_bndrs, spec_rhs, spec_fn_ty)-                   | add_void_arg = ( voidPrimId : spec_bndrs1-                                    , Lam voidArgId spec_rhs1-                                    , mkVisFunTyMany unboxedUnitTy spec_fn_ty1)-                   | otherwise   = (spec_bndrs1, spec_rhs1, spec_fn_ty1)--                 join_arity_decr = length rule_lhs_args - length spec_bndrs--                 ---------------------------------------                 -- Add a suitable unfolding; see Note [Inline specialisations]-                 -- The wrap_unf_body applies the original unfolding to the specialised-                 -- arguments, not forgetting to wrap the dx_binds around the outside (#22358)-                 simpl_opts = initSimpleOpts dflags-                 wrap_unf_body body = foldr (Let . db_bind) (body `mkApps` spec_args) dx_binds-                 spec_unf = specUnfolding simpl_opts spec_bndrs wrap_unf_body-                                          rule_lhs_args fn_unf--                 ---------------------------------------                 -- Adding arity information just propagates it a bit faster-                 --      See Note [Arity decrease] in GHC.Core.Opt.Simplify-                 -- Copy InlinePragma information from the parent Id.-                 -- So if f has INLINE[1] so does spec_fn-                 arity_decr     = count isValArg rule_lhs_args - count isId spec_bndrs--                 spec_inl_prag-                   | not is_local     -- See Note [Specialising imported functions]-                   , isStrongLoopBreaker (idOccInfo fn) -- in GHC.Core.Opt.OccurAnal-                   = neverInlinePragma-                   | otherwise-                   = inl_prag--                 spec_fn_info-                   = vanillaIdInfo `setArityInfo`      max 0 (fn_arity - arity_decr)-                                   `setInlinePragInfo` spec_inl_prag-                                   `setUnfoldingInfo`  spec_unf--                 -- Compute the IdDetails of the specialise Id-                 -- See Note [Transfer IdDetails during specialisation]-                 spec_fn_details-                   = case idDetails fn of-                       JoinId join_arity _ -> JoinId (join_arity - join_arity_decr) Nothing-                       DFunId is_nt        -> DFunId is_nt-                       _                   -> VanillaId--           ; spec_fn <- newSpecIdSM (idName fn) spec_fn_ty spec_fn_details spec_fn_info-           ; let-                -- The rule to put in the function's specialisation is:-                --      forall x @b d1' d2'.-                --          f x @T1 @b @T2 d1' d2' = f1 x @b-                -- See Note [Specialising Calls]-                herald | spec_imp  = -- Specialising imported fn-                                     text "SPEC/" <> ppr this_mod-                       | otherwise = -- Specialising local fn-                                     text "SPEC"--                spec_rule = mkSpecRule dflags this_mod True inl_act-                                    herald fn rule_bndrs rule_lhs_args-                                    (mkVarApps (Var spec_fn) spec_bndrs)--                spec_f_w_arity = spec_fn--                _rule_trace_doc = vcat [ ppr fn <+> dcolon <+> ppr fn_type-                                       , ppr spec_fn  <+> dcolon <+> ppr spec_fn_ty-                                       , ppr rhs_bndrs, ppr call_args-                                       , ppr spec_rule-                                       ]--           ; -- pprTrace "spec_call: rule" _rule_trace_doc-             return ( spec_rule                  : rules_acc-                    , (spec_f_w_arity, spec_rhs) : pairs_acc-                    , spec_uds           `thenUDs` uds_acc-                    ) } }---- Convenience function for invoking lookupRule from Specialise--- The SpecEnv's InScopeSet should include all the Vars in the [CoreExpr]-specLookupRule :: SpecEnv -> Id -> [CoreExpr]-               -> CompilerPhase  -- Look up rules as if we were in this phase-               -> [CoreRule] -> Maybe (CoreRule, CoreExpr)-specLookupRule env fn args phase rules-  = lookupRule ropts in_scope_env is_active fn args rules-  where-    dflags       = se_dflags env-    in_scope     = getSubstInScope (se_subst env)-    in_scope_env = ISE in_scope (whenActiveUnfoldingFun is_active)-    ropts        = initRuleOpts dflags-    is_active    = isActive phase--{- Note [Specialising DFuns]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~-DFuns have a special sort of unfolding (DFunUnfolding), and it is-hard to specialise a DFunUnfolding to give another DFunUnfolding-unless the DFun is fully applied (#18120).  So, in the case of DFunIds-we simply extend the CallKey with trailing UnspecTypes/UnspecArgs,-so that we'll generate a rule that completely saturates the DFun.--There is an ASSERT that checks this, in the DFunUnfolding case of-GHC.Core.Unfold.Make.specUnfolding.--Note [Transfer IdDetails during specialisation]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-When specialising a function, `newSpecIdSM` comes up with a fresh Id the-specialised RHS will be bound to. It is critical that we get the `IdDetails` of-the specialised Id correct:--* JoinId: We want the specialised Id to be a join point, too.  But-  we have to carefully adjust the arity--* DFunId: It is crucial that we also make the new Id a DFunId.-  - First, because it obviously /is/ a DFun, having a DFunUnfolding and-    all that; see Note [Specialising DFuns]--  - Second, DFuns get very delicate special treatment in the demand analyser;-    see GHC.Core.Opt.DmdAnal.enterDFun.  If the specialised function isn't-    also a DFunId, this special treatment doesn't happen, so the demand-    analyser makes a too-strict DFun, and we get an infinite loop.  See Note-    [Do not strictify a DFun's parameter dictionaries] in GHC.Core.Opt.DmdAnal.-    #22549 describes the loop, and (lower down) a case where a /specialised/-    DFun caused a loop.--* WorkerLikeId: Introduced by WW, so after Specialise. Nevertheless, they come-  up when specialising imports. We must keep them as VanillaIds because WW-  will detect them as WorkerLikeIds again. That is, unless specialisation-  allows unboxing of all previous CBV args, in which case sticking to-  VanillaIds was the only correct choice to begin with.--* RecSelId, DataCon*Id, ClassOpId, PrimOpId, FCallId, CoVarId, TickBoxId:-  Never specialised.--Note [Specialisation Must Preserve Sharing]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-Consider a function:--    f :: forall a. Eq a => a -> blah-    f =-      if expensive-         then f1-         else f2--As written, all calls to 'f' will share 'expensive'. But if we specialise 'f'-at 'Int', eg:--    $sfInt = SUBST[a->Int,dict->dEqInt] (if expensive then f1 else f2)--    RULE "SPEC f"-      forall (d :: Eq Int).-        f Int _ = $sfIntf--We've now lost sharing between 'f' and '$sfInt' for 'expensive'. Yikes!--To avoid this, we only generate specialisations for functions whose arity is-enough to bind all of the arguments we need to specialise.  This ensures our-specialised functions don't do any work before receiving all of their dicts,-and thus avoids the 'f' case above.--Note [Specialisations Must Be Lifted]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-Consider a function 'f':--    f = forall a. Eq a => Array# a--used like--    case x of-      True -> ...f @Int dEqInt...-      False -> 0--Naively, we might generate an (expensive) specialisation--    $sfInt :: Array# Int--even in the case that @x = False@! Instead, we add a dummy 'Void#' argument to-the specialisation '$sfInt' ($sfInt :: Void# -> Array# Int) in order to-preserve laziness.--Note [Care with unlifted bindings]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-Consider (#22998)-    f x = let x::ByteArray# = <some literal>-              n::Natural    = NB x-          in wombat @192827 (n |> co)-where-  co :: Natural ~ KnownNat 192827-  wombat :: forall (n:Nat). KnownNat n => blah--Left to itself, the specialiser would float the bindings for `x` and `n` to top-level, so we can specialise `wombat`.  But we can't have a top-level ByteArray#-(see Note [Core letrec invariant] in GHC.Core).  Boo.--This is pretty exotic, so we take a simple way out: in specBind (the NonRec-case) do not float the binding itself unless it satisfies exprIsTopLevelBindable.-This is conservative: maybe the RHS of `x` has a free var that would stop it-floating to top level anyway; but that is hard to spot (since we don't know what-the non-top-level in-scope binders are) and rare (since the binding must satisfy-Note [Core let-can-float invariant] in GHC.Core).--Arguably we'd be better off if we had left that `x` in the RHS of `n`, thus-    f x = let n::Natural = let x::ByteArray# = <some literal> in-                           NB x-          in wombat @192827 (n |> co)-Now we could float `n` happily.  But that's in conflict with exposing the `NB`-data constructor in the body of the `let`, so I'm leaving this unresolved.--Another case came up in #26682, where the binding had an unlifted sum type-(# Word# | ByteArray# #), itself arising from an UNPACK pragma.  Test case-T26682.--Note [Specialising Calls]-~~~~~~~~~~~~~~~~~~~~~~~~~-Suppose we have a function with a complicated type:--    f :: forall a b c. Int -> Eq a => Show b => c -> Blah-    f @a @b @c i dEqA dShowA x = blah--and suppose it is called at:--    f 7 @T1 @T2 @T3 dEqT1 ($dfShow dShowT2) t3--This call is described as a 'CallInfo' whose 'ci_key' is:--    [ SpecType T1, SpecType T2, UnspecType, UnspecArg, SpecDict dEqT1-    , SpecDict ($dfShow dShowT2), UnspecArg ]--Why are 'a' and 'b' identified as 'SpecType', while 'c' is 'UnspecType'?-Because we must specialise the function on type variables that appear-free in its *dictionary* arguments; but not on type variables that do not-appear in any dictionaries, i.e. are fully polymorphic.--Because this call has dictionaries applied, we'd like to specialise-the call on any type argument that appears free in those dictionaries.-In this case, those are [a :-> T1, b :-> T2].--We also need to substitute the dictionary binders with their-specialised dictionaries. The simplest substitution would be-[dEqA :-> dEqT1, dShowA :-> $dfShow dShowT2], but this duplicates-work, since `$dfShow dShowT2` is a function application. Therefore, we-also want to *float the dictionary out* (via bindAuxiliaryDict),-creating a new dict binding--    dShow1 = $dfShow dShowT2--and the substitution [dEqA :-> dEqT1, dShowA :-> dShow1].--With the substitutions in hand, we can generate a specialised function:--    $sf :: forall c. Int -> c -> Blah-    $sf = SUBST[a :-> T1, b :-> T2, dEqA :-> dEqT1, dShowA :-> dShow1] (\@c i x -> blah)--Note that the substitution is applied to the whole thing.  This is-convenient, but just slightly fragile.  Notably:-  * There had better be no name clashes in a/b/c--We must construct a rewrite rule:--    RULE "SPEC f @T1 @T2 _"-      forall (@c :: Type) (i :: Int) (d1 :: Eq T1) (d2 :: Show T2).-        f @T1 @T2 @c i d1 d2 = $sf @c i--In the rule, d1 and d2 are just wildcards, not used in the RHS.  Note-additionally that 'x' isn't captured by this rule --- we bind only-enough etas in order to capture all of the *specialised* arguments.--Note [Drop dead args from specialisations]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-When specialising a function, it’s possible some of the arguments may-actually be dead. For example, consider:--    f :: forall a. () -> Show a => a -> String-    f x y = show y ++ "!"--We might generate the following CallInfo for `f @Int`:--    [SpecType Int, UnspecArg, SpecDict $dShowInt, UnspecArg]--Normally we’d include both the x and y arguments in the-specialisation, since we’re not specialising on either of them. But-that’s silly, since x is actually unused! So we might as well drop it-in the specialisation:--    $sf :: Int -> String-    $sf y = show y ++ "!"--    {-# RULE "SPEC f @Int" forall x. f @Int x $dShow = $sf #-}--This doesn’t save us much, since the arg would be removed later by-worker/wrapper, anyway, but it’s easy to do.--Wrinkles--* Note that we only drop dead arguments if:-    1. We don’t specialise on them.-    2. They come before an argument we do specialise on.-  Doing the latter would require eta-expanding the RULE, which could-  make it match less often, so it’s not worth it. Doing the former could-  be more useful --- it would stop us from generating pointless-  specialisations --- but it’s more involved to implement and unclear if-  it actually provides much benefit in practice.--* If the function has a stable unfolding, specHeader has to come up with-  arguments to pass to that stable unfolding, when building the stable-  unfolding of the specialised function: this is the last field in specHeader's-  big result tuple.--  The right thing to do is to produce a LitRubbish; it should rapidly-  disappear.  Rather like GHC.Core.Opt.WorkWrap.Utils.mk_absent_let.--Note [Specialisation modulo dictionary selectors]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-In #19644, we discovered that the ClassOp/DFun rules from-Note [ClassOp/DFun selection] inhibit transitive specialisation.-Example, inspired by T17966:--  class C a where-    m :: Show b => a -> b -> String-    dummy :: a -> () -- Force a datatype dictionary representation--  instance C Int where-    m a b = show a ++ show b-    dummy _ = ()--  f :: (C a, Show b) => a -> b -> String-  f a b = m a b ++ "!"-  {-# INLINABLE[0] f #-}--  main = putStrLn (f (42::Int) (True::Bool))--Here, we specialise `f` at `Int` and `Bool`, giving--  $dC = $fCInt-  $dShow = GHC.Show.$fShowBool-  $sf (a::Int) (b::Bool) =-        ... (m @Int $dC @Bool $dShow a b) ...--Here `m` is just a DictSel, so there is (apparently) nothing to specialise!-However, the next Simplifier run will expose the rewritten instance method:--  ... $fCInt_$cm @Bool $fShowBool a b ...--where $fCInt_$cm is the instance method for `m` in `instance C Int`:--   $fCInt_$cm :: forall b. Show b => Int -> b -> String-   $fCInt_$cm b d x y = show @Int $dShowInt x ++ show @b d y--We want to specialise this! How? By doing the method-selection rewrite in-the Specialiser. Hence--1. In the App case of 'specExpr', try to apply the ClassOp/DFun rule on the-   head of the application, repeatedly, via 'fireRewriteRules'.-2. Attach an unfolding to freshly-bound dictionary ids such as `$dC` and-   `$dShow` in `bindAuxiliaryDict`, so that we can exploit the unfolding-   in 'fireRewriteRules' to do the ClassOp/DFun rewrite.--NB: Without (2), (1) would be pointless, because 'lookupRule' wouldn't be able-to look into the RHS of `$dC` to see the DFun.--Note [Zap occ info in rule binders]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-When we generate a specialisation RULE, we need to drop occurrence-info on the binders. If we don’t, things go wrong when we specialise a-function like--    f :: forall a. () -> Show a => a -> String-    f x y = show y ++ "!"--since we’ll generate a RULE like--    RULE "SPEC f @Int" forall x [Occ=Dead].-      f @Int x $dShow = $sf--and Core Lint complains, even though x only appears on the LHS (due to-Note [Drop dead args from specialisations]).--Why is that a Lint error? Because the arguments on the LHS of a rule-are syntactically expressions, not patterns, so Lint treats the-appearance of x as a use rather than a binding. Fortunately, the-solution is simple: we just make sure to zap the occ info before-using ids as wildcard binders in a rule.--Note [Account for casts in binding]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-Consider-   f :: Eq a => a -> IO ()-   {-# INLINABLE f-       StableUnf = (/\a \(d:Eq a) (x:a). blah) |> g-     #-}-   f = ...--In f's stable unfolding we have done some modest simplification which-has pushed the cast to the outside.  (I wonder if this is the Right-Thing, but it's what happens now; see GHC.Core.Opt.Simplify.Utils Note [Casts and-lambdas].)  Now that stable unfolding must be specialised, so we want-to push the cast back inside. It would be terrible if the cast-defeated specialisation!  Hence the use of collectBindersPushingCo.--Note [Evidence foralls]-~~~~~~~~~~~~~~~~~~~~~~~~~~-Suppose (#12212) that we are specialising-   f :: forall a b. (Num a, F a ~ F b) => blah-with a=b=Int. Then the RULE will be something like-   RULE forall (d:Num Int) (g :: F Int ~ F Int).-        f Int Int d g = f_spec-But both varToCoreExpr (when constructing the LHS args), and the-simplifier (when simplifying the LHS args), will transform to-   RULE forall (d:Num Int) (g :: F Int ~ F Int).-        f Int Int d <F Int> = f_spec-by replacing g with Refl.  So now 'g' is unbound, which results in a later-crash. So we use Refl right off the bat, and do not forall-quantify 'g':- * varToCoreExpr generates a Refl- * exprsFreeIdsList returns the Ids bound by the args,-   which won't include g--You might wonder if this will match as often, but the simplifier replaces-complicated Refl coercions with Refl pretty aggressively.--Note [Orphans and auto-generated rules]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-When we specialise an INLINABLE function, or when we have--fspecialise-aggressively, we auto-generate RULES that are orphans.-We don't want to warn about these, or we'd generate a lot of warnings.-Thus, we only warn about user-specified orphan rules.--Indeed, we don't even treat the module as an orphan module if it has-auto-generated *rule* orphans.  Orphan modules are read every time we-compile, so they are pretty obtrusive and slow down every compilation,-even non-optimised ones.  (Reason: for type class instances it's a-type correctness issue.)  But specialisation rules are strictly for-*optimisation* only so it's fine not to read the interface.--What this means is that a SPEC rules from auto-specialisation in-module M will be used in other modules only if M.hi has been read for-some other reason, which is actually pretty likely.--Note [From non-recursive to recursive]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-Even in the non-recursive case, if any dict-binds depend on 'fn' we might-have built a recursive knot--      f a d x = <blah>-      MkUD { ud_binds = NonRec d7  (MkD ..f..)-           , ud_calls = ...(f T d7)... }--The we generate--     Rec { fs x = <blah>[T/a, d7/d]-           f a d x = <blah>-               RULE f T _ = fs-           d7 = ...f... }--Here the recursion is only through the RULE.--However we definitely should /not/ make the Rec in this wildly common-case:-      d = ...-      MkUD { ud_binds = NonRec d7 (...d...)-           , ud_calls = ...(f T d7)... }--Here we want simply to add d to the floats, giving-      MkUD { ud_binds = NonRec d (...)-                        NonRec d7 (...d...)-           , ud_calls = ...(f T d7)... }--In general, we need only make this Rec if-  - there are some specialisations (spec_binds non-empty)-  - there are some dict_binds that depend on f (dump_dbs non-empty)--Note [Avoiding loops (DFuns)]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-When specialising /dictionary functions/ we must be very careful to-avoid building loops. Here is an example that bit us badly, on-several distinct occasions.--Here is one: #3591-     class Eq a => C a-     instance Eq [a] => C [a]--This translates to-     dfun :: Eq [a] -> C [a]-     dfun a d = MkD a d (meth d)--     d4 :: Eq [T] = <blah>-     d2 ::  C [T] = dfun T d4-     d1 :: Eq [T] = $p1 d2-     d3 ::  C [T] = dfun T d1--None of these definitions is recursive. What happened was that we-generated a specialisation:-     RULE forall d. dfun T d = dT  :: C [T]-     dT = (MkD a d (meth d)) [T/a, d1/d]-        = MkD T d1 (meth d1)--But now we use the RULE on the RHS of d2, to get-    d2 = dT = MkD d1 (meth d1)-    d1 = $p1 d2--and now d1 is bottom!  The problem is that when specialising 'dfun' we-should first dump "below" the binding all floated dictionary bindings-that mention 'dfun' itself.  So d2 and d3 (and hence d1) must be-placed below 'dfun', and thus unavailable to it when specialising-'dfun'.  That in turn means that the call (dfun T d1) must be-discarded.  On the other hand, the call (dfun T d4) is fine, assuming-d4 doesn't mention dfun.--Solution:-  Discard all calls that mention dictionaries that depend-  (directly or indirectly) on the dfun we are specialising.-  This is done by 'filterCalls'--Note [Avoiding loops (non-DFuns)]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-The whole Note [Avoiding loops (DFuns)] things applies only to DFuns.-It's important /not/ to apply filterCalls to non-DFuns. For example:--  class C a where { foo,bar :: [a] -> [a] }--  instance C Int where-     foo x = r_bar x-     bar xs = reverse xs--  r_bar :: C a => [a] -> [a]-  r_bar xs = bar (xs ++ xs)--That translates to:--    r_bar a (c::C a) (xs::[a]) = bar a d (xs ++ xs)--    Rec { $fCInt :: C Int = MkC foo_help reverse-          foo_help (xs::[Int]) = r_bar Int $fCInt xs }--The call (r_bar $fCInt) mentions $fCInt,-                        which mentions foo_help,-                        which mentions r_bar--But we DO want to specialise r_bar at Int:-    Rec { $fCInt :: C Int = MkC foo_help reverse-          foo_help (xs::[Int]) = r_bar Int $fCInt xs--          r_bar a (c::C a) (xs::[a]) = bar a d (xs ++ xs)-            RULE r_bar Int _ = r_bar_Int--          r_bar_Int xs = bar Int $fCInt (xs ++ xs)-           }--Note that, because of its RULE, r_bar joins the recursive-group.  (In this case it'll unravel a short moment later.)-See test simplCore/should_compile/T19599a.--Another example is #19599, which looked like this:--   class (Show a, Enum a) => MyShow a where-      myShow :: a -> String--   myShow_impl :: MyShow a => a -> String--   foo :: Int -> String-   foo = myShow_impl @Int $fMyShowInt--   Rec { $fMyShowInt = MkMyShowD $fEnumInt $fShowInt $cmyShow-       ; $cmyShow = myShow_impl @Int $fMyShowInt }--Here, we really do want to specialise `myShow_impl @Int $fMyShowInt`.---Note [Specialising a recursive group]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-Consider-    let rec { f x = ...g x'...-            ; g y = ...f y'.... }-    in f 'a'-Here we specialise 'f' at Char; but that is very likely to lead to-a specialisation of 'g' at Char.  We must do the latter, else the-whole point of specialisation is lost.--But we do not want to keep iterating to a fixpoint, because in the-presence of polymorphic recursion we might generate an infinite number-of specialisations.--So we use the following heuristic:-  * Arrange the rec block in dependency order, so far as possible-    (the occurrence analyser already does this)--  * Specialise it much like a sequence of lets--  * Then go through the block a second time, feeding call-info from-    the RHSs back in the bottom, as it were--In effect, the ordering maxmimises the effectiveness of each sweep,-and we do just two sweeps.   This should catch almost every case of-monomorphic recursion -- the exception could be a very knotted-up-recursion with multiple cycles tied up together.--This plan is implemented in the Rec case of specBindItself.--Note [Specialisations already covered]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-We obviously don't want to generate two specialisations for the same-argument pattern.  There are two wrinkles--1. We do the already-covered test in specDefn, not when we generate-the CallInfo in mkCallUDs.  We used to test in the latter place, but-we now iterate the specialiser somewhat, and the Id at the call site-might therefore not have all the RULES that we can see in specDefn--2. What about two specialisations where the second is an *instance*-of the first?  If the more specific one shows up first, we'll generate-specialisations for both.  If the *less* specific one shows up first,-we *don't* currently generate a specialisation for the more specific-one.  (See the call to lookupRule in already_covered.)  Reasons:-  (a) lookupRule doesn't say which matches are exact (bad reason)-  (b) if the earlier specialisation is user-provided, it's-      far from clear that we should auto-specialise further--Note [Auto-specialisation and RULES]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-Consider:-   g :: Num a => a -> a-   g = ...--   f :: (Int -> Int) -> Int-   f w = ...-   {-# RULE f g = 0 #-}--Suppose that auto-specialisation makes a specialised version of-g::Int->Int. That version won't appear in the LHS of the RULE for f.-So if the specialisation rule fires too early, the rule for f may-never fire.--It might be possible to add new rules, to "complete" the rewrite system.-Thus when adding-        RULE forall d. g Int d = g_spec-also add-        RULE f g_spec = 0--But that's a bit complicated.  For now we ask the programmer's help,-by *copying the INLINE activation pragma* to the auto-specialised-rule.  So if g says {-# NOINLINE[2] g #-}, then the auto-spec rule-will also not be active until phase 2.  And that's what programmers-should jolly well do anyway, even aside from specialisation, to ensure-that g doesn't inline too early.--This in turn means that the RULE would never fire for a NOINLINE-thing so not much point in generating a specialisation at all.--Note [Specialisation shape]-~~~~~~~~~~~~~~~~~~~~~~~~~~~-We only specialise a function if it has visible top-level lambdas-corresponding to its overloading.  E.g. if-        f :: forall a. Eq a => ....-then its body must look like-        f = /\a. \d. ...--Reason: when specialising the body for a call (f ty dexp), we want to-substitute dexp for d, and pick up specialised calls in the body of f.--We do allow casts, however; see Note [Account for casts in binding].--This doesn't always work.  One example I came across was this:-        newtype Gen a = MkGen{ unGen :: Int -> a }--        choose :: Eq a => a -> Gen a-        choose n = MkGen (\r -> n)--        oneof = choose (1::Int)--It's a silly example, but we get-        choose = /\a. g `cast` co-where choose doesn't have any dict arguments.  Thus far I have not-tried to fix this (wait till there's a real example).--Mind you, then 'choose' will be inlined (since RHS is trivial) so-it doesn't matter.  This comes up with single-method classes--   class C a where { op :: a -> a }-   instance C a => C [a] where ....-==>-   $fCList :: C a => C [a]-   $fCList = $copList |> (...coercion>...)-   ....(uses of $fCList at particular types)...--So we suppress the WARN if the rhs is trivial.--Note [Inline specialisations]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-Here is what we do with the InlinePragma of the original function--  * Activation/RuleMatchInfo: both inherited from the original function--  * InlineSpec: inherit from original function--  * Unfolding: transfer a StableUnfolding iff it is UnfWhen-               See GHC.Core.Unfold.Make.specUnfolding-               and its Note [Specialising unfoldings]--InlineSpec: you might wonder why we specialise INLINE functions at all.-After all they should be inlined, right?  Two reasons:-- * Even INLINE functions are sometimes not inlined, when they aren't-   applied to interesting arguments.  But perhaps the type arguments-   alone are enough to specialise (even though the args are too boring-   to trigger inlining), and it's certainly better to call the-   specialised version.-- * The RHS of an INLINE function might call another overloaded function,-   and we'd like to generate a specialised version of that function too.-   This actually happens a lot. Consider-      replicateM_ :: (Monad m) => Int -> m a -> m ()-      {-# INLINABLE replicateM_ #-}-      replicateM_ d x ma = ...-   The strictness analyser may transform to-      replicateM_ :: (Monad m) => Int -> m a -> m ()-      {-# INLINE replicateM_ #-}-      replicateM_ d x ma = case x of I# x' -> $wreplicateM_ d x' ma--      $wreplicateM_ :: (Monad m) => Int# -> m a -> m ()-      {-# INLINABLE $wreplicateM_ #-}-      $wreplicateM_ = ...-   Now an importing module has a specialised call to replicateM_, say-   (replicateM_ dMonadIO).  We certainly want to specialise $wreplicateM_!-   This particular example had a huge effect on the call to replicateM_-   in nofib/shootout/n-body.--}--{- *********************************************************************-*                                                                      *-                   SpecArg, and specHeader-*                                                                      *-********************************************************************* -}---- | An argument that we might want to specialise.--- See Note [Specialising Calls] for the nitty gritty details.-data SpecArg-  =-    -- | Type arguments that should be specialised, due to appearing-    -- free in the type of a 'SpecDict'.-    SpecType Type--    -- | Type arguments that should remain polymorphic.-  | UnspecType--    -- | Dictionaries that should be specialised. mkCallUDs ensures-    -- that only "interesting" dictionary arguments get a SpecDict;-    -- see Note [Interesting dictionary arguments]-  | SpecDict DictExpr--    -- | Value arguments that should not be specialised.-  | UnspecArg--instance Outputable SpecArg where-  ppr (SpecType t) = text "SpecType" <+> ppr t-  ppr UnspecType   = text "UnspecType"-  ppr (SpecDict d) = text "SpecDict" <+> ppr d-  ppr UnspecArg    = text "UnspecArg"--specArgFreeIds :: SpecArg -> IdSet-specArgFreeIds (SpecType {}) = emptyVarSet-specArgFreeIds (SpecDict dx) = exprFreeIds dx-specArgFreeIds UnspecType    = emptyVarSet-specArgFreeIds UnspecArg     = emptyVarSet--specArgFreeVars :: SpecArg -> VarSet-specArgFreeVars (SpecType ty) = tyCoVarsOfType ty-specArgFreeVars (SpecDict dx) = exprFreeVars dx-specArgFreeVars UnspecType    = emptyVarSet-specArgFreeVars UnspecArg     = emptyVarSet--isSpecDict :: SpecArg -> Bool-isSpecDict (SpecDict {}) = True-isSpecDict _             = False---- | Given binders from an original function 'f', and the 'SpecArg's--- corresponding to its usage, compute everything necessary to build--- a specialisation.------ We will use the running example from Note [Specialising Calls]:------     f :: forall a b c. Int -> Eq a => Show b => c -> Blah---     f @a @b @c i dEqA dShowB x = blah------ Suppose we decide to specialise it at the following pattern:------     [ SpecType T1, SpecType T2, UnspecType, UnspecArg---     , SpecDict dEqT1, SpecDict ($dfShow dShowT2), UnspecArg ]------ We'd eventually like to build the RULE------     RULE "SPEC f @T1 @T2 _"---       forall (@c :: Type) (i :: Int) (d1 :: Eq T1) (d2 :: Show T2).---         f @T1 @T2 @c i d1 d2 = $sf @c i------ and the specialisation '$sf'------     $sf :: forall c. Int -> c -> Blah---     $sf = SUBST[a :-> T1, b :-> T2, dEqA :-> dEqT1, dShowB :-> dShow1] (\@c i x -> blah)------ where dShow1 is a floated binding created by bindAuxiliaryDict.------ The cases for 'specHeader' below are presented in the same order as this--- running example. The result of 'specHeader' for this example is as follows:------    ( -- Returned arguments---      env + [a :-> T1, b :-> T2, dEqA :-> dEqT1, dShowB :-> dShow1]---    , [x]------      -- RULE helpers---    , [c, i, d1, d2]---    , [T1, T2, c, i, d1, d2]------      -- Specialised function helpers---    , [c, i, x]---    , [dShow1 = $dfShow dShowT2]---    , [T1, T2, c, i, dEqT1, dShow1]---    )-specHeader-     :: SpecEnv-     -> [InBndr]    -- The binders from the original function 'f'-     -> [SpecArg]   -- From the CallInfo-     -> SpecM ( Bool     -- True <=> some useful specialisation happened-                         -- Not the same as any (isSpecDict args) because-                         -- the args might be longer than bndrs--                -- Returned arguments-              , SpecEnv      -- Substitution to apply to the body of 'f'-              , [OutBndr]    -- Leftover binders from the original function 'f'-                             --   that don’t have a corresponding SpecArg--                -- RULE helpers-              , [OutBndr]    -- Binders for the RULE-              , [OutExpr]    -- Args for the LHS of the rule--                -- Specialised function helpers-              , [OutBndr]    -- Binders for $sf-              , [DictBind]   -- Auxiliary dictionary bindings-              , [OutExpr]    -- Specialised arguments for unfolding-                             -- Same length as "Args for LHS of rule"-              )---- We want to specialise on type 'T1', and so we must construct a substitution--- 'a->T1', as well as a LHS argument for the resulting RULE and unfolding--- details.-specHeader env (bndr : bndrs) (SpecType ty : args)-  = do { -- Find qvars, the type variables to add to the binders for the rule-         -- Namely those free in `ty` that aren't in scope-         -- See (MP2) in Note [Specialising polymorphic dictionaries]-         let in_scope = Core.getSubstInScope (se_subst env)-             qvars    = scopedSort $-                        filterOut (`elemInScopeSet` in_scope) $-                        tyCoVarsOfTypeList ty-             (env1, qvars') = substBndrs env qvars-             ty'            = substTy env1 ty-             env2           = extendTvSubst env1 bndr ty'-       ; (useful, env3, leftover_bndrs, rule_bs, rule_es, bs', dx, spec_args)-            <- specHeader env2 bndrs args-       ; pure ( useful-              , env3-              , leftover_bndrs-              , qvars' ++ rule_bs-              , Type ty' : rule_es-              , qvars' ++ bs'-              , dx-              , Type ty' : spec_args-              )-       }---- Next we have a type that we don't want to specialise. We need to perform--- a substitution on it (in case the type refers to 'a'). Additionally, we need--- to produce a binder, LHS argument and RHS argument for the resulting rule,--- /and/ a binder for the specialised body.-specHeader env (bndr : bndrs) (UnspecType : args)-  = do { let (env', bndr') = substBndr env bndr-       ; (useful, env'', leftover_bndrs, rule_bs, rule_es, bs', dx, spec_args)-            <- specHeader env' bndrs args-       ; pure ( useful-              , env''-              , leftover_bndrs-              , bndr' : rule_bs-              , varToCoreExpr bndr' : rule_es-              , bndr' : bs'-              , dx-              , varToCoreExpr bndr' : spec_args-              )-       }---- Next we want to specialise the 'Eq a' dict away. We need to construct--- a wildcard binder to match the dictionary (See Note [Specialising Calls] for--- the nitty-gritty), as a LHS rule and unfolding details.-specHeader env (bndr : bndrs) (SpecDict d : args)-  | not (isDeadBinder bndr)-  , allVarSet (`elemInScopeSet` in_scope) (exprFreeVars d)-    -- See Note [Weird special case for SpecDict]-  = do { (env1, bndr') <- newDictBndr env bndr -- See Note [Zap occ info in rule binders]-       ; let (env2, dx_bind, spec_dict) = bindAuxiliaryDict env1 bndr bndr' d-       ; (_, env3, leftover_bndrs, rule_bs, rule_es, bs', dx, spec_args)-             <- specHeader env2 bndrs args-       ; pure ( True      -- Ha!  A useful specialisation!-              , env3-              , leftover_bndrs-              -- See Note [Evidence foralls]-              , exprFreeIdsList (varToCoreExpr bndr') ++ rule_bs-              , varToCoreExpr bndr' : rule_es-              , bs'-              , maybeToList dx_bind ++ dx-              , spec_dict : spec_args-              )-       }-   where-     in_scope = Core.getSubstInScope (se_subst env)---- Finally, we don't want to specialise on this argument 'i':---   - It's an UnSpecArg, or---   - It's a dead dictionary--- We need to produce a binder, LHS and RHS argument for the RULE, and--- a binder for the specialised body.------ NB: Calls to 'specHeader' will trim off any trailing 'UnspecArg's, which is--- why 'i' doesn't appear in our RULE above. But we have no guarantee that--- there aren't 'UnspecArg's which come /before/ all of the dictionaries, so--- this case must be here.-specHeader env (bndr : bndrs) (_ : args)-    -- The "_" can be UnSpecArg, or SpecDict where the bndr is dead-  = do { -- see Note [Zap occ info in rule binders]-         let (env', bndr') = substBndr env (zapIdOccInfo bndr)-       ; (useful, env'', leftover_bndrs, rule_bs, rule_es, bs', dx, spec_args)-             <- specHeader env' bndrs args--       ; let bndr_ty = idType bndr'--             -- See Note [Drop dead args from specialisations]-             -- C.f. GHC.Core.Opt.WorkWrap.Utils.mk_absent_let-             (mb_spec_bndr, spec_arg)-                | isDeadBinder bndr-                , Just lit_expr <- mkLitRubbish bndr_ty-                = (Nothing, lit_expr)-                | otherwise-                = (Just bndr', varToCoreExpr bndr')--       ; pure ( useful-              , env''-              , leftover_bndrs-              , bndr' : rule_bs-              , varToCoreExpr bndr' : rule_es-              , case mb_spec_bndr of-                  Just b' -> b' : bs'-                  Nothing -> bs'-              , dx-              , spec_arg : spec_args-              )-       }---- If we run out of binders, stop immediately--- See Note [Specialisation Must Preserve Sharing]-specHeader env [] _ = pure (False, env, [], [], [], [], [], [])---- Return all remaining binders from the original function. These have the--- invariant that they should all correspond to unspecialised arguments, so--- it's safe to stop processing at this point.-specHeader env bndrs []-  = pure (False, env', bndrs', [], [], [], [], [])-  where-    (env', bndrs') = substBndrs env bndrs----- | Binds a dictionary argument to a fresh name, to preserve sharing-bindAuxiliaryDict-  :: SpecEnv-  -> InId -> OutId -> OutExpr -- Original dict binder, and the witnessing expression-  -> ( SpecEnv        -- Substitutes for orig_dict_id-     , Maybe DictBind -- Auxiliary dict binding, if any-     , OutExpr)       -- Witnessing expression (always trivial)-bindAuxiliaryDict env@(SE { se_subst = subst })-                  orig_dict_id fresh_dict_id dict_expr--  -- If the dictionary argument is trivial,-  -- don’t bother creating a new dict binding; just substitute-  | exprIsTrivial dict_expr-  = let env' = env { se_subst = Core.extendSubst subst orig_dict_id dict_expr }-    in -- pprTrace "bindAuxiliaryDict:trivial" (ppr orig_dict_id <+> ppr dict_id) $-       (env', Nothing, dict_expr)--  | otherwise  -- Non-trivial dictionary arg; make an auxiliary binding-  = let fresh_dict_id' = fresh_dict_id `addDictUnfolding` dict_expr--        dict_bind = mkDB (NonRec fresh_dict_id' dict_expr)-        env' = env { se_subst = Core.extendSubst subst orig_dict_id (Var fresh_dict_id')-                                `Core.extendSubstInScope` fresh_dict_id' }-                                -- Ensure the new unfolding is in the in-scope set-    in -- pprTrace "bindAuxiliaryDict:non-trivial" (ppr orig_dict_id <+> ppr fresh_dict_id') $-       (env', Just dict_bind, Var fresh_dict_id')--addDictUnfolding :: Id -> CoreExpr -> Id--- Add unfolding for freshly-bound Ids: see Note [Make the new dictionaries interesting]--- and Note [Specialisation modulo dictionary selectors]-addDictUnfolding id rhs-  = id `setIdUnfolding` mkSimpleUnfolding defaultUnfoldingOpts rhs--{--Note [Make the new dictionaries interesting]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-Important!  We're going to substitute dx_id1 for d-and we want it to look "interesting", else we won't gather *any*-consequential calls. E.g.-    f d = ...g d....-If we specialise f for a call (f (dfun dNumInt)), we'll get-a consequent call (g d') with an auxiliary definition-    d' = df dNumInt-We want that consequent call to look interesting; so we add an unfolding-in the dictionary Id.--}---{- *********************************************************************-*                                                                      *-            UsageDetails and suchlike-*                                                                      *-********************************************************************* -}--data UsageDetails-  = MkUD { ud_binds :: !FloatedDictBinds-         , ud_calls :: !CallDetails }-    -- INVARIANT: suppose bs = fdb_bndrs ud_binds-    -- Then 'calls' may *mention* 'bs',-    -- but there should be no calls *for* bs--data FloatedDictBinds  -- See Note [Floated dictionary bindings]-  = FDB { fdb_binds :: !(OrdList DictBind)-               -- The order is important;-               -- in ds1 `appOL` ds2, bindings in ds2 can depend on those in ds1--        , fdb_bndrs :: !IdSet-    }          -- ^ The binders of 'fdb_binds'.-               -- Caches a superset of the expression-               --   `mkVarSet (bindersOfDictBinds fdb_binds))`-               -- for later addition to an InScopeSet---- | A 'DictBind' is a binding along with a cached set containing its free--- variables (both type variables and dictionaries). We need this set--- in splitDictBinds, when filtering bindings to decide which are--- captured by a binder-data DictBind = DB { db_bind :: CoreBind, db_fvs :: VarSet }--bindersOfDictBind :: DictBind -> [Id]-bindersOfDictBind = bindersOf . db_bind--bindersOfDictBinds :: Foldable f => f DictBind -> [Id]-bindersOfDictBinds = bindersOfBinds . foldr ((:) . db_bind) []--{- Note [Floated dictionary bindings]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-We float out dictionary bindings for the reasons described under-"Dictionary floating" above.  But not /just/ dictionary bindings.-Consider--   f :: Eq a => blah-   f a d = rhs--   $c== :: T -> T -> Bool-   $c== x y = ...--   $df :: Eq T-   $df = Eq $c== ...--   gurgle = ...(f @T $df)...--We gather the call info for (f @T $df), and we don't want to drop it-when we come across the binding for $df.  So we add $df to the floats-and continue.  But then we have to add $c== to the floats, and so on.-These all float above the binding for 'f', and now we can-successfully specialise 'f'.--So the DictBinds in (ud_binds :: OrdList DictBind) may contain-non-dictionary bindings too.--Note [Specialising polymorphic dictionaries]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~--Note June 2023: This has proved to be quite a tricky optimisation to get right-see (#23469, #23109, #21229, #23445) so it is now guarded by a flag-`-fpolymorphic-specialisation`.---Consider-    class M a where { foo :: a -> Int }--    instance M (ST s) where ...-    -- dMST :: forall s. M (ST s)--    wimwam :: forall a. M a => a -> Int-    wimwam = /\a \(d::M a). body--    f :: ST s -> Int-    f = /\s \(x::ST s). wimwam @(ST s) (dMST @s) dx + 1--We'd like to specialise wimwam at (ST s), thus-    $swimwam :: forall s. ST s -> Int-    $swimwam = /\s. body[ST s/a, (dMST @s)/d]--    RULE forall s (d :: M (ST s)).-         wimwam @(ST s) d = $swimwam @s--Here are the moving parts:--(MP1) We must /not/ dump the CallInfo-        CIS wimwam (CI { ci_key = [@(ST s), dMST @s]-                       , ci_fvs = {dMST} })-      when we come to the /\s.  Instead, we simply let it continue to float-      upwards. Hence ci_fvs is an IdSet, listing the /Ids/ that-      are free in the call, but not the /TyVars/.  Hence using specArgFreeIds-      in singleCall.--  NB to be fully kosher we should explicitly quantifying the CallInfo-  over 's', but we don't bother.  This would matter if there was an-  enclosing binding of the same 's', which I don't expect to happen.--(MP2) When we come to specialise the call, we must remember to quantify-      over 's'.  That is done in the SpecType case of specHeader, where-      we add 's' (called qvars) to the binders of the RULE and the specialised-      function.--(MP3) If we have f :: forall m. Monoid m => blah, and two calls-        (f @(Endo b)      (d :: Monoid (Endo b))-        (f @(Endo (c->c)) (d :: Monoid (Endo (c->c)))-      we want to generate a specialisation only for the first.  The second-      is just a substitution instance of the first, with no greater specialisation.-      Hence the call to `remove_dups` in `filterCalls`.--All this arose in #13873, in the unexpected form that a SPECIALISE-pragma made the program slower!  The reason was that the specialised-function $sinsertWith arising from the pragma looked rather like `f`-above, and failed to specialise a call in its body like wimwam.-Without the pragma, the original call to `insertWith` was completely-monomorpic, and specialised in one go.--Wrinkles.--* See Note [Weird special case for SpecDict]--* With -XOverlappingInstances you might worry about this:-    class C a where ...-    instance C (Maybe Int) where ...   -- $df1 :: C (Maybe Int)-    instance C (Maybe a)   where ...   -- $df2 :: forall a. C (Maybe a)--    f :: C a => blah-    f = rhs--    g = /\a.  ...(f @(Maybe a) ($df2 a))...-    h = ...f @(Maybe Int) $df1--  There are two calls to f, but with different evidence.  This patch will-  combine them into one.  But it's OK: this code will never arise unless you-  use -XIncoherentInstances.  Even with -XOverlappingInstances, GHC tries hard-  to keep dictionaries as singleton types.  But that goes out of the window-  with -XIncoherentInstances -- and that is true even with ordianry type-class-  specialisation (at least if any inlining has taken place).--  GHC makes very few guarantees when you use -XIncoherentInstances, and its-  not worth crippling the normal case for the incoherent corner.  (The best-  thing might be to switch off specialisation altogether if incoherence is-  involved... but incoherence is a property of an instance, not a class, so-  it's a hard test to make.)--  But see Note [Specialisation and overlapping instances].--Note [Weird special case for SpecDict]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-Suppose we are trying to specialise for this this call:-   $wsplit @T (mkD @k @(a::k) :: C T)-where-   mkD :: forall k (a::k). C T-is a top-level dictionary-former.  This actually happened in #22459,-because of (MP1) of Note [Specialising polymorphic dictionaries].--How can we specialise $wsplit?  We might try--   RULE "SPEC" forall (d :: C T). $wsplit @T d = $s$wsplit--but then in the body of $s$wsplit what will we use for the dictionary-evidence?  We can't use (mkD @k @(a::k)) because k and a aren't in scope.-We could zap `k` to (Any @Type) and `a` to (Any @(Any @Type)), but that-is a lot of hard work for a very strange case.--So we simply refrain from specialising in this case; hence the guard-   allVarSet (`elemInScopeSet` in_scope) (exprFreeVars d)-in the SpecDict cased of specHeader.--How did this strange polymorphic mkD arise in the first place?-From GHC.Core.Opt.Utils.abstractFloats, which was abstracting-over too many type variables. But that too is now fixed;-see Note [Which type variables to abstract over] in that module.--}--instance Outputable DictBind where-  ppr (DB { db_bind = bind, db_fvs = fvs })-    = text "DB" <+> braces (sep [ text "fvs: " <+> ppr fvs-                                , text "bind:" <+> ppr bind ])--instance Outputable UsageDetails where-  ppr (MkUD { ud_binds = dbs, ud_calls = calls })-        = text "MkUD" <+> braces (sep (punctuate comma-                [text "binds" <+> equals <+> ppr dbs,-                 text "calls" <+> equals <+> ppr calls]))--instance Outputable FloatedDictBinds where-  ppr (FDB { fdb_binds = binds }) = ppr binds--emptyUDs :: UsageDetails-emptyUDs = MkUD { ud_binds = emptyFDBs, ud_calls = emptyDVarEnv }---emptyFDBs :: FloatedDictBinds-emptyFDBs = FDB { fdb_binds = nilOL, fdb_bndrs = emptyVarSet }---------------------------------------------------------------type CallDetails  = DIdEnv CallInfoSet-  -- The order of specialized binds and rules depends on how we linearize-  -- CallDetails, so to get determinism we must use a deterministic set here.-  -- See Note [Deterministic UniqFM] in GHC.Types.Unique.DFM--data CallInfoSet = CIS Id (Bag CallInfo)-  -- The list of types and dictionaries is guaranteed to-  -- match the type of f-  -- The Bag may contain duplicate calls (i.e. f @T and another f @T)-  -- These dups are eliminated by already_covered in specCalls--data CallInfo-  = CI { ci_key  :: [SpecArg]   -- All arguments-       , ci_fvs  :: IdSet       -- Free Ids of the ci_key call-                                -- /not/ including the main id itself, of course-                                -- NB: excluding tyvars:-                                --     See Note [Specialising polymorphic dictionaries]-    }--type DictExpr = CoreExpr--ciSetFilter :: (CallInfo -> Bool) -> CallInfoSet -> CallInfoSet-ciSetFilter p (CIS id a) = CIS id (filterBag p a)--instance Outputable CallInfoSet where-  ppr (CIS fn map) = hang (text "CIS" <+> ppr fn)-                        2 (ppr map)--pprCallInfo :: Id -> CallInfo -> SDoc-pprCallInfo fn (CI { ci_key = key })-  = ppr fn <+> ppr key--instance Outputable CallInfo where-  ppr (CI { ci_key = key, ci_fvs = _fvs })-    = text "CI" <> braces (text "fvs" <+> ppr _fvs-                           $$ sep (map ppr key))--unionCalls :: CallDetails -> CallDetails -> CallDetails-unionCalls c1 c2 = plusDVarEnv_C unionCallInfoSet c1 c2--unionCallInfoSet :: CallInfoSet -> CallInfoSet -> CallInfoSet-unionCallInfoSet (CIS f calls1) (CIS _ calls2) =-  CIS f (calls1 `unionBags` calls2)--callDetailsFVs :: CallDetails -> VarSet-callDetailsFVs calls =-  nonDetStrictFoldUDFM (unionVarSet . callInfoFVs) emptyVarSet calls-  -- It's OK to use nonDetStrictFoldUDFM here because we forget the ordering-  -- immediately by converting to a nondeterministic set.--callInfoFVs :: CallInfoSet -> VarSet-callInfoFVs (CIS _ call_info) =-  foldr (\(CI { ci_fvs = fv }) vs -> unionVarSet fv vs) emptyVarSet call_info--getTheta :: [PiTyBinder] -> [PredType]-getTheta = fmap piTyBinderType . filter isInvisiblePiTyBinder . filter isAnonPiTyBinder----------------------------------------------------------------singleCall :: SpecEnv -> Id -> [SpecArg] -> UsageDetails-singleCall spec_env id args-  = MkUD {ud_binds = emptyFDBs,-          ud_calls = unitDVarEnv id $ CIS id $-                     unitBag (CI { ci_key  = args-                                 , ci_fvs  = call_fvs }) }-  where-    call_fvs =-      foldr (unionVarSet . free_var_fn) emptyVarSet args--    free_var_fn =-      if gopt Opt_PolymorphicSpecialisation (se_dflags spec_env)-        then specArgFreeIds-        else specArgFreeVars----        -- specArgFreeIds: we specifically look for free Ids, not TyVars-        --    see (MP1) in Note [Specialising polymorphic dictionaries]-        ---        -- We don't include the 'id' itself.--mkCallUDs :: SpecEnv -> OutExpr -> [OutExpr] -> UsageDetails-mkCallUDs env fun args-  | (_, Var f) <- stripTicksTop tickishFloatable fun -- See Note [Ticks on applications]-  = -- pprTraceWith "mkCallUDs" (\res -> vcat [ ppr f, ppr args, ppr res ]) $-    mkCallUDs' env f args-  | otherwise-  = emptyUDs--mkCallUDs' :: SpecEnv -> Id -> [OutExpr] -> UsageDetails-mkCallUDs' env f args-  | wantCallsFor env f    -- We want it, and...-  , not (null ci_key)     -- this call site has a useful specialisation-  = -- pprTrace "mkCallUDs: keeping" _trace_doc-    singleCall env f ci_key--  | otherwise  -- See also Note [Specialisations already covered]-  = -- pprTrace "mkCallUDs: discarding" _trace_doc-    emptyUDs--  where-    _trace_doc = vcat [ppr f, ppr args, ppr ci_key]-    pis                = fst $ splitPiTys $ idType f-    constrained_tyvars = tyCoVarsOfTypes $ getTheta pis--    ci_key :: [SpecArg]-    ci_key = dropWhileEndLE (not . isSpecDict) $-             zipWith mk_spec_arg args pis-             -- Drop trailing args until we get to a SpecDict-             -- In this way the RULE has as few args as possible,-             -- which broadens its applicability, since rules only-             -- fire when saturated--    mk_spec_arg :: OutExpr -> PiTyBinder -> SpecArg-    mk_spec_arg arg (Named bndr)-      |  binderVar bndr `elemVarSet` constrained_tyvars-      = case arg of-          Type ty -> SpecType ty-          _       -> pprPanic "ci_key" $ ppr arg-      |  otherwise = UnspecType--    -- For "invisibleFunArg", which are the type-class dictionaries,-    -- we decide on a case by case basis if we want to specialise-    -- on this argument; if so, SpecDict, if not UnspecArg-    mk_spec_arg arg (Anon pred af)-      | isInvisibleFunArg af-      , interestingDict arg (scaledThing pred)-              -- See Note [Interesting dictionary arguments]-      = SpecDict arg--      | otherwise = UnspecArg--{--Note [Ticks on applications]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~-Ticks such as source location annotations can sometimes make their way-onto applications (see e.g. #21697). So if we see something like--    App (Tick _ f) e--we need to descend below the tick to find what the real function being-applied is.--The resulting RULE also has to be able to match this annotated use-site, so we only look through ticks that RULE matching looks through-(see Note [Tick annotations in RULE matching] in GHC.Core.Rules).--}--wantCallsFor :: SpecEnv -> Id -> Bool-wantCallsFor _env _f = True- -- We could reduce the size of the UsageDetails by being less eager- -- about collecting calls for LocalIds: there is no point for- -- ones that are lambda-bound.  We can't decide this by looking at- -- the (absence of an) unfolding, because unfoldings for local- -- functions are discarded by cloneBindSM, so no local binder will- -- have an unfolding at this stage.  We'd have to keep a candidate- -- set of let-binders.- --- -- Not many lambda-bound variables have dictionary arguments, so- -- this would make little difference anyway.- --- -- For imported Ids we could check for an unfolding, but we have to- -- do so anyway in canSpecImport, and it seems better to have it- -- all in one place.  So we simply collect usage info for imported- -- overloaded functions.--{- Note [Interesting dictionary arguments]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-Consider this-         \a.\d:Eq a.  let f = ... in ...(f d)...-There really is not much point in specialising f wrt the dictionary d,-because the code for the specialised f is not improved at all, because-d is lambda-bound.  We simply get junk specialisations.--What is "interesting"?  Just that it has *some* structure.  But what about-variables?  We look in the variable's /unfolding/.  And that means-that we must be careful to ensure that dictionaries have unfoldings,--* cloneBndrSM discards non-Stable unfoldings-* specBind updates the unfolding after specialisation-  See Note [Update unfolding after specialisation]-* bindAuxiliaryDict adds an unfolding for an aux dict-  see Note [Specialisation modulo dictionary selectors]-* specCase adds unfoldings for the new bindings it creates--We accidentally lost accurate tracking of local variables for a long-time, because cloned variables didn't have unfoldings. But makes a-massive difference in a few cases, eg #5113. For nofib as a-whole it's only a small win: 2.2% improvement in allocation for ansi,-1.2% for bspt, but mostly 0.0!  Average 0.1% increase in binary size.--Note [Update unfolding after specialisation]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-Consider (#21848)--  wombat :: Show b => Int -> b -> String-  wombat a b | a>0       = wombat (a-1) b-             | otherwise = show a ++ wombat a b--  class C a where-    meth :: Show b => a -> b -> String-    dummy :: a -> () -- Force a datatype dictionary representation--  instance C Int where-    meth = wombat-    dummy _ = ()--  class C a => D a   -- D has C as a superclass-  instance D Int--  f :: (D a, Show b) => a -> b -> String-  {-# INLINABLE[0] f #-}-  f a b = meth a b ++ "!" ++ meth a b--Now `f` turns into:--  f @a @b (dd :: D a) (ds :: Show b) a b-     = let dc :: D a = %p1 dd  -- Superclass selection-       in meth @a dc ....-          meth @a dc ....--When we specialise `f`, at a=Int say, that superclass selection can-nfire (via rewiteClassOps), but that info (that 'dc' is now a-particular dictionary `C`, of type `C Int`) must be available to-the call `meth @a dc`, so that we can fire the `meth` class-op, and-thence specialise `wombat`.--We deliver on this idea by updating the unfolding for the binder-in the NonRec case of specBind.  (This is too exotic to trouble with-the Rec case.)--}--interestingDict :: CoreExpr -> Type -> Bool--- A dictionary argument is interesting if it has *some* structure,--- see Note [Interesting dictionary arguments]--- NB: "dictionary" arguments include constraints of all sorts,---     including equality constraints; hence the Coercion case--- To make this work, we need to ensure that dictionaries have--- unfoldings in them.-interestingDict arg arg_ty-  | not (typeDeterminesValue arg_ty) = False   -- See Note [Type determines value]-  | otherwise                        = go arg-  where-    go (Var v)               =  hasSomeUnfolding (idUnfolding v)-                             || isDataConWorkId v-    go (Type _)              = False-    go (Coercion _)          = False-    go (App fn (Type _))     = go fn-    go (App fn (Coercion _)) = go fn-    go (Tick _ a)            = go a-    go (Cast e _)            = go e-    go _                     = True--thenUDs :: UsageDetails -> UsageDetails -> UsageDetails-thenUDs (MkUD {ud_binds = db1, ud_calls = calls1})-        (MkUD {ud_binds = db2, ud_calls = calls2})-  = MkUD { ud_binds       = db1    `thenFDBs`   db2-         , ud_calls       = calls1 `unionCalls`  calls2 }--thenFDBs :: FloatedDictBinds -> FloatedDictBinds -> FloatedDictBinds--- Combine FloatedDictBinds--- In (dbs1 `thenFDBs` dbs2), dbs2 may mention dbs1 but not vice versa-thenFDBs (FDB { fdb_binds = dbs1, fdb_bndrs = bs1 })-         (FDB { fdb_binds = dbs2, fdb_bndrs = bs2 })-  = FDB { fdb_binds = dbs1 `appOL` dbs2-        , fdb_bndrs = bs1  `unionVarSet` bs2 }--------------------------------_dictBindBndrs :: OrdList DictBind -> [Id]-_dictBindBndrs dbs = foldr ((++) . bindersOf . db_bind) [] dbs---- | Construct a 'DictBind' from a 'CoreBind'-mkDB :: CoreBind -> DictBind-mkDB bind = DB { db_bind = bind, db_fvs = bind_fvs bind }---- | Identify the free variables of a 'CoreBind'-bind_fvs :: CoreBind -> VarSet-bind_fvs (NonRec bndr rhs) = pair_fvs (bndr,rhs)-bind_fvs (Rec prs)         = rhs_fvs `delVarSetList` (map fst prs)-                           where-                             rhs_fvs = unionVarSets (map pair_fvs prs)--pair_fvs :: (Id, CoreExpr) -> VarSet-pair_fvs (bndr, rhs) = exprSomeFreeVars interesting rhs-                       `unionVarSet` idFreeVars bndr-        -- idFreeVars: don't forget variables mentioned in-        -- the rules of the bndr.  C.f. OccAnal.addRuleUsage-        -- Also tyvars mentioned in its type; they may not appear-        -- in the RHS-        --      type T a = Int-        --      x :: T a = 3-  where-    interesting :: InterestingVarFun-    interesting v = isLocalVar v || (isId v && isDFunId v)-        -- Very important: include DFunIds /even/ if it is imported-        -- Reason: See Note [Avoiding loops in specImports], the #13429-        --         example involving an imported dfun.  We must know-        --         whether a dictionary binding depends on an imported-        --         DFun in case we try to specialise that imported DFun---- | Flatten a set of "dumped" 'DictBind's, and some other binding--- pairs, into a single recursive binding.-recWithDumpedDicts :: [(Id,CoreExpr)] -> OrdList DictBind -> DictBind-recWithDumpedDicts pairs dbs-  = DB { db_bind = Rec bindings-       , db_fvs = fvs `delVarSetList` map fst bindings }-  where-    (bindings, fvs) = foldr add ([], emptyVarSet)-                                (dbs `snocOL` mkDB (Rec pairs))-    add (DB { db_bind = bind, db_fvs = fvs }) (prs_acc, fvs_acc)-      = case bind of-          NonRec b r -> ((b,r) : prs_acc, fvs')-          Rec prs1   -> (prs1 ++ prs_acc, fvs')-      where-        fvs' = fvs_acc `unionVarSet` fvs--snocDictBind :: UsageDetails -> DictBind -> UsageDetails-snocDictBind uds@MkUD{ud_binds= FDB { fdb_binds = dbs, fdb_bndrs = bs }} db-  = uds { ud_binds = FDB { fdb_binds = dbs `snocOL` db-                         , fdb_bndrs = bs `extendVarSetList` bindersOfDictBind db } }--snocDictBinds :: UsageDetails -> [DictBind] -> UsageDetails--- Add ud_binds to the tail end of the bindings in uds-snocDictBinds uds@MkUD{ud_binds=FDB{ fdb_binds = binds, fdb_bndrs = bs }} dbs-  = uds { ud_binds = FDB { fdb_binds = binds `appOL`        (toOL dbs)-                         , fdb_bndrs = bs    `extendVarSetList` bindersOfDictBinds dbs } }--consDictBinds :: [DictBind] -> UsageDetails -> UsageDetails-consDictBinds dbs uds@MkUD{ud_binds=FDB{fdb_binds = binds, fdb_bndrs = bs}}-  = uds { ud_binds = FDB{ fdb_binds = toOL dbs `appOL` binds-                        , fdb_bndrs = bs `extendVarSetList` bindersOfDictBinds dbs } }--wrapDictBinds :: FloatedDictBinds -> [CoreBind] -> [CoreBind]-wrapDictBinds (FDB { fdb_binds = dbs }) binds-  = foldr add binds dbs-  where-    add (DB { db_bind = bind }) binds = bind : binds--wrapDictBindsE :: OrdList DictBind -> CoreExpr -> CoreExpr-wrapDictBindsE dbs expr-  = foldr add expr dbs-  where-    add (DB { db_bind = bind }) expr = Let bind expr-------------------------dumpUDs :: [CoreBndr] -> UsageDetails -> (UsageDetails, OrdList DictBind)--- Used at binder; just dump anything mentioning the binder-dumpUDs bndrs uds@(MkUD { ud_binds = orig_dbs, ud_calls = orig_calls })-  | null bndrs = (uds, nilOL)  -- Common in case alternatives-  | otherwise  = -- pprTrace "dumpUDs" (ppr bndrs $$ ppr free_uds $$ ppr dump_dbs) $-                 (free_uds, dump_dbs)-  where-    free_uds = uds { ud_binds = free_dbs, ud_calls = free_calls }-    bndr_set = mkVarSet bndrs-    (free_dbs, dump_dbs, dump_set) = splitDictBinds orig_dbs bndr_set--    -- Delete calls:-    --   * For any binder in `bndrs`-    --   * That mention a dictionary bound in `dump_set`-    -- These variables aren't in scope "above" the binding and the `dump_dbs`,-    -- so no call should mention them.  (See #26682.)-    free_calls = deleteCallsMentioning dump_set $-                 deleteCallsFor bndrs orig_calls--dumpBindUDs :: Bool   -- Main binding can float to top-            -> [CoreBndr] -> UsageDetails-            -> (UsageDetails, OrdList DictBind, Bool)--- Used at a let(rec) binding.--- We return a boolean indicating whether the binding itself---    is mentioned, directly or indirectly, by any of the ud_calls;---    in that case we want to float the binding itself.---    See Note [Floated dictionary bindings]--- If the boolean is True, then the returned ud_calls can mention `bndrs`;--- if False, then returned ud_calls must not mention `bndrs`-dumpBindUDs can_float_bind bndrs (MkUD { ud_binds = orig_dbs, ud_calls = orig_calls })-  = ( MkUD { ud_binds = free_dbs, ud_calls = free_calls2 }-    , dump_dbs-    , can_float_bind && calls_mention_bndrs )-  where-    bndr_set = mkVarSet bndrs-    (free_dbs, dump_dbs, dump_set) = splitDictBinds orig_dbs bndr_set-    free_calls1 = deleteCallsFor bndrs orig_calls-    calls_mention_bndrs = dump_set `intersectsVarSet` callDetailsFVs free_calls1-    free_calls2 | can_float_bind = free_calls1-                | otherwise      = deleteCallsMentioning dump_set free_calls1--callsForMe :: Id -> UsageDetails -> (UsageDetails, [CallInfo])-callsForMe fn uds@MkUD { ud_binds = orig_dbs, ud_calls = orig_calls }-  = -- pprTrace ("callsForMe")-    --          (vcat [ppr fn,-    --                 text "Orig dbs ="     <+> ppr (_dictBindBndrs orig_dbs),-    --                 text "Orig calls ="   <+> ppr orig_calls,-    --                 text "Calls for me =" <+> ppr calls_for_me]) $-    (uds_without_me, calls_for_me)-  where-    uds_without_me = uds { ud_calls = delDVarEnv orig_calls fn }-    calls_for_me = case lookupDVarEnv orig_calls fn of-                        Nothing -> []-                        Just cis -> filterCalls cis orig_dbs-         -- filterCalls: drop calls that (directly or indirectly)-         -- refer to fn.  See Note [Avoiding loops (DFuns)]-------------------------filterCalls :: CallInfoSet -> FloatedDictBinds -> [CallInfo]--- Remove dominated calls (Note [Specialising polymorphic dictionaries])--- and loopy DFuns (Note [Avoiding loops (DFuns)])-filterCalls (CIS fn call_bag) (FDB { fdb_binds = dbs })-  | isDFunId fn  -- Note [Avoiding loops (DFuns)] applies only to DFuns-  = filter ok_call de_dupd_calls-  | otherwise         -- Do not apply it to non-DFuns-  = de_dupd_calls  -- See Note [Avoiding loops (non-DFuns)]-  where-    de_dupd_calls = remove_dups call_bag--    dump_set = foldl' go (unitVarSet fn) dbs-      -- This dump-set could also be computed by splitDictBinds-      --   (_,_,dump_set) = splitDictBinds dbs {fn}-      -- But this variant is shorter--    go so_far (DB { db_bind = bind, db_fvs = fvs })-       | fvs `intersectsVarSet` so_far-       = extendVarSetList so_far (bindersOf bind)-       | otherwise = so_far--    ok_call (CI { ci_fvs = fvs }) = fvs `disjointVarSet` dump_set--remove_dups :: Bag CallInfo -> [CallInfo]--- Calls involving more generic instances beat more specific ones.--- See (MP3) in Note [Specialising polymorphic dictionaries]-remove_dups calls = foldr add [] calls-  where-    add :: CallInfo -> [CallInfo] -> [CallInfo]-    add ci [] = [ci]-    add ci1 (ci2:cis) | ci2 `beats_or_same` ci1 = ci2:cis-                      | ci1 `beats_or_same` ci2 = ci1:cis-                      | otherwise               = ci2 : add ci1 cis--beats_or_same :: CallInfo -> CallInfo -> Bool-beats_or_same (CI { ci_key = args1 }) (CI { ci_key = args2 })-  = go args1 args2-  where-    go [] _ = True-    go (arg1:args1) (arg2:args2) = go_arg arg1 arg2 && go args1 args2-    go (_:_)        []           = False--    go_arg (SpecType ty1) (SpecType ty2) = isJust (tcMatchTy ty1 ty2)-    go_arg UnspecType     UnspecType     = True-    go_arg (SpecDict {})  (SpecDict {})  = True-    go_arg UnspecArg      UnspecArg      = True-    go_arg _              _              = False-------------------------splitDictBinds :: FloatedDictBinds -> IdSet -> (FloatedDictBinds, OrdList DictBind, IdSet)--- splitDictBinds dbs bndrs returns---   (free_dbs, dump_dbs, dump_set)--- where---   * dump_dbs depends, transitively on bndrs---   * free_dbs does not depend on bndrs---   * dump_set = bndrs `union` bndrs(dump_dbs)-splitDictBinds (FDB { fdb_binds = dbs, fdb_bndrs = bs }) bndr_set-   = (FDB { fdb_binds = free_dbs-          , fdb_bndrs = bs `minusVarSet` dump_set }-     , dump_dbs, dump_set)-   where-    (free_dbs, dump_dbs, dump_set)-      = foldl' split_db (nilOL, nilOL, bndr_set) dbs-                -- Important that it's foldl' not foldr;-                -- we're accumulating the set of dumped ids in dump_set--    split_db (free_dbs, dump_dbs, dump_idset) db-        | DB { db_bind = bind, db_fvs = fvs } <- db-        , dump_idset `intersectsVarSet` fvs     -- Dump it-        = (free_dbs, dump_dbs `snocOL` db,-           extendVarSetList dump_idset (bindersOf bind))--        | otherwise     -- Don't dump it-        = (free_dbs `snocOL` db, dump_dbs, dump_idset)--------------------------deleteCallsMentioning :: VarSet -> CallDetails -> CallDetails--- Remove calls mentioning any Id in bndrs--- NB: The call is allowed to mention TyVars in bndrs---     Note [Specialising polymorphic dictionaries]---     ci_fvs are just the free /Ids/-deleteCallsMentioning bndrs calls-  = mapDVarEnv (ciSetFilter keep_call) calls-  where-    keep_call (CI { ci_fvs = fvs }) = fvs `disjointVarSet` bndrs--deleteCallsFor :: [Id] -> CallDetails -> CallDetails--- Remove calls *for* bndrs-deleteCallsFor bndrs calls = delDVarEnvList calls bndrs--{--************************************************************************-*                                                                      *-\subsubsection{Boring helper functions}-*                                                                      *-************************************************************************--}--type SpecM a = UniqSM a--runSpecM :: SpecM a -> CoreM a-runSpecM thing_inside-  = do { us <- getUniqueSupplyM-       ; return (initUs_ us thing_inside) }--mapAndCombineSM :: (a -> SpecM (b, UsageDetails)) -> [a] -> SpecM ([b], UsageDetails)-mapAndCombineSM _ []     = return ([], emptyUDs)-mapAndCombineSM f (x:xs) = do (y, uds1) <- f x-                              (ys, uds2) <- mapAndCombineSM f xs-                              return (y:ys, uds1 `thenUDs` uds2)--extendTvSubst :: SpecEnv -> TyVar -> Type -> SpecEnv-extendTvSubst env tv ty-  = env { se_subst = Core.extendTvSubst (se_subst env) tv ty }--extendInScope :: SpecEnv -> OutId -> SpecEnv-extendInScope env@(SE { se_subst = subst }) bndr-  = env { se_subst = subst `Core.extendSubstInScope` bndr }--zapSubst :: SpecEnv -> SpecEnv-zapSubst env@(SE { se_subst = subst })-  = env { se_subst = Core.zapSubst subst }--substTy :: SpecEnv -> Type -> Type-substTy env ty = substTyUnchecked (se_subst env) ty--substCo :: SpecEnv -> Coercion -> Coercion-substCo env co = Core.substCo (se_subst env) co--substBndr :: SpecEnv -> CoreBndr -> (SpecEnv, CoreBndr)-substBndr env bs = case Core.substBndr (se_subst env) bs of-                      (subst', bs') -> (env { se_subst = subst' }, bs')--substBndrs :: SpecEnv -> [CoreBndr] -> (SpecEnv, [CoreBndr])-substBndrs env bs = case Core.substBndrs (se_subst env) bs of-                      (subst', bs') -> (env { se_subst = subst' }, bs')--cloneBndrSM :: SpecEnv -> Id -> SpecM (SpecEnv, Id)--- Clone the binders of the bind; return new bind with the cloned binders--- Return the substitution to use for RHSs, and the one to use for the body--- Discards non-Stable unfoldings-cloneBndrSM env@(SE { se_subst = subst }) bndr-  = do { us <- getUniqueSupplyM-       ; let (subst', bndr') = Core.cloneIdBndr subst us bndr-       ; return (env { se_subst = subst' }, bndr') }--cloneRecBndrsSM :: SpecEnv -> [Id] -> SpecM (SpecEnv, [Id])-cloneRecBndrsSM env@(SE { se_subst = subst }) bndrs-  = do { (subst', bndrs') <- Core.cloneRecIdBndrs subst bndrs-       ; let env' = env { se_subst = subst' }-       ; return (env', bndrs') }--newDictBndr :: SpecEnv -> CoreBndr -> SpecM (SpecEnv, CoreBndr)--- Make up completely fresh binders for the dictionaries--- Their bindings are going to float outwards-newDictBndr env@(SE { se_subst = subst }) b-  = do { uniq <- getUniqueM-       ; let n    = idName b-             ty'  = substTyUnchecked subst (idType b)-             b'   = mkUserLocal (nameOccName n) uniq ManyTy ty' (getSrcSpan n)-             env' = env { se_subst = subst `Core.extendSubstInScope` b' }-       ; pure (env', b') }+{-# LANGUAGE MultiWayIf #-}++{-+(c) The GRASP/AQUA Project, Glasgow University, 1993-1998++\section[Specialise]{Stamping out overloading, and (optionally) polymorphism}+-}++module GHC.Core.Opt.Specialise ( specProgram, specUnfolding ) where++import GHC.Prelude++import GHC.Driver.DynFlags+import GHC.Driver.Config+import GHC.Driver.Config.Diagnostic+import GHC.Driver.Config.Core.Rules ( initRuleOpts )++import GHC.Core.Type  hiding( substTy, substCo, extendTvSubst, zapSubst )+import GHC.Core.SimpleOpt( defaultSimpleOpts, simpleOptExprWith, exprIsConApp_maybe )+import GHC.Core.Predicate+import GHC.Core.Class( classMethods )+import GHC.Core.Coercion( Coercion )+import GHC.Core.Opt.Monad+import qualified GHC.Core.Subst as Core+import GHC.Core.Unfold.Make+import GHC.Core+import GHC.Core.Make      ( mkLitRubbish )+import GHC.Core.Unify     ( tcMatchTy )+import GHC.Core.Rules+import GHC.Core.Utils     ( exprIsTrivial, exprIsTopLevelBindable+                          , mkCast, exprType, exprIsHNF+                          , stripTicksTop, mkInScopeSetBndrs )+import GHC.Core.FVs+import GHC.Core.Opt.Arity( collectBindersPushingCo )++import GHC.Builtin.Types  ( unboxedUnitTy )++import GHC.Data.Maybe     ( isJust )+import GHC.Data.Bag+import GHC.Data.OrdList+import GHC.Data.List.SetOps++import GHC.Types.Basic+import GHC.Types.Unique.Supply+import GHC.Types.Unique.DFM+import GHC.Types.Name+import GHC.Types.Tickish+import GHC.Types.Id.Make  ( voidArgId, voidPrimId )+import GHC.Types.Var+import GHC.Types.Var.Set+import GHC.Types.Var.Env+import GHC.Types.Id+import GHC.Types.Id.Info+import GHC.Types.Error++import GHC.Utils.Error ( mkMCDiagnostic )+import GHC.Utils.Monad    ( foldlM )+import GHC.Utils.Misc+import GHC.Utils.FV+import GHC.Utils.Outputable+import GHC.Utils.Panic++import GHC.Unit.Module( Module )+import GHC.Unit.Module.ModGuts+import GHC.Core.Unfold++import Data.List( partition )+import Data.List.NonEmpty ( NonEmpty (..) )+import GHC.Core.Subst (substTickish)+import GHC.Core.TyCon (tyConClass_maybe)+import GHC.Core.DataCon (dataConTyCon)++{-+************************************************************************+*                                                                      *+\subsection[notes-Specialise]{Implementation notes [SLPJ, Aug 18 1993]}+*                                                                      *+************************************************************************++These notes describe how we implement specialisation to eliminate+overloading.++The specialisation pass works on Core+syntax, complete with all the explicit dictionary application,+abstraction and construction as added by the type checker.  The+existing type checker remains largely as it is.++One important thought: the {\em types} passed to an overloaded+function, and the {\em dictionaries} passed are mutually redundant.+If the same function is applied to the same type(s) then it is sure to+be applied to the same dictionary(s)---or rather to the same {\em+values}.  (The arguments might look different but they will evaluate+to the same value.)++Second important thought: we know that we can make progress by+treating dictionary arguments as static and worth specialising on.  So+we can do without binding-time analysis, and instead specialise on+dictionary arguments and no others.++The basic idea+~~~~~~~~~~~~~~+Suppose we have++        let f = <f_rhs>+        in <body>++and suppose f is overloaded.++STEP 1: CALL-INSTANCE COLLECTION++We traverse <body>, accumulating all applications of f to types and+dictionaries.++(Might there be partial applications, to just some of its types and+dictionaries?  In principle yes, but in practice the type checker only+builds applications of f to all its types and dictionaries, so partial+applications could only arise as a result of transformation, and even+then I think it's unlikely.  In any case, we simply don't accumulate such+partial applications.)+++STEP 2: EQUIVALENCES++So now we have a collection of calls to f:+        f t1 t2 d1 d2+        f t3 t4 d3 d4+        ...+Notice that f may take several type arguments.  To avoid ambiguity, we+say that f is called at type t1/t2 and t3/t4.++We take equivalence classes using equality of the *types* (ignoring+the dictionary args, which as mentioned previously are redundant).++STEP 3: SPECIALISATION++For each equivalence class, choose a representative (f t1 t2 d1 d2),+and create a local instance of f, defined thus:++        f@t1/t2 = <f_rhs> t1 t2 d1 d2++f_rhs presumably has some big lambdas and dictionary lambdas, so lots+of simplification will now result.  However we don't actually *do* that+simplification.  Rather, we leave it for the simplifier to do.  If we+*did* do it, though, we'd get more call instances from the specialised+RHS.  We can work out what they are by instantiating the call-instance+set from f's RHS with the types t1, t2.++Add this new id to f's IdInfo, to record that f has a specialised version.++Before doing any of this, check that f's IdInfo doesn't already+tell us about an existing instance of f at the required type/s.+(This might happen if specialisation was applied more than once, or+it might arise from user SPECIALIZE pragmas.)++Recursion+~~~~~~~~~+Wait a minute!  What if f is recursive?  Then we can't just plug in+its right-hand side, can we?++But it's ok.  The type checker *always* creates non-recursive definitions+for overloaded recursive functions.  For example:++        f x = f (x+x)           -- Yes I know its silly++becomes++        f a (d::Num a) = let p = +.sel a d+                         in+                         letrec fl (y::a) = fl (p y y)+                         in+                         fl++We still have recursion for non-overloaded functions which we+specialise, but the recursive call should get specialised to the+same recursive version.+++Polymorphism 1+~~~~~~~~~~~~~~++All this is crystal clear when the function is applied to *constant+types*; that is, types which have no type variables inside.  But what if+it is applied to non-constant types?  Suppose we find a call of f at type+t1/t2.  There are two possibilities:++(a) The free type variables of t1, t2 are in scope at the definition point+of f.  In this case there's no problem, we proceed just as before.  A common+example is as follows.  Here's the Haskell:++        g y = let f x = x+x+              in f y + f y++After typechecking we have++        g a (d::Num a) (y::a) = let f b (d'::Num b) (x::b) = +.sel b d' x x+                                in +.sel a d (f a d y) (f a d y)++Notice that the call to f is at type type "a"; a non-constant type.+Both calls to f are at the same type, so we can specialise to give:++        g a (d::Num a) (y::a) = let f@a (x::a) = +.sel a d x x+                                in +.sel a d (f@a y) (f@a y)+++(b) The other case is when the type variables in the instance types+are *not* in scope at the definition point of f.  The example we are+working with above is a good case.  There are two instances of (+.sel a d),+but "a" is not in scope at the definition of +.sel.  Can we do anything?+Yes, we can "common them up", a sort of limited common sub-expression deal.+This would give:++        g a (d::Num a) (y::a) = let +.sel@a = +.sel a d+                                    f@a (x::a) = +.sel@a x x+                                in +.sel@a (f@a y) (f@a y)++This can save work, and can't be spotted by the type checker, because+the two instances of +.sel weren't originally at the same type.++Further notes on (b)++* There are quite a few variations here.  For example, the defn of+  +.sel could be floated outside the \y, to attempt to gain laziness.+  It certainly mustn't be floated outside the \d because the d has to+  be in scope too.++* We don't want to inline f_rhs in this case, because+that will duplicate code.  Just commoning up the call is the point.++* Nothing gets added to +.sel's IdInfo.++* Don't bother unless the equivalence class has more than one item!++Not clear whether this is all worth it.  It is of course OK to+simply discard call-instances when passing a big lambda.++Polymorphism 2 -- Overloading+~~~~~~~~~~~~~~+Consider a function whose most general type is++        f :: forall a b. Ord a => [a] -> b -> b++There is really no point in making a version of g at Int/Int and another+at Int/Bool, because it's only instantiating the type variable "a" which+buys us any efficiency. Since g is completely polymorphic in b there+ain't much point in making separate versions of g for the different+b types.++That suggests that we should identify which of g's type variables+are constrained (like "a") and which are unconstrained (like "b").+Then when taking equivalence classes in STEP 2, we ignore the type args+corresponding to unconstrained type variable.  In STEP 3 we make+polymorphic versions.  Thus:++        f@t1/ = /\b -> <f_rhs> t1 b d1 d2++We do this.+++Dictionary floating+~~~~~~~~~~~~~~~~~~~+Consider this++        f a (d::Num a) = let g = ...+                         in+                         ...(let d1::Ord a = Num.Ord.sel a d in g a d1)...++Here, g is only called at one type, but the dictionary isn't in scope at the+definition point for g.  Usually the type checker would build a+definition for d1 which enclosed g, but the transformation system+might have moved d1's defn inward.  Solution: float dictionary bindings+outwards along with call instances.++Consider++        f x = let g p q = p==q+                  h r s = (r+s, g r s)+              in+              h x x+++Before specialisation, leaving out type abstractions we have++        f df x = let g :: Eq a => a -> a -> Bool+                     g dg p q = == dg p q+                     h :: Num a => a -> a -> (a, Bool)+                     h dh r s = let deq = eqFromNum dh+                                in (+ dh r s, g deq r s)+              in+              h df x x++After specialising h we get a specialised version of h, like this:++                    h' r s = let deq = eqFromNum df+                             in (+ df r s, g deq r s)++But we can't naively make an instance for g from this, because deq is not in scope+at the defn of g.  Instead, we have to float out the (new) defn of deq+to widen its scope.  Notice that this floating can't be done in advance -- it only+shows up when specialisation is done.++User SPECIALIZE pragmas+~~~~~~~~~~~~~~~~~~~~~~~+Specialisation pragmas can be digested by the type checker, and implemented+by adding extra definitions along with that of f, in the same way as before++        f@t1/t2 = <f_rhs> t1 t2 d1 d2++Indeed the pragmas *have* to be dealt with by the type checker, because+only it knows how to build the dictionaries d1 and d2!  For example++        g :: Ord a => [a] -> [a]+        {-# SPECIALIZE f :: [Tree Int] -> [Tree Int] #-}++Here, the specialised version of g is an application of g's rhs to the+Ord dictionary for (Tree Int), which only the type checker can conjure+up.  There might not even *be* one, if (Tree Int) is not an instance of+Ord!  (All the other specialisation has suitable dictionaries to hand+from actual calls.)++Problem.  The type checker doesn't have to hand a convenient <f_rhs>, because+it is buried in a complex (as-yet-un-desugared) binding group.+Maybe we should say++        f@t1/t2 = f* t1 t2 d1 d2++where f* is the Id f with an IdInfo which says "inline me regardless!".+Indeed all the specialisation could be done in this way.+That in turn means that the simplifier has to be prepared to inline absolutely+any in-scope let-bound thing.+++Again, the pragma should permit polymorphism in unconstrained variables:++        h :: Ord a => [a] -> b -> b+        {-# SPECIALIZE h :: [Int] -> b -> b #-}++We *insist* that all overloaded type variables are specialised to ground types,+(and hence there can be no context inside a SPECIALIZE pragma).+We *permit* unconstrained type variables to be specialised to+        - a ground type+        - or left as a polymorphic type variable+but nothing in between.  So++        {-# SPECIALIZE h :: [Int] -> [c] -> [c] #-}++is *illegal*.  (It can be handled, but it adds complication, and gains the+programmer nothing.)+++SPECIALISING INSTANCE DECLARATIONS+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+Consider++        instance Foo a => Foo [a] where+                ...+        {-# SPECIALIZE instance Foo [Int] #-}++The original instance decl creates a dictionary-function+definition:++        dfun.Foo.List :: forall a. Foo a -> Foo [a]++The SPECIALIZE pragma just makes a specialised copy, just as for+ordinary function definitions:++        dfun.Foo.List@Int :: Foo [Int]+        dfun.Foo.List@Int = dfun.Foo.List Int dFooInt++The information about what instance of the dfun exist gets added to+the dfun's IdInfo in the same way as a user-defined function too.+++Automatic instance decl specialisation?+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+Can instance decls be specialised automatically?  It's tricky.+We could collect call-instance information for each dfun, but+then when we specialised their bodies we'd get new call-instances+for ordinary functions; and when we specialised their bodies, we might get+new call-instances of the dfuns, and so on.  This all arises because of+the unrestricted mutual recursion between instance decls and value decls.++Still, there's no actual problem; it just means that we may not do all+the specialisation we could theoretically do.++Furthermore, instance decls are usually exported and used non-locally,+so we'll want to compile enough to get those specialisations done.++Lastly, there's no such thing as a local instance decl, so we can+survive solely by spitting out *usage* information, and then reading that+back in as a pragma when next compiling the file.  So for now,+we only specialise instance decls in response to pragmas.+++SPITTING OUT USAGE INFORMATION+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~++To spit out usage information we need to traverse the code collecting+call-instance information for all imported (non-prelude?) functions+and data types. Then we equivalence-class it and spit it out.++This is done at the top-level when all the call instances which escape+must be for imported functions and data types.++*** Not currently done ***+++Partial specialisation by pragmas+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+What about partial specialisation:++        k :: (Ord a, Eq b) => [a] -> b -> b -> [a]+        {-# SPECIALIZE k :: Eq b => [Int] -> b -> b -> [a] #-}++or even++        {-# SPECIALIZE k :: Eq b => [Int] -> [b] -> [b] -> [a] #-}++Seems quite reasonable.  Similar things could be done with instance decls:++        instance (Foo a, Foo b) => Foo (a,b) where+                ...+        {-# SPECIALIZE instance Foo a => Foo (a,Int) #-}+        {-# SPECIALIZE instance Foo b => Foo (Int,b) #-}++Ho hum.  Things are complex enough without this.  I pass.+++Requirements for the simplifier+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+The simplifier has to be able to take advantage of the specialisation.++* When the simplifier finds an application of a polymorphic f, it looks in+f's IdInfo in case there is a suitable instance to call instead.  This converts++        f t1 t2 d1 d2   ===>   f_t1_t2++Note that the dictionaries get eaten up too!++* Dictionary selection operations on constant dictionaries must be+  short-circuited:++        +.sel Int d     ===>  +Int++The obvious way to do this is in the same way as other specialised+calls: +.sel has inside it some IdInfo which tells that if it's applied+to the type Int then it should eat a dictionary and transform to +Int.++In short, dictionary selectors need IdInfo inside them for constant+methods.++* Exactly the same applies if a superclass dictionary is being+  extracted:++        Eq.sel Int d   ===>   dEqInt++* Something similar applies to dictionary construction too.  Suppose+dfun.Eq.List is the function taking a dictionary for (Eq a) to+one for (Eq [a]).  Then we want++        dfun.Eq.List Int d      ===> dEq.List_Int++Where does the Eq [Int] dictionary come from?  It is built in+response to a SPECIALIZE pragma on the Eq [a] instance decl.++In short, dfun Ids need IdInfo with a specialisation for each+constant instance of their instance declaration.++All this uses a single mechanism: the SpecEnv inside an Id+++What does the specialisation IdInfo look like?+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~++The SpecEnv of an Id maps a list of types (the template) to an expression++        [Type]  |->  Expr++For example, if f has this RuleInfo:++        [Int, a]  ->  \d:Ord Int. f' a++it means that we can replace the call++        f Int t  ===>  (\d. f' t)++This chucks one dictionary away and proceeds with the+specialised version of f, namely f'.+++What can't be done this way?+~~~~~~~~~~~~~~~~~~~~~~~~~~~~+There is no way, post-typechecker, to get a dictionary for (say)+Eq a from a dictionary for Eq [a].  So if we find++        ==.sel [t] d++we can't transform to++        eqList (==.sel t d')++where+        eqList :: (a->a->Bool) -> [a] -> [a] -> Bool++Of course, we currently have no way to automatically derive+eqList, nor to connect it to the Eq [a] instance decl, but you+can imagine that it might somehow be possible.  Taking advantage+of this is permanently ruled out.++Still, this is no great hardship, because we intend to eliminate+overloading altogether anyway!++A note about non-tyvar dictionaries+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+Some Ids have types like++        forall a,b,c. Eq a -> Ord [a] -> tau++This seems curious at first, because we usually only have dictionary+args whose types are of the form (C a) where a is a type variable.+But this doesn't hold for the functions arising from instance decls,+which sometimes get arguments with types of form (C (T a)) for some+type constructor T.++Should we specialise wrt this compound-type dictionary?  We used to say+"no", saying:+        "This is a heuristic judgement, as indeed is the fact that we+        specialise wrt only dictionaries.  We choose *not* to specialise+        wrt compound dictionaries because at the moment the only place+        they show up is in instance decls, where they are simply plugged+        into a returned dictionary.  So nothing is gained by specialising+        wrt them."++But it is simpler and more uniform to specialise wrt these dicts too;+and in future GHC is likely to support full fledged type signatures+like+        f :: Eq [(a,b)] => ...+++Note [Specialisation and overlapping instances]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+Here is at tricky case (see a comment in MR !8916):++    module A where+      class C a where+        meth :: a -> String+      instance {-# OVERLAPPABLE #-} C (Maybe a) where+        meth _ = "Maybe"++      {-# SPECIALISE f :: Maybe a -> Bool -> String #-}+      f :: C a => a -> Bool -> String+      f a True = f a False+      f a _    = meth a++    module B where+      import A++      instance C (Maybe Int) where+        meth _ = "Int"++      main = putStrLn $ f (Just 42 :: Maybe Int) True++Running main without optimisations yields "Int", the correct answer.+Activating optimisations yields "Maybe" due to a rewrite rule in module+A generated by the SPECIALISE pragma:++    RULE "USPEC f" forall a (d :: C a). f @a d = $sf++In B we get the call (f @(Maybe Int) (d :: C (Maybe Int))), and+that rewrites to $sf, but that isn't really right.++Overlapping instances mean that `C (Maybe Int)` is not a singleton+type: there two distinct dictionaries that have this type.  And that+spells trouble for specialistion, which really asssumes singleton+types.++For now, we just accept this problem, but it may bite us one day.+One solution would be to decline to expose any specialisation rules+to an importing module -- but that seems a bit drastic.+++************************************************************************+*                                                                      *+\subsubsection{The new specialiser}+*                                                                      *+************************************************************************++Our basic game plan is this.  For let(rec) bound function+        f :: (C a, D c) => (a,b,c,d) -> Bool++* Find any specialised calls of f, (f ts ds), where+  ts are the type arguments t1 .. t4, and+  ds are the dictionary arguments d1 .. d2.++* Add a new definition for f1 (say):++        f1 = /\ b d -> (..body of f..) t1 b t3 d d1 d2++  Note that we abstract over the unconstrained type arguments.++* Add the mapping++        [t1,b,t3,d]  |->  \d1 d2 -> f1 b d++  to the specialisations of f.  This will be used by the+  simplifier to replace calls+                (f t1 t2 t3 t4) da db+  by+                (\d1 d1 -> f1 t2 t4) da db++  All the stuff about how many dictionaries to discard, and what types+  to apply the specialised function to, are handled by the fact that the+  SpecEnv contains a template for the result of the specialisation.++We don't build *partial* specialisations for f.  For example:++  f :: Eq a => a -> a -> Bool+  {-# SPECIALISE f :: (Eq b, Eq c) => (b,c) -> (b,c) -> Bool #-}++Here, little is gained by making a specialised copy of f.+There's a distinct danger that the specialised version would+first build a dictionary for (Eq b, Eq c), and then select the (==)+method from it!  Even if it didn't, not a great deal is saved.++We do, however, generate polymorphic, but not overloaded, specialisations:++  f :: Eq a => [a] -> b -> b -> b+  ... SPECIALISE f :: [Int] -> b -> b -> b ...++Hence, the invariant is this:++        *** no specialised version is overloaded ***+++************************************************************************+*                                                                      *+\subsubsection{The exported function}+*                                                                      *+************************************************************************+-}++-- | Specialise calls to type-class overloaded functions occurring in a program.+specProgram :: ModGuts -> CoreM ModGuts+specProgram guts@(ModGuts { mg_module = this_mod+                          , mg_rules  = local_rules+                          , mg_binds  = binds })+  = do { dflags   <- getDynFlags+       ; rule_env <- initRuleEnv guts+                     -- See Note [Fire rules in the specialiser]++              -- We need to start with a Subst that knows all the things+              -- that are in scope, so that the substitution engine doesn't+              -- accidentally re-use a unique that's already in use+              -- Easiest thing is to do it all at once, as if all the top-level+              -- decls were mutually recursive+       ; let top_env = SE { se_subst = Core.mkEmptySubst $+                                        mkInScopeSetBndrs binds+                                      --    mkInScopeSetList $+                                      --  bindersOfBinds binds+                          , se_module = this_mod+                          , se_rules  = rule_env+                          , se_dflags = dflags }++             go []           = return ([], emptyUDs)+             go (bind:binds) = do (bind', binds', uds') <- specBind TopLevel top_env bind $ \_ ->+                                                           go binds+                                  return (bind' ++ binds', uds')++             -- Specialise the bindings of this module+       ; (binds', uds) <- runSpecM (go binds)++       ; (spec_rules, spec_binds) <- specImports top_env uds++       ; return (guts { mg_binds = spec_binds ++ binds'+                      , mg_rules = spec_rules ++ local_rules }) }++{-+Note [Wrap bindings returned by specImports]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+'specImports' returns a set of specialized bindings. However, these are lacking+necessary floated dictionary bindings, which are returned by+UsageDetails(ud_binds). These dictionaries need to be brought into scope with+'wrapDictBinds' before the bindings returned by 'specImports' can be used. See,+for instance, the 'specImports' call in 'specProgram'.+++Note [Disabling cross-module specialisation]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+Since GHC 7.10 we have performed specialisation of INLINABLE bindings living+in modules outside of the current module. This can sometimes uncover user code+which explodes in size when aggressively optimized. The+-fno-cross-module-specialise option was introduced to allow users to being+bitten by such instances to revert to the pre-7.10 behavior.++See #10491+-}+++{- *********************************************************************+*                                                                      *+                   Specialising imported functions+*                                                                      *+********************************************************************* -}++{- Note [Specialising imported functions]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+specImports specialises imported functions, based on calls in this module.++When -fspecialise-aggressively is on, we specialise any imported+function for which we have an unfolding.  The+-fspecialise-aggressively flag is usually off, because we risk lots of+orphan modules from over-vigorous specialisation.  (See Note [Orphans]+in GHC.Core.) However it's not a big deal: anything non-recursive with+an unfolding-template will probably have been inlined already.++When -fspecialise-aggressively is off, we are more selective about+specialisation (see canSpecImport):++(1) Without -fspecialise-aggressively, do not specialise+    DFunUnfoldings. Note [Do not specialise imported DFuns].++(2) Without -fspecialise-aggressively, specialise only imported things+    that have a /user-supplied/ INLINE or INLINABLE pragma (hence+    isAnyInlinePragma rather than isStableSource).++    In particular, we don't want to specialise workers created by+    worker/wrapper (for functions with no pragma) because they won't+    specialise usefully, and they generate quite a bit of useless code+    bloat.++    Specialise even INLINE things; it hasn't inlined yet, so perhaps+    it never will.  Moreover it may have calls inside it that we want+    to specialise++Wrinkle (W1): If we specialise an imported Id M.foo, we make a /local/+binding $sfoo.  But specImports may further specialise $sfoo. So we end up+with RULES for both M.foo (imported) and $sfoo (local).  Rules for local+Ids should be attached to the Ids themselves (see GHC.HsToCore+Note [Attach rules to local ids]); so we must partition the rules and+attach the local rules.  That is done in specImports, via addRulesToId.++Note [Glom the bindings if imported functions are specialised]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+Suppose we have an imported, *recursive*, INLINABLE function+   f :: Eq a => a -> a+   f = /\a \d x. ...(f a d)...+In the module being compiled we have+   g x = f (x::Int)+Now we'll make a specialised function+   f_spec :: Int -> Int+   f_spec = \x -> ...(f Int dInt)...+   {-# RULE  f Int _ = f_spec #-}+   g = \x. f Int dInt x+Note that f_spec doesn't look recursive+After rewriting with the RULE, we get+   f_spec = \x -> ...(f_spec)...+BUT since f_spec was non-recursive before it'll *stay* non-recursive.+The occurrence analyser never turns a NonRec into a Rec.  So we must+make sure that f_spec is recursive.  Easiest thing is to make all+the specialisations for imported bindings recursive.+-}++specImports :: SpecEnv+            -> UsageDetails+            -> CoreM ([CoreRule], [CoreBind])+specImports top_env (MkUD { ud_binds = dict_binds, ud_calls = calls })+  | not $ gopt Opt_CrossModuleSpecialise (se_dflags top_env)+    -- See Note [Disabling cross-module specialisation]+  = return ([], wrapDictBinds dict_binds [])++  | otherwise+  = do { let env_w_dict_bndrs = top_env `bringFloatedDictsIntoScope` dict_binds+       ; (_env, spec_rules, spec_binds) <- spec_imports env_w_dict_bndrs [] dict_binds calls++             -- Make a Rec: see Note [Glom the bindings if imported functions are specialised]+             --+             -- wrapDictBinds: don't forget to wrap the specialized bindings with+             --   bindings for the needed dictionaries.+             --   See Note [Wrap bindings returned by specImports]+             --+             -- addRulesToId: see Wrinkle (W1) in Note [Specialising imported functions]+             --               c.f. GHC.HsToCore.addExportFlagsAndRules+       ; let (rules_for_locals, rules_for_imps) = partition isLocalRule spec_rules+             local_rule_base = extendRuleBaseList emptyRuleBase rules_for_locals+             final_binds+               | null spec_binds = wrapDictBinds dict_binds []+               | otherwise       = [Rec $ mapFst (addRulesToId local_rule_base) $+                                          flattenBinds                          $+                                          wrapDictBinds dict_binds              $+                                          spec_binds]++       ; return (rules_for_imps, final_binds)+    }++-- | Specialise a set of calls to imported bindings+spec_imports :: SpecEnv          -- Passed in so that all top-level Ids are in scope+                                 ---In-scope set includes the FloatedDictBinds+             -> [Id]             -- Stack of imported functions being specialised+                                 -- See Note [specImport call stack]+             -> FloatedDictBinds -- Dict bindings, used /only/ for filterCalls+                                 -- See Note [Avoiding loops in specImports]+             -> CallDetails      -- Calls for imported things+             -> CoreM ( SpecEnv      -- Env contains the new rules+                      , [CoreRule]   -- New rules+                      , [CoreBind] ) -- Specialised bindings+spec_imports env callers dict_binds calls+  = do { let import_calls = dVarEnvElts calls+--       ; debugTraceMsg (text "specImports {" <+>+--                         vcat [ text "calls:" <+> ppr import_calls+--                              , text "dict_binds:" <+> ppr dict_binds ])+       ; (env, rules, spec_binds) <- go env import_calls+--       ; debugTraceMsg (text "End specImports }" <+> ppr import_calls)++       ; return (env, rules, spec_binds) }+  where+    go :: SpecEnv -> [CallInfoSet] -> CoreM (SpecEnv, [CoreRule], [CoreBind])+    go env [] = return (env, [], [])+    go env (cis : other_calls)+      = do { -- debugTraceMsg (text "specImport {" <+> ppr cis)+           ; (env, rules1, spec_binds1) <- spec_import env callers dict_binds cis+           ; -- debugTraceMsg (text "specImport }" <+> ppr cis)++           ; (env, rules2, spec_binds2) <- go env other_calls+           ; return (env, rules1 ++ rules2, spec_binds1 ++ spec_binds2) }++spec_import :: SpecEnv               -- Passed in so that all top-level Ids are in scope+                                     ---In-scope set includes the FloatedDictBinds+            -> [Id]                  -- Stack of imported functions being specialised+                                     -- See Note [specImport call stack]+            -> FloatedDictBinds      -- Dict bindings, used /only/ for filterCalls+                                     -- See Note [Avoiding loops in specImports]+            -> CallInfoSet           -- Imported function and calls for it+            -> CoreM ( SpecEnv+                     , [CoreRule]    -- New rules+                     , [CoreBind] )  -- Specialised bindings+spec_import env callers dict_binds cis@(CIS fn _)+  | isIn "specImport" fn callers+  = return (env, [], [])  -- No warning.  This actually happens all the time+                          -- when specialising a recursive function, because+                          -- the RHS of the specialised function contains a recursive+                          -- call to the original function++  | null good_calls+  = return (env, [], [])++  | Just rhs <- canSpecImport dflags fn+  = do {     -- Get rules from the external package state+             -- We keep doing this in case we "page-fault in"+             -- more rules as we go along+       ; eps_rules <- getExternalRuleBase+       ; let rule_env = se_rules env `updExternalPackageRules` eps_rules++--       ; debugTraceMsg (text "specImport1" <+> vcat+--           [ text "function:" <+> ppr fn+--           , text "good calls:" <+> ppr good_calls+--           , text "existing rules:" <+> ppr (getRules rule_env fn)+--           , text "rhs:" <+> ppr rhs+--           , text "dict_binds:" <+> ppr dict_binds ])++       ; (rules1, spec_pairs, MkUD { ud_binds = dict_binds1, ud_calls = new_calls })+            <- runSpecM $ specCalls True env (getRules rule_env fn) good_calls fn rhs++       ; let spec_binds1 = [NonRec b r | (b,r) <- spec_pairs]+             -- After the rules kick in, via fireRewriteRules, we may get recursion,+             -- but we rely on a global GlomBinds to sort that out later+             -- See Note [Glom the bindings if imported functions are specialised]+             -- Meanwhile, though, bring the binders into scope++             new_subst = se_subst env `Core.extendSubstInScopeList` map fst spec_pairs+             new_env   = env { se_rules = rule_env `addLocalRules` rules1+                             , se_subst = new_subst }+                         `bringFloatedDictsIntoScope` dict_binds1++       -- Now specialise any cascaded calls+--       ; debugTraceMsg (text "specImport 2" <+> vcat+--           [ text "function:" <+> ppr fn+--           , text "rules1:" <+> ppr rules1+--           , text "spec_binds1" <+> ppr spec_binds1+--           , text "dict_binds1" <+> ppr dict_binds1+--           , text "new_calls" <+> ppr new_calls ])++       ; (env, rules2, spec_binds2)+            <- spec_imports new_env (fn:callers)+                                    (dict_binds `thenFDBs` dict_binds1)+                                    new_calls++       ; let final_binds = wrapDictBinds dict_binds1 $+                           spec_binds2 ++ spec_binds1++       ; return (env, rules2 ++ rules1, final_binds) }++  | otherwise+  = do { tryWarnMissingSpecs dflags callers fn good_calls+       ; return (env, [], [])}++  where+    dflags = se_dflags env+    good_calls = filterCalls cis dict_binds+       -- SUPER IMPORTANT!  Drop calls that (directly or indirectly) refer to fn+       -- See Note [Avoiding loops in specImports]++canSpecImport :: DynFlags -> Id -> Maybe CoreExpr+canSpecImport dflags fn+  | isDataConWrapId fn+  = Nothing   -- Don't specialise data-con wrappers, even if they+              -- have dict args; there is no benefit.++  | CoreUnfolding { uf_tmpl = rhs } <- unf+    -- CoreUnfolding: see Note [Specialising imported functions] point (1).+  , isAnyInlinePragma (idInlinePragma fn)+    -- See Note [Specialising imported functions] point (2).+  = Just rhs++  | gopt Opt_SpecialiseAggressively dflags+  = maybeUnfoldingTemplate unf+    -- With -fspecialise-aggressively, specialise anything+    -- with an unfolding, stable or not, DFun or not++  | otherwise = Nothing+  where+    unf = realIdUnfolding fn   -- We want to see the unfolding even for loop breakers++-- | Returns whether or not to show a missed-spec warning.+-- If -Wall-missed-specializations is on, show the warning.+-- Otherwise, if -Wmissed-specializations is on, only show a warning+-- if there is at least one imported function being specialized,+-- and if all imported functions are marked with an inline pragma+-- Use the most specific warning as the reason.+tryWarnMissingSpecs :: DynFlags -> [Id] -> Id -> [CallInfo] -> CoreM ()+-- See Note [Warning about missed specialisations]+tryWarnMissingSpecs dflags callers fn calls_for_fn+  | isClassOpId fn = return () -- See Note [Missed specialisation for ClassOps]+  | wopt Opt_WarnMissedSpecs dflags+    && not (null callers)+    && allCallersInlined                  = doWarn $ WarningWithFlag Opt_WarnMissedSpecs+  | wopt Opt_WarnAllMissedSpecs dflags    = doWarn $ WarningWithFlag Opt_WarnAllMissedSpecs+  | otherwise                             = return ()+  where+    allCallersInlined = all (isAnyInlinePragma . idInlinePragma) callers+    diag_opts = initDiagOpts dflags+    doWarn reason =+      msg (mkMCDiagnostic diag_opts reason Nothing)+        (vcat [ hang (text ("Could not specialise imported function") <+> quotes (ppr fn))+                2 (vcat [ text "when specialising" <+> quotes (ppr caller)+                        | caller <- callers])+          , whenPprDebug (text "calls:" <+> vcat (map (pprCallInfo fn) calls_for_fn))+          , text "Probable fix: add INLINABLE pragma on" <+> quotes (ppr fn) ])++{- Note [Missed specialisation for ClassOps]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+In #19592 I saw a number of missed specialisation warnings+which were the result of things like:++    case isJumpishInstr @X86.Instr $dInstruction_s7f8 eta3_a78C of { ...++where isJumpishInstr is part of the Instruction class and defined like+this:++    class Instruction instr where+        ...+        isJumpishInstr :: instr -> Bool+        ...++isJumpishInstr is a ClassOp which will select the right method+from within the dictionary via our built in rules. See also+Note [ClassOp/DFun selection] in GHC.Tc.TyCl.Instance.++We don't give these unfoldings, and as a result the specialiser+complains. But usually this doesn't matter. The simplifier will+apply the rule and we end up with++    case isJumpishInstrImplX86 eta3_a78C of { ...++Since isJumpishInstrImplX86 is defined for a concrete instance (given+by the dictionary) it is usually already well specialised!+Theoretically the implementation of a method could still be overloaded+over a different type class than what it's a method of. But I wasn't able+to make this go wrong, and SPJ thinks this should be fine as well.++So I decided to remove the warnings for failed specialisations on ClassOps+alltogether as they do more harm than good.+-}++{- Note [Do not specialise imported DFuns]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+Ticket #18223 shows that specialising calls of DFuns is can cause a huge+and entirely unnecessary blowup in program size.  Consider a call to+    f @[[[[[[[[T]]]]]]]] d1 x+where df :: C a => C [a]+      d1 :: C [[[[[[[[T]]]]]]]] = dfC[] @[[[[[[[T]]]]]]] d1+      d2 :: C [[[[[[[T]]]]]]]   = dfC[] @[[[[[[T]]]]]] d3+      ...+Now we'll specialise f's RHS, which may give rise to calls to 'g',+also overloaded, which we will specialise, and so on.  However, if+we specialise the calls to dfC[], we'll generate specialised copies of+all methods of C, at all types; and the same for C's superclasses.++And many of these specialised functions will never be called.  We are+going to call the specialised 'f', and the specialised 'g', but DFuns+group functions into a tuple, many of whose elements may never be used.++With deeply-nested types this can lead to a simply overwhelming number+of specialisations: see #18223 for a simple example (from the wild).+I measured the number of specialisations for various numbers of calls+of `flip evalStateT ()`, and got this++                       Size after one simplification+  #calls    #SPEC rules    Terms     Types+      5         56          3100     10600+      9        108         13660     77206++The real tests case has 60+ calls, which blew GHC out of the water.++Solution: don't specialise DFuns.  The downside is that if we end+up with (h (dfun d)), /and/ we don't specialise 'h', then we won't+pass to 'h' a tuple of specialised functions.++However, the flag -fspecialise-aggressively (experimental, off by default)+allows DFuns to specialise as well.++Note [Avoiding loops in specImports]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+We must take great care when specialising instance declarations+(DFuns like $fOrdList) lest we accidentally build a recursive+dictionary. See Note [Avoiding loops (DFuns)].++The basic strategy of Note [Avoiding loops (DFuns)] is to use filterCalls+to discard loopy specialisations.  But to do that we must ensure+that the in-scope dict-binds (passed to filterCalls) contains+all the needed dictionary bindings.  In particular, in the recursive+call to spec_imports in spec_import, we must include the dict-binds+from the parent.  Lacking this caused #17151, a really nasty bug.++Here is what happened.+* Class structure:+    Source is a superclass of Mut+    Index is a superclass of Source++* We started with these dict binds+    dSource = $fSourcePix @Int $fIndexInt+    dIndex  = sc_sel dSource+    dMut    = $fMutPix @Int dIndex+  and these calls to specialise+    $fMutPix @Int dIndex+    $fSourcePix @Int $fIndexInt++* We specialised the call ($fMutPix @Int dIndex)+  ==> new call ($fSourcePix @Int dIndex)+      (because Source is a superclass of Mut)++* We specialised ($fSourcePix @Int dIndex)+  ==> produces specialised dict $s$fSourcePix,+      a record with dIndex as a field+      plus RULE forall d. ($fSourcePix @Int d) = $s$fSourcePix+  *** This is the bogus step ***++* Now we decide not to specialise the call+    $fSourcePix @Int $fIndexInt+  because we alredy have a RULE that matches it++* Finally the simplifer rewrites+    dSource = $fSourcePix @Int $fIndexInt+    ==>  dSource = $s$fSourcePix++Disaster. Now we have++Rewrite dSource's RHS to $s$fSourcePix   Disaster+    dSource = $s$fSourcePix+    dIndex  = sc_sel dSource+    $s$fSourcePix = MkSource dIndex ...++Solution: filterCalls should have stopped the bogus step,+by seeing that dIndex transitively uses $fSourcePix. But+it can only do that if it sees all the dict_binds.  Wow.++--------------+Here's another example (#13429).  Suppose we have+  class Monoid v => C v a where ...++We start with a call+   f @ [Integer] @ Integer $fC[]Integer++Specialising call to 'f' gives dict bindings+   $dMonoid_1 :: Monoid [Integer]+   $dMonoid_1 = M.$p1C @ [Integer] $fC[]Integer++   $dC_1 :: C [Integer] (Node [Integer] Integer)+   $dC_1 = M.$fCvNode @ [Integer] $dMonoid_1++...plus a recursive call to+   f @ [Integer] @ (Node [Integer] Integer) $dC_1++Specialising that call gives+   $dMonoid_2  :: Monoid [Integer]+   $dMonoid_2  = M.$p1C @ [Integer] $dC_1++   $dC_2 :: C [Integer] (Node [Integer] Integer)+   $dC_2 = M.$fCvNode @ [Integer] $dMonoid_2++Now we have two calls to the imported function+  M.$fCvNode :: Monoid v => C v a+  M.$fCvNode @v @a m = C m some_fun++But we must /not/ use the call (M.$fCvNode @ [Integer] $dMonoid_2)+for specialisation, else we get:++  $dC_1 = M.$fCvNode @ [Integer] $dMonoid_1+  $dMonoid_2 = M.$p1C @ [Integer] $dC_1+  $s$fCvNode = C $dMonoid_2 ...+    RULE M.$fCvNode [Integer] _ _ = $s$fCvNode++Now use the rule to rewrite the call in the RHS of $dC_1+and we get a loop!+++Note [specImport call stack]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+When specialising an imports function 'f', we may get new calls+of an imported function 'g', which we want to specialise in turn,+and similarly specialising 'g' might expose a new call to 'h'.++We track the stack of enclosing functions. So when specialising 'h' we+have a specImport call stack of [g,f]. We do this for two reasons:+* Note [Warning about missed specialisations]+* Note [Avoiding recursive specialisation]++Note [Warning about missed specialisations]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+Suppose+ * In module Lib, you carefully mark a function 'foo' INLINABLE+ * Import Lib(foo) into another module M+ * Call 'foo' at some specialised type in M+Then you jolly well expect it to be specialised in M.  But what if+'foo' calls another function 'Lib.bar'.  Then you'd like 'bar' to be+specialised too.  But if 'bar' is not marked INLINABLE it may well+not be specialised.  The warning Opt_WarnMissedSpecs warns about this.++It's more noisy to warning about a missed specialisation opportunity+for /every/ overloaded imported function, but sometimes useful. That+is what Opt_WarnAllMissedSpecs does.++ToDo: warn about missed opportunities for local functions.++Note [Avoiding recursive specialisation]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+When we specialise 'f' we may find new overloaded calls to 'g', 'h' in+'f's RHS.  So we want to specialise g,h.  But we don't want to+specialise f any more!  It's possible that f's RHS might have a+recursive yet-more-specialised call, so we'd diverge in that case.+And if the call is to the same type, one specialisation is enough.+Avoiding this recursive specialisation loop is one reason for the+'callers' stack passed to specImports and specImport.+++************************************************************************+*                                                                      *+\subsubsection{@specExpr@: the main function}+*                                                                      *+************************************************************************+-}++data SpecEnv+  = SE { se_subst :: Core.Subst+             -- We carry a substitution down:+             -- a) we must clone any binding that might float outwards,+             --    to avoid name clashes+             -- b) we carry a type substitution to use when analysing+             --    the RHS of specialised bindings (no type-let!)++       , se_module :: Module+       , se_rules  :: RuleEnv  -- From the home package and this module+       , se_dflags :: DynFlags+     }++instance Outputable SpecEnv where+  ppr (SE { se_subst = subst })+    = text "SE" <+> braces (text "subst =" <+> ppr subst)++specVar :: SpecEnv -> InId -> SpecM (OutExpr, UsageDetails)+specVar env@(SE { se_subst = Core.Subst in_scope ids _ _ }) v+  | not (isLocalId v)                   = return (Var v, emptyUDs)+  | Just e  <- lookupVarEnv ids       v = specExpr (zapSubst env) e  -- Note (1)+  | Just v' <- lookupInScope in_scope v = return (Var v', emptyUDs)+  | otherwise = pprPanic "specVar" (ppr v $$ ppr in_scope)+  -- c.f. GHC.Core.Subst.lookupIdSubst+  -- Note (1): we recurse so we do the lookupInScope thing on any Vars in e+  --           probably has little effect, but it's the right thing.+  --           We need zapSubst because `e` is an OutExpr++specExpr :: SpecEnv -> CoreExpr -> SpecM (CoreExpr, UsageDetails)++---------------- First the easy cases --------------------+specExpr env (Var v)       = specVar env v+specExpr env (Type ty)     = return (Type     (substTy env ty), emptyUDs)+specExpr env (Coercion co) = return (Coercion (substCo env co), emptyUDs)+specExpr _   (Lit lit)     = return (Lit lit,                   emptyUDs)+specExpr env (Cast e co)+  = do { (e', uds) <- specExpr env e+       ; return ((mkCast e' (substCo env co)), uds) }+specExpr env (Tick tickish body)+  = do { (body', uds) <- specExpr env body+       ; return (Tick (specTickish env tickish) body', uds) }++---------------- Applications might generate a call instance --------------------+specExpr env expr@(App {})+  = do { let (fun_in, args_in) = collectArgs expr+       ; (fun_out, uds_fun)   <- specExpr env fun_in+       ; (args_out, uds_args) <- mapAndCombineSM (specExpr env) args_in+       ; let uds_app  = uds_fun `thenUDs` uds_args+             env_args = zapSubst env `bringFloatedDictsIntoScope` ud_binds uds_app+                -- zapSubst: we have now fully applied the substitution+                -- bringFloatedDictsIntoScope: some dicts may have floated out of+                -- args_in; they should be in scope for fireRewriteRules (#21689)++       -- Try firing rewrite rules+       -- See Note [Fire rules in the specialiser]+       ; let (fun_out', args_out') = fireRewriteRules env_args fun_out args_out++       -- Make a call record, and return+       ; let uds_call = mkCallUDs env fun_out' args_out'+       ; return (fun_out' `mkApps` args_out', uds_app `thenUDs` uds_call) }++---------------- Lambda/case require dumping of usage details --------------------+specExpr env e@(Lam {})+  = specLam env' bndrs' body+  where+    (bndrs, body)  = collectBinders e+    (env', bndrs') = substBndrs env bndrs+        -- More efficient to collect a group of binders together all at once+        -- and we don't want to split a lambda group with dumped bindings++specExpr env (Case scrut case_bndr ty alts)+  = do { (scrut', scrut_uds) <- specExpr env scrut+       ; (scrut'', case_bndr', alts', alts_uds)+             <- specCase env scrut' case_bndr alts+--       ; pprTrace "specExpr:case" (vcat+--            [ text "scrut" <+> ppr scrut, text "scrut'" <+> ppr scrut'+--            , text "case_bndr'" <+> ppr case_bndr'+--            , text "alts_uds" <+> ppr alts_uds+--            ])+       ; return (Case scrut'' case_bndr' (substTy env ty) alts'+                , scrut_uds `thenUDs` alts_uds) }++---------------- Finally, let is the interesting case --------------------+specExpr env (Let bind body)+  = do { (binds', body', uds) <- specBind NotTopLevel env bind $ \body_env ->+                                 -- pprTrace "specExpr:let" (ppr (se_subst body_env) $$ ppr body) $+                                 specExpr body_env body+         -- All done+       ; return (foldr Let body' binds', uds) }++-- See Note [Specialisation modulo dictionary selectors]+--     Note [ClassOp/DFun selection]+--     Note [Fire rules in the specialiser]+fireRewriteRules :: SpecEnv   -- Substitution is already zapped+                 -> OutExpr -> [OutExpr] -> (OutExpr, [OutExpr])+fireRewriteRules env (Var f) args+  | let rules = getRules (se_rules env) f+  , Just (rule, expr) <- specLookupRule env f args activeInInitialPhase rules+  , let rest_args    = drop (ruleArity rule) args -- See Note [Extra args in the target]+        zapped_subst = se_subst env   -- Just needed for the InScopeSet+        expr'        = simpleOptExprWith defaultSimpleOpts zapped_subst (mkApps expr rest_args)+                       -- simplOptExpr needed because lookupRule returns+                       --   (\x y. rhs) arg1 arg2+  , (fun', args') <- collectArgs expr'+  = fireRewriteRules env fun' args'+fireRewriteRules _ fun args = (fun, args)++--------------+specLam :: SpecEnv -> [OutBndr] -> InExpr -> SpecM (OutExpr, UsageDetails)+-- The binders have been substituted, but the body has not+specLam env bndrs body+  | null bndrs+  = specExpr env body+  | otherwise+  = do { (body', uds) <- specExpr env body+       ; let (free_uds, dumped_dbs) = dumpUDs bndrs uds+       ; return (mkLams bndrs (wrapDictBindsE dumped_dbs body'), free_uds) }++--------------+specTickish :: SpecEnv -> CoreTickish -> CoreTickish+specTickish (SE { se_subst = subst }) bp = substTickish subst bp++--------------+specCase :: SpecEnv+         -> OutExpr             -- Scrutinee, already done+         -> InId -> [InAlt]+         -> SpecM ( OutExpr     -- New scrutinee+                  , OutId+                  , [OutAlt]+                  , UsageDetails)+specCase env scrut' case_bndr [Alt con args rhs]+  | -- See Note [Floating dictionaries out of cases]+    isDictTy (idType case_bndr)+  , interestingDict env scrut'+  , not (isDeadBinder case_bndr && null sc_args')+  = do { case_bndr_flt :| sc_args_flt <- mapM clone_me (case_bndr' :| sc_args')++       ; let case_bndr_flt' = case_bndr_flt `addDictUnfolding` scrut'+             scrut_bind     = mkDB (NonRec case_bndr_flt scrut')++             sc_args_flt' = zipWith addDictUnfolding sc_args_flt sc_rhss+             sc_rhss      = [ Case (Var case_bndr_flt') case_bndr' (idType sc_arg')+                                   [Alt con args' (Var sc_arg')]+                            | sc_arg' <- sc_args' ]+             cb_set       = unitVarSet case_bndr_flt'+             sc_binds     = [ DB { db_bind = NonRec sc_arg_flt sc_rhs, db_fvs  = cb_set }+                            | (sc_arg_flt, sc_rhs) <- sc_args_flt' `zip` sc_rhss ]++             flt_binds    = scrut_bind : sc_binds++             -- Extend the substitution for RHS to map the *original* binders+             -- to their floated versions.+             mb_sc_flts :: [Maybe DictId]+             mb_sc_flts = map (lookupVarEnv clone_env) args'+             clone_env  = zipVarEnv sc_args' sc_args_flt'++             subst_prs  = (case_bndr, Var case_bndr_flt)+                        : [ (arg, Var sc_flt)+                          | (arg, Just sc_flt) <- args `zip` mb_sc_flts ]+             subst'   = se_subst env_rhs+                        `Core.extendSubstInScopeList` (case_bndr_flt' : sc_args_flt')+                        `Core.extendIdSubstList`      subst_prs+             env_rhs' = env_rhs { se_subst = subst' }++       ; (rhs', rhs_uds)   <- specExpr env_rhs' rhs+       ; let (free_uds, dumped_dbs) = dumpUDs (case_bndr':args') rhs_uds+             all_uds = flt_binds `consDictBinds` free_uds+             alt'    = Alt con args' (wrapDictBindsE dumped_dbs rhs')+--       ; pprTrace "specCase" (ppr case_bndr $$ ppr scrut_bind) $+       ; return (Var case_bndr_flt, case_bndr', [alt'], all_uds) }+  where+    (env_rhs, (case_bndr':|args')) = substBndrs env (case_bndr:|args)+    sc_args' = filter is_flt_sc_arg args'++    clone_me bndr = do { uniq <- getUniqueM+                       ; return (mkUserLocalOrCoVar occ uniq wght ty loc) }+       where+         name = idName bndr+         wght = idMult bndr+         ty   = idType bndr+         occ  = nameOccName name+         loc  = getSrcSpan name++    arg_set = mkVarSet args'+    is_flt_sc_arg var =  isId var+                      && not (isDeadBinder var)+                      && isDictTy var_ty+                      && tyCoVarsOfType var_ty `disjointVarSet` arg_set+       where+         var_ty = idType var++specCase env scrut case_bndr alts+  = do { (alts', uds_alts) <- mapAndCombineSM spec_alt alts+       ; return (scrut, case_bndr', alts', uds_alts) }+  where+    (env_alt, case_bndr') = substBndr env case_bndr+    spec_alt (Alt con args rhs)+      = do { (rhs', uds) <- specExpr env_rhs rhs+           ; let (free_uds, dumped_dbs) = dumpUDs (case_bndr' : args') uds+--           ; unless (isNilOL dumped_dbs) $+--             pprTrace "specAlt" (vcat+--                 [text "case_bndr', args" <+> (ppr case_bndr' $$ ppr args)+--                 ,text "dumped" <+> ppr dumped_dbs ]) return ()+           ; return (Alt con args' (wrapDictBindsE dumped_dbs rhs'), free_uds) }+        where+          (env_rhs, args') = substBndrs env_alt args+++{- Note [Fire rules in the specialiser]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+Consider this (#21851)++    module A where+      f :: Num b => b -> (b, b)+      f x = (x + 1, snd (f x))+      {-# SPECIALIZE f :: Int -> (Int, Int) #-}++    module B (g') where+      import A++      g :: Num a => a -> a+      g x = fst (f x)+      {-# NOINLINE[99] g #-}++      h :: Int -> Int+      h = g++Note that `f` has the CPR property, and so will worker/wrapper.++The call to `g` in `h` will make us specialise `g @Int`. And the specialised+version of `g` will contain the call `f @Int`; but in the subsequent run of+the Simplifier, there will be a competition between:+  * The user-supplied SPECIALISE rule for `f`+  * The inlining of the wrapper for `f`+In fact, the latter wins -- see Note [tryRules: plan (BEFORE)]+GHC.Core.Opt.Simplify.Iteration.  However, it a bit fragile.++Moreover consider (test T21851_2):++    module A+      f :: (Ord a, Show b) => a -> b -> blah+      {-# RULE forall b. f @Int @b = wombat #-}++      wombat :: Show b => Int -> b -> blah+      wombat = blah++    module B+      import A+      g :: forall a. Ord a => blah+      g @a = ...g...f @a @Char....++      h = ....g @Int....++Now, in module B, GHC will specialise `g @Int`, which will lead to a+call `f @Int @Char`.  If we immediately (in the specialiser) rewrite+that to `womabat @Char`, we have a chance to specialise `wombat`.++Conclusion: it's treat if the Specialiser fires RULEs itself.+It's not hard to achieve: see `fireRewriteRules`. The only tricky bit is+making sure that we have a reasonably up to date EPS rule base. Currently+we load it up just once, in `initRuleEnv`, called at the beginning of+`specProgram`.++NB: you might wonder if running rules in the specialiser (this Note) renders+Note [tryRules: plan (BEFORE)] in the Simplifier (partly) redundant.  That is,+if we run rules in the specialiser, does it matter if we make rules "win" over+inlining in the Simplifier?  Yes, it does!  See the discussion in #21851.++Note [Floating dictionaries out of cases]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+Consider+   g = \d. case d of { MkD sc ... -> ...(f sc)... }+Naively we can't float d2's binding out of the case expression,+because 'sc' is bound by the case, and that in turn means we can't+specialise f, which seems a pity.++So we invert the case, by floating out a binding+for 'sc_flt' thus:+    sc_flt = case d of { MkD sc ... -> sc }+Now we can float the call instance for 'f'.  Indeed this is just+what'll happen if 'sc' was originally bound with a let binding,+but case is more efficient, and necessary with equalities. So it's+good to work with both.++You might think that this won't make any difference, because the+call instance will only get nuked by the \d.  BUT if 'g' itself is+specialised, then transitively we should be able to specialise f.++In general, given+   case e of cb { MkD sc ... -> ...(f sc)... }+we transform to+   let cb_flt = e+       sc_flt = case cb_flt of { MkD sc ... -> sc }+   in+   case cb_flt of bg { MkD sc ... -> ....(f sc_flt)... }++The "_flt" things are the floated binds; we use the current substitution+to substitute sc -> sc_flt in the RHS++************************************************************************+*                                                                      *+                     Dealing with a binding+*                                                                      *+************************************************************************+-}++bringFloatedDictsIntoScope :: SpecEnv -> FloatedDictBinds -> SpecEnv+bringFloatedDictsIntoScope env (FDB { fdb_bndrs = dx_bndrs })+  = -- pprTrace "brought into scope" (ppr dx_bndrs) $+    env {se_subst=subst'}+  where+   subst' = se_subst env `Core.extendSubstInScopeSet` dx_bndrs++specBind :: TopLevelFlag+         -> SpecEnv    -- At top-level only, this env already has the+                       -- top level binders in scope+         -> InBind+         -> (SpecEnv -> SpecM (body, UsageDetails))    -- Process the body+         -> SpecM ( [OutBind]           -- New bindings+                  , body                -- Body+                  , UsageDetails)       -- And info to pass upstream++-- Returned UsageDetails:+--    No calls for binders of this bind+specBind top_lvl env (NonRec fn rhs) do_body+  = do { (rhs', rhs_uds) <- specExpr env rhs++       ; (body_env1, fn1) <- case top_lvl of+                               TopLevel    -> return (env, fn)+                               NotTopLevel -> cloneBndrSM env fn++       ; let fn2 | isStableUnfolding (idUnfolding fn1) = fn1+                 | otherwise = fn1 `setIdUnfolding` mkSimpleUnfolding defaultUnfoldingOpts rhs'+             -- Update the unfolding with the perhaps-simpler or more specialised rhs'+             -- This is important: see Note [Update unfolding after specialisation]+             -- And in any case cloneBndrSM discards non-Stable unfoldings++             fn3 = floatifyIdDemandInfo fn2+             -- We zap the demand info because the binding may float,+             -- which would invalidate the demand info (see #17810 for example).+             -- Destroying demand info is not terrible; specialisation is+             -- always followed soon by demand analysis.+             -- See Note [Floatifying demand info when floating] in GHC.Core.Opt.SetLevels++             body_env2 = body_env1 `bringFloatedDictsIntoScope` ud_binds rhs_uds+                                   `extendInScope` fn3+                                   -- bringFloatedDictsIntoScope: see #23567++       ; (body', body_uds) <- do_body body_env2++       ; (fn4, spec_defns, body_uds1) <- specDefn env body_uds fn3 rhs++       ; let (free_uds, dump_dbs, float_all) = dumpBindUDs [fn4] body_uds1+             all_free_uds                    = free_uds `thenUDs` rhs_uds++             pairs = spec_defns ++ [(fn4, rhs')]+                        -- fn4 mentions the spec_defns in its rules,+                        -- so put the latter first++             final_binds :: [DictBind]+             -- See Note [From non-recursive to recursive]+             final_binds | not (isNilOL dump_dbs)+                         , not (null spec_defns)+                         = [recWithDumpedDicts pairs dump_dbs]+                         | otherwise+                         = [mkDB $ NonRec b r | (b,r) <- pairs]+                           ++ fromOL dump_dbs++             can_float_this_one = exprIsTopLevelBindable rhs (idType fn)+             -- exprIsTopLevelBindable: see Note [Care with unlifted bindings]++       ; if float_all && can_float_this_one then+             -- Rather than discard the calls mentioning the bound variables+             -- we float this (dictionary) binding along with the others+              return ([], body', all_free_uds `snocDictBinds` final_binds)+         else+             -- No call in final_uds mentions bound variables,+             -- so we can just leave the binding here+              return (map db_bind final_binds, body', all_free_uds) }+++specBind top_lvl env (Rec pairs) do_body+       -- Note [Specialising a recursive group]+  = do { let (bndrs,rhss) = unzip pairs++       ; (rec_env, bndrs1) <- case top_lvl of+                                 TopLevel    -> return (env, bndrs)+                                 NotTopLevel -> cloneRecBndrsSM env bndrs++       ; (rhss', rhs_uds)  <- mapAndCombineSM (specExpr rec_env) rhss+       ; (body', body_uds) <- do_body rec_env++       ; let scope_uds = body_uds `thenUDs` rhs_uds+                       -- Includes binds and calls arising from rhss++       ; (bndrs2, spec_defns2, uds2) <- specDefns rec_env scope_uds (bndrs1 `zip` rhss)+         -- bndrs2 is like bndrs1, but with RULES added++       ; (bndrs3, spec_defns3, uds3)+             <- if null spec_defns2  -- Common case: no specialisation+                then return (bndrs2, [], uds2)+                else do {            -- Specialisation occurred; do it again+                          (bndrs3, spec_defns3, uds3)+                              <- specDefns rec_env uds2 (bndrs2 `zip` rhss)+                        ; return (bndrs3, spec_defns3 ++ spec_defns2, uds3) }++       ; let (final_uds, dumped_dbs, float_all) = dumpBindUDs bndrs1 uds3+             final_bind = recWithDumpedDicts (spec_defns3 ++ zip bndrs3 rhss')+                                             dumped_dbs++       ; if float_all then+              return ([], body', final_uds `snocDictBind` final_bind)+         else+              return ([db_bind final_bind], body', final_uds) }+++---------------------------+specDefns :: SpecEnv+          -> UsageDetails               -- Info on how it is used in its scope+          -> [(OutId,InExpr)]           -- The things being bound and their un-processed RHS+          -> SpecM ([OutId],            -- Original Ids with RULES added+                    [(OutId,OutExpr)],  -- Extra, specialised bindings+                    UsageDetails)       -- Stuff to fling upwards from the specialised versions++-- Specialise a list of bindings (the contents of a Rec), but flowing usages+-- upwards binding by binding.  Example: { f = ...g ...; g = ...f .... }+-- Then if the input CallDetails has a specialised call for 'g', whose specialisation+-- in turn generates a specialised call for 'f', we catch that in this one sweep.+-- But not vice versa (it's a fixpoint problem).++specDefns _env uds []+  = return ([], [], uds)+specDefns env uds ((bndr,rhs):pairs)+  = do { (bndrs1, spec_defns1, uds1) <- specDefns env uds  pairs+       ; (bndr1, spec_defns2, uds2)  <- specDefn  env uds1 bndr rhs+       ; return (bndr1 : bndrs1, spec_defns1 ++ spec_defns2, uds2) }++---------------------------+specDefn :: SpecEnv+         -> UsageDetails                -- Info on how it is used in its scope+         -> OutId -> InExpr             -- The thing being bound and its un-processed RHS+         -> SpecM (Id,                  -- Original Id with added RULES+                   [(Id,CoreExpr)],     -- Extra, specialised bindings+                   UsageDetails)        -- Stuff to fling upwards from the specialised versions++specDefn env body_uds fn rhs+  = do { let (body_uds_without_me, calls_for_me) = callsForMe fn body_uds+             rules_for_me = idCoreRules fn+             -- Bring into scope the binders from the floated dicts+             env_w_dict_bndrs = bringFloatedDictsIntoScope env (ud_binds body_uds)++       ; (rules, spec_defns, spec_uds) <- specCalls False env_w_dict_bndrs+                                                    rules_for_me calls_for_me fn rhs++       ; return ( fn `addIdSpecialisations` rules+                , spec_defns+                , body_uds_without_me `thenUDs` spec_uds) }+                -- It's important that the `thenUDs` is this way+                -- round, because body_uds_without_me may bind+                -- dictionaries that are used in calls_for_me passed+                -- to specDefn.  So the dictionary bindings in+                -- spec_uds may mention dictionaries bound in+                -- body_uds_without_me++---------------------------+specCalls :: Bool              -- True  =>  specialising imported fn+                               -- False =>  specialising local fn+          -> SpecEnv+          -> [CoreRule]        -- Existing RULES for the fn+          -> [CallInfo]+          -> OutId -> InExpr+          -> SpecM SpecInfo    -- New rules, specialised bindings, and usage details++-- This function checks existing rules, and does not create+-- duplicate ones. So the caller does not need to do this filtering.+-- See `alreadyCovered`++type SpecInfo = ( [CoreRule]       -- Specialisation rules+                , [(Id,CoreExpr)]  -- Specialised definition+                , UsageDetails )   -- Usage details from specialised RHSs++specCalls spec_imp env existing_rules calls_for_me fn rhs+        -- The first case is the interesting one+  |  notNull calls_for_me               -- And there are some calls to specialise+  && not (isNeverActive (idInlineActivation fn))+        -- Don't specialise NOINLINE things+        -- See Note [Auto-specialisation and RULES]+        --+        -- Don't specialise OPAQUE things, see Note [OPAQUE pragma].+        -- Since OPAQUE things are always never-active (see+        -- GHC.Parser.PostProcess.mkOpaquePragma) this guard never fires for+        -- OPAQUE things.++--   && not (certainlyWillInline (idUnfolding fn))      -- And it's not small+--      See Note [Inline specialisations] for why we do not+--      switch off specialisation for inline functions++  = -- pprTrace "specCalls: some" (vcat+    --  [ text "function" <+> ppr fn+    --  , text "calls:" <+> ppr calls_for_me+    --  , text "subst" <+> ppr (se_subst env) ]) $+    foldlM spec_call ([], [], emptyUDs) calls_for_me++  | otherwise   -- No calls or RHS doesn't fit our preconceptions+  = warnPprTrace (not (exprIsTrivial rhs) && notNull calls_for_me)+          "Missed specialisation opportunity for" (ppr fn $$ trace_doc) $+          -- Note [Specialisation shape]+    -- pprTrace "specCalls: none" (ppr fn <+> ppr calls_for_me) $+    return ([], [], emptyUDs)+  where+    trace_doc = sep [ ppr rhs_bndrs, ppr (idInlineActivation fn) ]++    fn_type   = idType fn+    fn_arity  = idArity fn+    fn_unf    = realIdUnfolding fn  -- Ignore loop-breaker-ness here+    inl_prag  = idInlinePragma fn+    inl_act   = inlinePragmaActivation inl_prag+    is_active = isActive (beginPhase inl_act) :: Activation -> Bool+         -- is_active: inl_act is the activation we are going to put in the new+         --   SPEC rule; so we want to see if it is covered by another rule with+         --   that same activation.+    is_local  = isLocalId fn+    is_dfun   = isDFunId fn+    dflags    = se_dflags env+    this_mod  = se_module env+    subst     = se_subst env+    in_scope  = Core.substInScopeSet subst+        -- Figure out whether the function has an INLINE pragma+        -- See Note [Inline specialisations]++    (rhs_bndrs, rhs_body) = collectBindersPushingCo rhs+                            -- See Note [Account for casts in binding]++    -- Copy InlinePragma information from the parent Id.+    -- So if f has INLINE[1] so does spec_fn+    spec_inl_prag+      | not is_local     -- See Note [Specialising imported functions]+      , isStrongLoopBreaker (idOccInfo fn) -- in GHC.Core.Opt.OccurAnal+      = neverInlinePragma+      | otherwise+      = inl_prag++    not_in_scope :: InterestingVarFun+    not_in_scope v = isLocalVar v && not (v `elemInScopeSet` in_scope)++    ----------------------------------------------------------+        -- Specialise to one particular call pattern+    spec_call :: SpecInfo                         -- Accumulating parameter+              -> CallInfo                         -- Call instance+              -> SpecM SpecInfo+    spec_call spec_acc@(rules_acc, pairs_acc, uds_acc) _ci@(CI { ci_key = call_args })+      = -- See Note [Specialising Calls]+        do { let all_call_args | is_dfun   = saturating_call_args -- See Note [Specialising DFuns]+                               | otherwise = call_args+                 saturating_call_args = call_args ++ map mk_extra_dfun_arg (dropList call_args rhs_bndrs)+                 mk_extra_dfun_arg bndr | isTyVar bndr = UnspecType+                                        | otherwise    = UnspecArg++             -- Find qvars, the type variables to add to the binders for the rule+             -- Namely those free in `ty` that aren't in scope+             -- See (MP2) in Note [Specialising polymorphic dictionaries]+           ; let poly_qvars = scopedSort $ fvVarList $ specArgsFVs not_in_scope call_args+                 subst'     = subst `Core.extendSubstInScopeList` poly_qvars+                              -- Maybe we should clone the poly_qvars telescope?++             -- Any free Ids will have caused the call to be dropped+           ; massertPpr (all isTyCoVar poly_qvars)+                        (ppr fn $$ ppr all_call_args $$ ppr poly_qvars)++           ; (useful, subst'', rule_bndrs, rule_lhs_args, spec_bndrs, dx_binds, spec_args)+                 <- specHeader subst' rhs_bndrs all_call_args+           ; let all_rule_bndrs = poly_qvars ++ rule_bndrs+                 env' = env { se_subst = subst'' }++           -- Check for (a) usefulness and (b) not already covered+           -- See (SC1) in Note [Specialisations already covered]+           ; let all_rules = rules_acc ++ existing_rules+                 -- all_rules: we look both in the rules_acc (generated by this invocation+                 --   of specCalls), and in existing_rules (passed in to specCalls)+                 already_covered = alreadyCovered env' all_rule_bndrs fn+                                                  rule_lhs_args is_active all_rules++{-         ; pprTrace "spec_call" (vcat+                [ text "fun:       "  <+> ppr fn+                , text "call info: "  <+> ppr _ci+                , text "useful:    "  <+> ppr useful+                , text "already_covered:"  <+> ppr already_covered+                , text "poly_qvars: " <+> ppr poly_qvars+                , text "useful:    "  <+> ppr useful+                , text "all_rule_bndrs:"  <+> ppr all_rule_bndrs+                , text "rule_lhs_args:"  <+> ppr rule_lhs_args+                , text "spec_bndrs:" <+> ppr spec_bndrs+                , text "dx_binds:"   <+> ppr dx_binds+                , text "spec_args: "  <+> ppr spec_args+                , text "rhs_bndrs"    <+> ppr rhs_bndrs+                , text "rhs_body"     <+> ppr rhs_body+                , text "subst''" <+> ppr subst'' ]) $+             return ()+-}++           ; if not useful          -- No useful specialisation+                || already_covered  -- Useful, but done already+             then return spec_acc+             else++        -- Not useless, not already covered: make a specialised binding+        do { let inner_rhs_bndrs = dropList all_call_args rhs_bndrs+                 (env'', inner_rhs_bndrs') = substBndrs env' inner_rhs_bndrs++             -- Run the specialiser on the specialised RHS+           ; (rhs_body', rhs_uds) <- specExpr env'' rhs_body++{-         ; pprTrace "spec_call2" (vcat+                 [ text "fun:" <+> ppr fn+                 , text "rhs_body':" <+> ppr rhs_body' ]) $+             return ()+-}++           -- Make the RHS of the specialised function+           ; let spec_rhs_bndrs = spec_bndrs ++ inner_rhs_bndrs'+                 (rhs_uds1, inner_dumped_dbs) = dumpUDs spec_rhs_bndrs rhs_uds+                 (rhs_uds2, outer_dumped_dbs) = dumpUDs poly_qvars (dx_binds `consDictBinds` rhs_uds1)+                 -- dx_binds comes from the arguments to the call, and so can mention+                 -- poly_qvars but no other local binders+                 spec_rhs = mkLams poly_qvars               $+                            wrapDictBindsE outer_dumped_dbs $+                            mkLams spec_rhs_bndrs           $+                            wrapDictBindsE inner_dumped_dbs rhs_body'+                 rule_rhs_args = poly_qvars ++ spec_bndrs++                 -- Maybe add a void arg to the specialised function,+                 -- to avoid unlifted bindings+                 -- See Note [Specialisations Must Be Lifted]+                 -- C.f. GHC.Core.Opt.WorkWrap.Utils.needsVoidWorkerArg++                 spec_fn_ty = exprType spec_rhs+                 add_void_arg = isUnliftedType spec_fn_ty && not (isJoinId fn)+                 (rule_rhs_args1, spec_rhs1, spec_fn_ty1)+                   | add_void_arg = ( voidPrimId : rule_rhs_args+                                    , Lam voidArgId spec_rhs+                                    , mkVisFunTyMany unboxedUnitTy spec_fn_ty )+                   | otherwise    = (rule_rhs_args, spec_rhs, spec_fn_ty)++                 --------------------------------------+                 -- Add a suitable unfolding; see Note [Inline specialisations]+                 -- The wrap_unf_body applies the original unfolding to the specialised+                 -- arguments, not forgetting to wrap the dx_binds around the outside (#22358)+                 simpl_opts = initSimpleOpts dflags+                 wrap_unf_body body = foldr (Let . db_bind) (body `mkApps` spec_args) dx_binds+                 spec_unf = specUnfolding simpl_opts rule_rhs_args1 wrap_unf_body+                                          rule_lhs_args fn_unf++                 --------------------------------------+                 -- Adding arity information just propagates it a bit faster+                 --      See Note [Arity decrease] in GHC.Core.Opt.Simplify+                 join_arity_decr = length rule_lhs_args         - length rule_rhs_args1+                 arity_decr      = count isValArg rule_lhs_args - count isId rule_rhs_args1++                 spec_fn_info+                   = vanillaIdInfo `setArityInfo`      max 0 (fn_arity - arity_decr)+                                   `setInlinePragInfo` spec_inl_prag+                                   `setUnfoldingInfo`  spec_unf++                 -- Compute the IdDetails of the specialise Id+                 -- See Note [Transfer IdDetails during specialisation]+                 spec_fn_details+                   = case idDetails fn of+                       JoinId join_arity _ -> JoinId (join_arity - join_arity_decr) Nothing+                       DFunId unary        -> DFunId unary+                       _                   -> VanillaId++           ; spec_fn <- newSpecIdSM (idName fn) spec_fn_ty1 spec_fn_details spec_fn_info+           ; let+                -- The rule to put in the function's specialisation is:+                --      forall x @b d1' d2'.+                --          f x @T1 @b @T2 d1' d2' = f1 x @b+                -- See Note [Specialising Calls]+                herald | spec_imp  = -- Specialising imported fn+                                     text "SPEC/" <> ppr this_mod+                       | otherwise = -- Specialising local fn+                                     text "SPEC"++                spec_rule = mkSpecRule dflags this_mod True inl_act+                                    herald fn all_rule_bndrs rule_lhs_args+                                    (mkVarApps (Var spec_fn) rule_rhs_args1)++                _rule_trace_doc = vcat [ ppr fn <+> dcolon <+> ppr fn_type+                                       , ppr spec_fn  <+> dcolon <+> ppr spec_fn_ty1+                                       , ppr rhs_bndrs, ppr call_args+                                       , ppr spec_rule+                                       , text "acc" <+> ppr rules_acc+                                       , text "existing" <+> ppr existing_rules+                                       ]++           ; -- pprTrace "spec_call: rule" _rule_trace_doc+             return ( spec_rule            : rules_acc+                    , (spec_fn, spec_rhs1) : pairs_acc+                    , rhs_uds2 `thenUDs` uds_acc+                    ) } }++alreadyCovered :: SpecEnv+               -> [Var] -> Id -> [CoreExpr]   -- LHS of possible new rule+               -> (Activation -> Bool)        -- Which rules are active+               -> [CoreRule] -> Bool+-- Note [Specialisations already covered] esp (SC2)+alreadyCovered env bndrs fn args is_active rules+  = case specLookupRule env fn args is_active rules of+      Nothing             -> False+      Just (rule, _)+        | isAutoRule rule -> -- Discard identical rules+                             -- We know that (fn args) is an instance of RULE+                             -- Check if RULE is an instance of (fn args)+                             ruleLhsIsMoreSpecific in_scope bndrs args rule+        | otherwise       -> True  -- User rules dominate+  where+    in_scope = substInScopeSet (se_subst env)++-- Convenience function for invoking lookupRule from Specialise+-- The SpecEnv's InScopeSet should include all the Vars in the [CoreExpr]+specLookupRule :: HasDebugCallStack+               => SpecEnv -> Id -> [CoreExpr]+               -> (Activation -> Bool)  -- Which rules are active+               -> [CoreRule] -> Maybe (CoreRule, CoreExpr)+specLookupRule env fn args is_active rules+  | null rules+  = Nothing    -- Saves building a few thunks in the common case+  | otherwise+  = lookupRule ropts in_scope_env is_active fn args rules+  where+    dflags       = se_dflags env+    in_scope     = substInScopeSet (se_subst env)+    in_scope_env = ISE in_scope (whenActiveUnfoldingFun is_active)+    ropts        = initRuleOpts dflags++{- Note [Specialising DFuns]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~+DFuns have a special sort of unfolding (DFunUnfolding), and it is+hard to specialise a DFunUnfolding to give another DFunUnfolding+unless the DFun is fully applied (#18120).  So, in the case of DFunIds+we simply extend the CallKey with trailing UnspecTypes/UnspecArgs,+so that we'll generate a rule that completely saturates the DFun.++There is an ASSERT that checks this, in the DFunUnfolding case of+GHC.Core.Unfold.Make.specUnfolding.++Note [Transfer IdDetails during specialisation]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+When specialising a function, `newSpecIdSM` comes up with a fresh Id the+specialised RHS will be bound to. It is critical that we get the `IdDetails` of+the specialised Id correct:++* JoinId: We want the specialised Id to be a join point, too.  But+  we have to carefully adjust the arity++* DFunId: It is crucial that we also make the new Id a DFunId.+  - First, because it obviously /is/ a DFun, having a DFunUnfolding and+    all that; see Note [Specialising DFuns]++  - Second, DFuns get very delicate special treatment in the demand analyser;+    see GHC.Core.Opt.DmdAnal.enterDFun.  If the specialised function isn't+    also a DFunId, this special treatment doesn't happen, so the demand+    analyser makes a too-strict DFun, and we get an infinite loop.  See Note+    [Do not strictify a DFun's parameter dictionaries] in GHC.Core.Opt.DmdAnal.+    #22549 describes the loop, and (lower down) a case where a /specialised/+    DFun caused a loop.++* WorkerLikeId: Introduced by WW, so after Specialise. Nevertheless, they come+  up when specialising imports. We must keep them as VanillaIds because WW+  will detect them as WorkerLikeIds again. That is, unless specialisation+  allows unboxing of all previous CBV args, in which case sticking to+  VanillaIds was the only correct choice to begin with.++* RecSelId, DataCon*Id, ClassOpId, PrimOpId, FCallId, CoVarId, TickBoxId:+  Never specialised.++Note [Specialisation Must Preserve Sharing]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+Consider a function:++    f :: forall a. Eq a => a -> blah+    f =+      if expensive+         then f1+         else f2++As written, all calls to 'f' will share 'expensive'. But if we specialise 'f'+at 'Int', eg:++    $sfInt = SUBST[a->Int,dict->dEqInt] (if expensive then f1 else f2)++    RULE "SPEC f"+      forall (d :: Eq Int).+        f Int _ = $sfIntf++We've now lost sharing between 'f' and '$sfInt' for 'expensive'. Yikes!++To avoid this, we only generate specialisations for functions whose arity is+enough to bind all of the arguments we need to specialise.  This ensures our+specialised functions don't do any work before receiving all of their dicts,+and thus avoids the 'f' case above.++Note [Specialisations Must Be Lifted]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+Consider a function 'f':++    f = forall a. Eq a => Array# a++used like++    case x of+      True -> ...f @Int dEqInt...+      False -> 0++Naively, we might generate an (expensive) specialisation++    $sfInt :: Array# Int++even in the case that @x = False@! Instead, we add a dummy 'Void#' argument to+the specialisation '$sfInt' ($sfInt :: Void# -> Array# Int) in order to+preserve laziness.++Note [Care with unlifted bindings]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+Consider (#22998)+    f x = let x::ByteArray# = <some literal>+              n::Natural    = NB x+          in wombat @192827 (n |> co)+where+  co :: Natural ~ KnownNat 192827+  wombat :: forall (n:Nat). KnownNat n => blah++Left to itself, the specialiser would float the bindings for `x` and `n` to top+level, so we can specialise `wombat`.  But we can't have a top-level ByteArray#+(see Note [Core letrec invariant] in GHC.Core).  Boo.++This is pretty exotic, so we take a simple way out: in specBind (the NonRec+case) do not float the binding itself unless it satisfies exprIsTopLevelBindable.+This is conservative: maybe the RHS of `x` has a free var that would stop it+floating to top level anyway; but that is hard to spot (since we don't know what+the non-top-level in-scope binders are) and rare (since the binding must satisfy+Note [Core let-can-float invariant] in GHC.Core).+++Note [Specialising Calls]+~~~~~~~~~~~~~~~~~~~~~~~~~+Suppose we have a function with a complicated type:++    f :: forall a b c. Int -> Eq a => Show b => c -> Blah+    f @a @b @c i dEqA dShowA x = blah++and suppose it is called at:++    f @T1 @T2 @T3 7 dEqT1 ($dfShow dShowT2) t3++This call is described as a 'CallInfo' whose 'ci_key' is:++    [ SpecType T1, SpecType T2, UnspecType+    , UnspecArg+    , SpecDict dEqT1+    , SpecDict ($dfShow dShowT2)+    , UnspecArg ]++Why are 'a' and 'b' identified as 'SpecType', while 'c' is 'UnspecType'?+Because we must specialise the function on type variables that appear+free in its *dictionary* arguments; but not on type variables that do not+appear in any dictionaries, i.e. are fully polymorphic.++Because this call has dictionaries applied, we'd like to specialise+the call on any type argument that appears free in those dictionaries.+In this case, those are [a :-> T1, b :-> T2].++We also need to substitute the dictionary binders with their+specialised dictionaries. The simplest substitution would be+[dEqA :-> dEqT1, dShowA :-> $dfShow dShowT2], but this duplicates+work, since `$dfShow dShowT2` is a function application. Therefore, we+also want to *float the dictionary out* (via bindAuxiliaryDict),+creating a new dict binding++    dShow1 = $dfShow dShowT2++and the substitution [dEqA :-> dEqT1, dShowA :-> dShow1].++With the substitutions in hand, we can generate a specialised function:++    $sf :: forall c. Int -> c -> Blah+    $sf = SUBST[a :-> T1, b :-> T2, dEqA :-> dEqT1, dShowA :-> dShow1] (\@c i x -> blah)++Note that the substitution is applied to the whole thing.  This is+convenient, but just slightly fragile.  Notably:+  * There had better be no name clashes in a/b/c++We must construct a rewrite rule:++    RULE "SPEC f @T1 @T2 _"+      forall (@c :: Type) (i :: Int) (d1 :: Eq T1) (d2 :: Show T2).+        f @T1 @T2 @c i d1 d2 = $sf @c i++In the rule, d1 and d2 are just wildcards, not used in the RHS.  Note+additionally that 'x' isn't captured by this rule --- we bind only+enough etas in order to capture all of the *specialised* arguments.++Note [Drop dead args from specialisations]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+When specialising a function, it’s possible some of the arguments may+actually be dead. For example, consider:++    f :: forall a. () -> Show a => a -> String+    f x y = show y ++ "!"++We might generate the following CallInfo for `f @Int`:++    [SpecType Int, UnspecArg, SpecDict $dShowInt, UnspecArg]++Normally we’d include both the x and y arguments in the+specialisation, since we’re not specialising on either of them. But+that’s silly, since x is actually unused! So we might as well drop it+in the specialisation:++    $sf :: Int -> String+    $sf y = show y ++ "!"++    {-# RULE "SPEC f @Int" forall x. f @Int x $dShow = $sf #-}++This doesn’t save us much, since the arg would be removed later by+worker/wrapper, anyway, but it’s easy to do.++Wrinkles++* Note that we only drop dead arguments if:+    1. We don’t specialise on them.+    2. They come before an argument we do specialise on.+  Doing the latter would require eta-expanding the RULE, which could+  make it match less often, so it’s not worth it. Doing the former could+  be more useful --- it would stop us from generating pointless+  specialisations --- but it’s more involved to implement and unclear if+  it actually provides much benefit in practice.++* If the function has a stable unfolding, specHeader has to come up with+  arguments to pass to that stable unfolding, when building the stable+  unfolding of the specialised function: this is the last field in specHeader's+  big result tuple.++  The right thing to do is to produce a LitRubbish; it should rapidly+  disappear.  Rather like GHC.Core.Opt.WorkWrap.Utils.mk_absent_let.++Note [Specialisation modulo dictionary selectors]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+In #19644, we discovered that the ClassOp/DFun rules from+Note [ClassOp/DFun selection] inhibit transitive specialisation.+Example, inspired by T17966:++  class C a where+    m :: Show b => a -> b -> String+    dummy :: a -> () -- Force a datatype dictionary representation++  instance C Int where+    m a b = show a ++ show b+    dummy _ = ()++  f :: (C a, Show b) => a -> b -> String+  f a b = m a b ++ "!"+  {-# INLINABLE[0] f #-}++  main = putStrLn (f (42::Int) (True::Bool))++Here, we specialise `f` at `Int` and `Bool`, giving++  $dC = $fCInt+  $dShow = GHC.Show.$fShowBool+  $sf (a::Int) (b::Bool) =+        ... (m @Int $dC @Bool $dShow a b) ...++Here `m` is just a DictSel, so there is (apparently) nothing to specialise!+However, the next Simplifier run will expose the rewritten instance method:++  ... $fCInt_$cm @Bool $fShowBool a b ...++where $fCInt_$cm is the instance method for `m` in `instance C Int`:++   $fCInt_$cm :: forall b. Show b => Int -> b -> String+   $fCInt_$cm b d x y = show @Int $dShowInt x ++ show @b d y++We want to specialise this! How? By doing the method-selection rewrite in+the Specialiser. Hence++1. In the App case of 'specExpr', try to apply the ClassOp/DFun rule on the+   head of the application, repeatedly, via 'fireRewriteRules'.+2. Attach an unfolding to freshly-bound dictionary ids such as `$dC` and+   `$dShow` in `bindAuxiliaryDict`, so that we can exploit the unfolding+   in 'fireRewriteRules' to do the ClassOp/DFun rewrite.++NB: Without (2), (1) would be pointless, because 'lookupRule' wouldn't be able+to look into the RHS of `$dC` to see the DFun.++Note [Zap occ info in rule binders]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+When we generate a specialisation RULE, we need to drop occurrence+info on the binders. If we don’t, things go wrong when we specialise a+function like++    f :: forall a. () -> Show a => a -> String+    f x y = show y ++ "!"++since we’ll generate a RULE like++    RULE "SPEC f @Int" forall x [Occ=Dead].+      f @Int x $dShow = $sf++and Core Lint complains, even though x only appears on the LHS (due to+Note [Drop dead args from specialisations]).++Why is that a Lint error? Because the arguments on the LHS of a rule+are syntactically expressions, not patterns, so Lint treats the+appearance of x as a use rather than a binding. Fortunately, the+solution is simple: we just make sure to zap the occ info before+using ids as wildcard binders in a rule.++Note [Account for casts in binding]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+Consider+   f :: Eq a => a -> IO ()+   {-# INLINABLE f+       StableUnf = (/\a \(d:Eq a) (x:a). blah) |> g+     #-}+   f = ...++In f's stable unfolding we have done some modest simplification which+has pushed the cast to the outside.  (I wonder if this is the Right+Thing, but it's what happens now; see GHC.Core.Opt.Simplify.Utils Note [Casts and+lambdas].)  Now that stable unfolding must be specialised, so we want+to push the cast back inside. It would be terrible if the cast+defeated specialisation!  Hence the use of collectBindersPushingCo.++Note [Evidence foralls]+~~~~~~~~~~~~~~~~~~~~~~~~~~+Suppose (#12212) that we are specialising+   f :: forall a b. (Num a, F a ~# F b) => blah+with a=b=Int. Then the RULE will be something like+   RULE forall (d:Num Int) (g :: F Int ~# F Int).+        f Int Int d g = f_spec+where that `g` is really (Coercion (CoVar g)), since `g` is a+coercion variable and can't appear as (Var g).++But both varToCoreExpr (when constructing the LHS args), and the+simplifier (when simplifying the LHS args), will transform to+   RULE forall (d:Num Int) (g :: F Int ~ F Int).+        f Int Int d <F Int> = f_spec+by replacing g with Refl.  So now 'g' is unbound, which results in a later+crash. So we use Refl right off the bat, and do not forall-quantify 'g':+ * varToCoreExpr generates a (Coercion Refl)+ * exprsFreeIdsList returns the Ids bound by the args,+   which won't include g++You might wonder if this will match as often, but the simplifier replaces+complicated Refl coercions with Refl pretty aggressively.++Note [Orphans and auto-generated rules]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+When we specialise an INLINABLE function, or when we have+-fspecialise-aggressively, we auto-generate RULES that are orphans.+We don't want to warn about these, or we'd generate a lot of warnings.+Thus, we only warn about user-specified orphan rules.++Indeed, we don't even treat the module as an orphan module if it has+auto-generated *rule* orphans.  Orphan modules are read every time we+compile, so they are pretty obtrusive and slow down every compilation,+even non-optimised ones.  (Reason: for type class instances it's a+type correctness issue.)  But specialisation rules are strictly for+*optimisation* only so it's fine not to read the interface.++What this means is that a SPEC rules from auto-specialisation in+module M will be used in other modules only if M.hi has been read for+some other reason, which is actually pretty likely.++Note [From non-recursive to recursive]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+Even in the non-recursive case, if any dict-binds depend on 'fn' we might+have built a recursive knot++      f a d x = <blah>+      MkUD { ud_binds = NonRec d7  (MkD ..f..)+           , ud_calls = ...(f T d7)... }++The we generate++     Rec { fs x = <blah>[T/a, d7/d]+           f a d x = <blah>+               RULE f T _ = fs+           d7 = ...f... }++Here the recursion is only through the RULE.++However we definitely should /not/ make the Rec in this wildly common+case:+      d = ...+      MkUD { ud_binds = NonRec d7 (...d...)+           , ud_calls = ...(f T d7)... }++Here we want simply to add d to the floats, giving+      MkUD { ud_binds = NonRec d (...)+                        NonRec d7 (...d...)+           , ud_calls = ...(f T d7)... }++In general, we need only make this Rec if+  - there are some specialisations (spec_binds non-empty)+  - there are some dict_binds that depend on f (dump_dbs non-empty)++Note [Avoiding loops (DFuns)]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+When specialising /dictionary functions/ we must be very careful to+avoid building loops. Here is an example that bit us badly, on+several distinct occasions.++Here is one: #3591+     class Eq a => C a+     instance Eq [a] => C [a]++This translates to+     dfun :: Eq [a] -> C [a]+     dfun a d = MkD a d (meth d)++     d4 :: Eq [T] = <blah>+     d2 ::  C [T] = dfun T d4+     d1 :: Eq [T] = $p1 d2+     d3 ::  C [T] = dfun T d1++None of these definitions is recursive. What happened was that we+generated a specialisation:+     RULE forall d. dfun T d = dT  :: C [T]+     dT = (MkD a d (meth d)) [T/a, d1/d]+        = MkD T d1 (meth d1)++But now we use the RULE on the RHS of d2, to get+    d2 = dT = MkD d1 (meth d1)+    d1 = $p1 d2++and now d1 is bottom!  The problem is that when specialising 'dfun' we+should first dump "below" the binding all floated dictionary bindings+that mention 'dfun' itself.  So d2 and d3 (and hence d1) must be+placed below 'dfun', and thus unavailable to it when specialising+'dfun'.  That in turn means that the call (dfun T d1) must be+discarded.  On the other hand, the call (dfun T d4) is fine, assuming+d4 doesn't mention dfun.++Solution:+  Discard all calls that mention dictionaries that depend+  (directly or indirectly) on the dfun we are specialising.+  This is done by 'filterCalls'++Note [Avoiding loops (non-DFuns)]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+The whole Note [Avoiding loops (DFuns)] things applies only to DFuns.+It's important /not/ to apply filterCalls to non-DFuns. For example:++  class C a where { foo,bar :: [a] -> [a] }++  instance C Int where+     foo x = r_bar x+     bar xs = reverse xs++  r_bar :: C a => [a] -> [a]+  r_bar xs = bar (xs ++ xs)++That translates to:++    r_bar a (c::C a) (xs::[a]) = bar a d (xs ++ xs)++    Rec { $fCInt :: C Int = MkC foo_help reverse+          foo_help (xs::[Int]) = r_bar Int $fCInt xs }++The call (r_bar $fCInt) mentions $fCInt,+                        which mentions foo_help,+                        which mentions r_bar++But we DO want to specialise r_bar at Int:+    Rec { $fCInt :: C Int = MkC foo_help reverse+          foo_help (xs::[Int]) = r_bar Int $fCInt xs++          r_bar a (c::C a) (xs::[a]) = bar a d (xs ++ xs)+            RULE r_bar Int _ = r_bar_Int++          r_bar_Int xs = bar Int $fCInt (xs ++ xs)+           }++Note that, because of its RULE, r_bar joins the recursive+group.  (In this case it'll unravel a short moment later.)+See test simplCore/should_compile/T19599a.++Another example is #19599, which looked like this:++   class (Show a, Enum a) => MyShow a where+      myShow :: a -> String++   myShow_impl :: MyShow a => a -> String++   foo :: Int -> String+   foo = myShow_impl @Int $fMyShowInt++   Rec { $fMyShowInt = MkMyShowD $fEnumInt $fShowInt $cmyShow+       ; $cmyShow = myShow_impl @Int $fMyShowInt }++Here, we really do want to specialise `myShow_impl @Int $fMyShowInt`.+++Note [Specialising a recursive group]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+Consider+    let rec { f x = ...g x'...+            ; g y = ...f y'.... }+    in f 'a'+Here we specialise 'f' at Char; but that is very likely to lead to+a specialisation of 'g' at Char.  We must do the latter, else the+whole point of specialisation is lost.++But we do not want to keep iterating to a fixpoint, because in the+presence of polymorphic recursion we might generate an infinite number+of specialisations.++So we use the following heuristic:+  * Arrange the rec block in dependency order, so far as possible+    (the occurrence analyser already does this)++  * Specialise it much like a sequence of lets++  * Then go through the block a second time, feeding call-info from+    the RHSs back in the bottom, as it were++In effect, the ordering maxmimises the effectiveness of each sweep,+and we do just two sweeps.   This should catch almost every case of+monomorphic recursion -- the exception could be a very knotted-up+recursion with multiple cycles tied up together.++This plan is implemented in the Rec case of specBindItself.++Note [Specialisations already covered]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+We obviously don't want to generate two specialisations for the same+argument pattern.  Wrinkles++(SC1) We do the already-covered test in specDefn, not when we generate+    the CallInfo in mkCallUDs.  We used to test in the latter place, but+    we now iterate the specialiser somewhat, and the Id at the call site+    might therefore not have all the RULES that we can see in specDefn++(SC2) What about two specialisations where the second is an *instance*+   of the first?  It's a bit arbitrary, but here's what we do:+   * If the existing one is user-specified, via a SPECIALISE pragma, we+     suppress the further specialisation.+   * If the existing one is auto-generated, we generate a second RULE+     for the more specialised version.+   The latter is important because we don't want the accidental order+   of calls to determine what specialisations we generate.++(SC3) Annoyingly, we /also/ eliminate duplicates in `filterCalls`.+   See (MP3) in Note [Specialising polymorphic dictionaries]++Note [Auto-specialisation and RULES]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+Consider:+   g :: Num a => a -> a+   g = ...++   f :: (Int -> Int) -> Int+   f w = ...+   {-# RULE f g = 0 #-}++Suppose that auto-specialisation makes a specialised version of+g::Int->Int. That version won't appear in the LHS of the RULE for f.+So if the specialisation rule fires too early, the rule for f may+never fire.++It might be possible to add new rules, to "complete" the rewrite system.+Thus when adding+        RULE forall d. g Int d = g_spec+also add+        RULE f g_spec = 0++But that's a bit complicated.  For now we ask the programmer's help,+by *copying the INLINE activation pragma* to the auto-specialised+rule.  So if g says {-# NOINLINE[2] g #-}, then the auto-spec rule+will also not be active until phase 2.  And that's what programmers+should jolly well do anyway, even aside from specialisation, to ensure+that g doesn't inline too early.++This in turn means that the RULE would never fire for a NOINLINE+thing so not much point in generating a specialisation at all.++Note [Specialisation shape]+~~~~~~~~~~~~~~~~~~~~~~~~~~~+We only specialise a function if it has visible top-level lambdas+corresponding to its overloading.  E.g. if+        f :: forall a. Eq a => ....+then its body must look like+        f = /\a. \d. ...++Reason: when specialising the body for a call (f ty dexp), we want to+substitute dexp for d, and pick up specialised calls in the body of f.++We do allow casts, however; see Note [Account for casts in binding].++This doesn't always work.  One example I came across was this:+        newtype Gen a = MkGen{ unGen :: Int -> a }++        choose :: Eq a => a -> Gen a+        choose n = MkGen (\r -> n)++        oneof = choose (1::Int)++It's a silly example, but we get+        choose = /\a. g `cast` co+where choose doesn't have any dict arguments.  Thus far I have not+tried to fix this (wait till there's a real example).++Mind you, then 'choose' will be inlined (since RHS is trivial) so+it doesn't matter.  This comes up with single-method classes++   class C a where { op :: a -> a }+   instance C a => C [a] where ....+==>+   $fCList :: C a => C [a]+   $fCList = $copList |> (...coercion>...)+   ....(uses of $fCList at particular types)...++So we suppress the WARN if the rhs is trivial.++Note [Inline specialisations]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+Here is what we do with the InlinePragma of the original function++  * Activation/RuleMatchInfo: both inherited from the original function++  * InlineSpec: inherit from original function++  * Unfolding: transfer a StableUnfolding iff it is UnfWhen+               See GHC.Core.Unfold.Make.specUnfolding+               and its Note [Specialising unfoldings]++InlineSpec: you might wonder why we specialise INLINE functions at all.+After all they should be inlined, right?  Two reasons:++ * Even INLINE functions are sometimes not inlined, when they aren't+   applied to interesting arguments.  But perhaps the type arguments+   alone are enough to specialise (even though the args are too boring+   to trigger inlining), and it's certainly better to call the+   specialised version.++ * The RHS of an INLINE function might call another overloaded function,+   and we'd like to generate a specialised version of that function too.+   This actually happens a lot. Consider+      replicateM_ :: (Monad m) => Int -> m a -> m ()+      {-# INLINABLE replicateM_ #-}+      replicateM_ d x ma = ...+   The strictness analyser may transform to+      replicateM_ :: (Monad m) => Int -> m a -> m ()+      {-# INLINE replicateM_ #-}+      replicateM_ d x ma = case x of I# x' -> $wreplicateM_ d x' ma++      $wreplicateM_ :: (Monad m) => Int# -> m a -> m ()+      {-# INLINABLE $wreplicateM_ #-}+      $wreplicateM_ = ...+   Now an importing module has a specialised call to replicateM_, say+   (replicateM_ dMonadIO).  We certainly want to specialise $wreplicateM_!+   This particular example had a huge effect on the call to replicateM_+   in nofib/shootout/n-body.+-}++{- *********************************************************************+*                                                                      *+                   SpecArg, and specHeader+*                                                                      *+********************************************************************* -}++-- | An argument that we might want to specialise.+-- See Note [Specialising Calls] for the nitty gritty details.+data SpecArg+  =+    -- | Type arguments that should be specialised, due to appearing+    -- free in the type of a 'SpecDict'.+    SpecType Type++    -- | Type arguments that should remain polymorphic.+  | UnspecType++    -- | Dictionaries that should be specialised. mkCallUDs ensures+    -- that only "interesting" dictionary arguments get a SpecDict;+    -- see Note [Interesting dictionary arguments]+  | SpecDict DictExpr++    -- | Value arguments that should not be specialised.+  | UnspecArg++instance Outputable SpecArg where+  ppr (SpecType t)  = text "SpecType" <+> ppr t+  ppr (SpecDict d)  = text "SpecDict" <+> ppr d+  ppr UnspecType    = text "UnspecType"+  ppr UnspecArg     = text "UnspecArg"++specArgsFVs :: InterestingVarFun -> [SpecArg] -> FV+-- Find the free vars of the SpecArgs that are not already in scope+specArgsFVs interesting args+  = filterFV interesting $+    foldr (unionFV . get) emptyFV args+  where+    get :: SpecArg -> FV+    get (SpecType ty)   = tyCoFVsOfType ty+    get (SpecDict dx)   = exprFVs dx+    get UnspecType      = emptyFV+    get UnspecArg       = emptyFV++isSpecDict :: SpecArg -> Bool+isSpecDict (SpecDict {}) = True+isSpecDict _             = False++-- | Given binders from an original function 'f', and the 'SpecArg's+-- corresponding to its usage, compute everything necessary to build+-- a specialisation.+--+-- We will use the running example from Note [Specialising Calls]:+--+--     f :: forall a b c. Int -> Eq a => Show b => c -> Blah+--     f @a @b @c i dEqA dShowB x = blah+--+-- Suppose we decide to specialise it at the following pattern:+--+--     [ SpecType T1, SpecType T2, UnspecType, UnspecArg+--     , SpecDict dEqT1, SpecDict ($dfShow dShowT2), UnspecArg ]+--+-- We'd eventually like to build the RULE+--+--     RULE "SPEC f @T1 @T2 _"+--       forall (@c :: Type) (i :: Int) (d1 :: Eq T1) (d2 :: Show T2).+--         f @T1 @T2 @c i d1 d2 = $sf @c i+--+-- and the specialisation '$sf'+--+--     $sf :: forall c. Int -> c -> Blah+--     $sf = SUBST[a :-> T1, b :-> T2, dEqA :-> dEqT1, dShowB :-> dShow1] (\@c i x -> blah)+--+-- where dShow1 is a floated binding created by bindAuxiliaryDict.+--+-- The cases for 'specHeader' below are presented in the same order as this+-- running example. The result of 'specHeader' for this example is as follows:+--+--    ( -- Returned arguments+--      env + [a :-> T1, b :-> T2, dEqA :-> dEqT1, dShowB :-> dShow1]+--    , [x]+--+--      -- RULE helpers+--    , [c, i, d1, d2]+--    , [T1, T2, c, i, d1, d2]+--+--      -- Specialised function helpers+--    , [c, i, x]+--    , [dShow1 = $dfShow dShowT2]+--    , [T1, T2, c, i, dEqT1, dShow1]+--    )+specHeader+     :: Core.Subst  -- This substitution applies to the [InBndr]+     -> [InBndr]    -- Binders from the original function `f`+     -> [SpecArg]   -- From the CallInfo+     -> SpecM ( Bool     -- True <=> some useful specialisation happened+                         -- Not the same as any (isSpecDict args) because+                         -- the args might be longer than bndrs++              , Core.Subst   -- Apply this to the body++                -- RULE helpers+                -- `RULE forall rule_bndrs. f rule_es = $sf spec_bndrs`+              , [OutBndr]    -- rule_bndrs: Binders for the RULE+              , [OutExpr]    -- rule_es:    Args for the LHS of the rule++                -- Specialised function helpers+                -- `$sf = \spec_bndrs. let { dx_binds } in <orig-rhs> spec_arg`+              , [OutBndr]    -- spec_bndrs: Binders for $sf, and args for the RHS+                             --             of the RULE. Subset of rule_bndrs.+              , [DictBind]   -- dx_binds:   Auxiliary dictionary bindings+              , [OutExpr]    -- spec_args:  Specialised arguments for unfolding+                             --             Same length as "Args for LHS of rule"+              )++-- If we run out of binders, stop immediately+-- See Note [Specialisation Must Preserve Sharing]+specHeader subst [] _  = pure (False, subst, [], [], [], [], [])+specHeader subst _  [] = pure (False, subst, [], [], [], [], [])++-- We want to specialise on type 'T1', and so we must construct a substitution+-- 'a->T1', as well as a LHS argument for the resulting RULE and unfolding+-- details.+specHeader subst (bndr:bndrs) (SpecType ty : args)+  = do { let subst1 = Core.extendTvSubst subst bndr ty+       ; (useful, subst2, rule_bs, rule_args, spec_bs, dx, spec_args)+             <- specHeader subst1 bndrs args+       ; pure ( useful, subst2+              , rule_bs,     Type ty : rule_args+              , spec_bs, dx, Type ty : spec_args ) }++-- Next we have a type that we don't want to specialise. We need to perform+-- a substitution on it (in case the type refers to 'a'). Additionally, we need+-- to produce a binder, LHS argument and RHS argument for the resulting rule,+-- /and/ a binder for the specialised body.+specHeader subst (bndr:bndrs) (UnspecType : args)+  = do { let (subst1, bndr') = Core.substBndr subst bndr+       ; (useful, subst2, rule_bs, rule_es, spec_bs, dx, spec_args)+             <- specHeader subst1 bndrs args+       ; let ty_e' = Type (mkTyVarTy bndr')+       ; pure ( useful, subst2+              , bndr' : rule_bs,     ty_e' : rule_es+              , bndr' : spec_bs, dx, ty_e' : spec_args ) }++specHeader subst (bndr:bndrs) (_ : args)+  | isDeadBinder bndr+  , let (subst1, bndr') = Core.substBndr subst (zapIdOccInfo bndr)+  , Just rubbish_lit <- mkLitRubbish (idType bndr')+  = -- See Note [Drop dead args from specialisations]+    do { (useful, subst2, rule_bs, rule_es, spec_bs, dx, spec_args) <- specHeader subst1 bndrs args+       ; pure ( useful, subst2+              , bndr' : rule_bs, Var bndr'   : rule_es+              , spec_bs,     dx, rubbish_lit : spec_args ) }++-- Next we want to specialise the 'Eq a' dict away. We need to construct+-- a wildcard binder to match the dictionary (See Note [Specialising Calls] for+-- the nitty-gritty), as a LHS rule and unfolding details.+specHeader subst (bndr:bndrs) (SpecDict dict_arg : args)+  = do { -- Make up a fresh binder to use in the RULE+         -- It might turn into a dict binding (via bindAuxiliaryDict) which we+         -- then float, so we use cloneIdBndr to get a completely fresh binder+         us <- getUniqueSupplyM+       ; let (subst1, bndr') = Core.cloneIdBndr subst us (zapIdOccInfo bndr)+                 -- zapIdOccInfo: see Note [Zap occ info in rule binders]++         -- Extend the substitution to map bndr :-> dict_arg, for use in the RHS+       ; let (subst2, dx_bind, spec_dict) = bindAuxiliaryDict subst1 bndr bndr' dict_arg++       ; (_, subst3, rule_bs, rule_es, spec_bs, dx, spec_args) <- specHeader subst2 bndrs args++       ; let dx' = case dx_bind of { Nothing -> dx; Just d -> d : dx }+       ; pure ( True, subst3      -- Ha!  A useful specialisation!+              , bndr' : rule_bs, Var bndr' : rule_es+              , spec_bs,    dx', spec_dict : spec_args ) }++-- Finally, we don't want to specialise on this argument 'i':+-- We need to produce a binder, LHS and RHS argument for the RULE, and+-- a binder for the specialised body.+--+-- NB: Calls to 'specHeader' will trim off any trailing 'UnspecArg's, which is+-- why 'i' doesn't appear in our RULE above. But we have no guarantee that+-- there aren't 'UnspecArg's which come /before/ all of the dictionaries, so+-- this case must be here.+specHeader subst (bndr:bndrs) (UnspecArg : args)+  = do { let (subst1, bndr') = Core.substBndr subst (zapIdOccInfo bndr)+                 -- zapIdOccInfo: see Note [Zap occ info in rule binders]+       ; (useful, subst2, rule_bs, rule_es, spec_bs, dx, spec_args) <- specHeader subst1 bndrs args++       ; let dummy_arg = varToCoreExpr bndr'+               -- dummy_arg is usually just (Var bndr),+               -- but if bndr :: t1 ~# t2, it'll be (Coercion (CoVar bndr))+               --     or even Coercion Refl (if t1=t2)+               -- See Note [Evidence foralls]+             bndrs = exprFreeIdsList dummy_arg++       ; pure ( useful, subst2+              , bndrs ++ rule_bs,     dummy_arg : rule_es+              , bndrs ++ spec_bs, dx, dummy_arg : spec_args ) }+++-- | Binds a dictionary argument to a fresh name, to preserve sharing+bindAuxiliaryDict+  :: Subst+  -> InId -> OutId -> OutExpr -- Original dict binder, and the witnessing expression+  -> ( Subst          -- Substitutes for orig_dict_id+     , Maybe DictBind -- Auxiliary dict binding, if any+     , OutExpr)       -- Witnessing expression (always trivial)+bindAuxiliaryDict subst orig_dict_id fresh_dict_id dict_arg++  -- If the dictionary argument is trivial,+  -- don’t bother creating a new dict binding; just substitute+  | exprIsTrivial dict_arg+  , let subst' = Core.extendSubst subst orig_dict_id dict_arg+  = -- pprTrace "bindAuxiliaryDict:trivial" (ppr orig_dict_id <+> ppr dict_id) $+    (subst', Nothing, dict_arg)++  | otherwise  -- Non-trivial dictionary arg; make an auxiliary binding+  , let fresh_dict_id' = fresh_dict_id `addDictUnfolding` dict_arg++        dict_bind = mkDB (NonRec fresh_dict_id' dict_arg)+        subst'    = Core.extendSubst subst orig_dict_id (Var fresh_dict_id')+                    `Core.extendSubstInScope` fresh_dict_id'+                    -- Ensure the new unfolding is in the in-scope set+  = -- pprTrace "bindAuxiliaryDict:non-trivial" (ppr orig_dict_id <+> ppr fresh_dict_id') $+    (subst', Just dict_bind, Var fresh_dict_id')++addDictUnfolding :: Id -> CoreExpr -> Id+-- Add unfolding for freshly-bound Ids: see Note [Make the new dictionaries interesting]+-- and Note [Specialisation modulo dictionary selectors]+addDictUnfolding id rhs+  = id `setIdUnfolding` mkSimpleUnfolding defaultUnfoldingOpts rhs++{-+Note [Make the new dictionaries interesting]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+Important!  We're going to substitute dx_id1 for d+and we want it to look "interesting", else we won't gather *any*+consequential calls. E.g.+    f d = ...g d....+If we specialise f for a call (f (dfun dNumInt)), we'll get+a consequent call (g d') with an auxiliary definition+    d' = df dNumInt+We want that consequent call to look interesting; so we add an unfolding+in the dictionary Id.+-}+++{- *********************************************************************+*                                                                      *+            UsageDetails and suchlike+*                                                                      *+********************************************************************* -}++data UsageDetails+  = MkUD { ud_binds :: !FloatedDictBinds+         , ud_calls :: !CallDetails }+    -- INVARIANT: suppose bs = fdb_bndrs ud_binds+    -- Then 'calls' may *mention* 'bs',+    -- but there should be no calls *for* bs++data FloatedDictBinds  -- See Note [Floated dictionary bindings]+  = FDB { fdb_binds :: !(OrdList DictBind)+               -- The order is important;+               -- in ds1 `appOL` ds2, bindings in ds2 can depend on those in ds1++        , fdb_bndrs :: !IdSet+    }          -- ^ The binders of 'fdb_binds'.+               -- Caches a superset of the expression+               --   `mkVarSet (bindersOfDictBinds fdb_binds))`+               -- for later addition to an InScopeSet++-- | A 'DictBind' is a binding along with a cached set containing its free+-- variables (both type variables and dictionaries). We need this set+-- in splitDictBinds, when filtering bindings to decide which are+-- captured by a binder+data DictBind = DB { db_bind :: CoreBind, db_fvs :: VarSet }++bindersOfDictBind :: DictBind -> [Id]+bindersOfDictBind = bindersOf . db_bind++bindersOfDictBinds :: Foldable f => f DictBind -> [Id]+bindersOfDictBinds = bindersOfBinds . foldr ((:) . db_bind) []++{- Note [Floated dictionary bindings]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+We float out dictionary bindings for the reasons described under+"Dictionary floating" above.  But not /just/ dictionary bindings.+Consider++   f :: Eq a => blah+   f a d = rhs++   $c== :: T -> T -> Bool+   $c== x y = ...++   $df :: Eq T+   $df = Eq $c== ...++   gurgle = ...(f @T $df)...++We gather the call info for (f @T $df), and we don't want to drop it+when we come across the binding for $df.  So we add $df to the floats+and continue.  But then we have to add $c== to the floats, and so on.+These all float above the binding for 'f', and now we can+successfully specialise 'f'.++So the DictBinds in (ud_binds :: OrdList DictBind) may contain+non-dictionary bindings too.++Note [Specialising polymorphic dictionaries]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+Note June 2023: This has proved to be quite a tricky optimisation to get right+see (#23469, #23109, #21229, #23445) so it is now guarded by a flag+`-fpolymorphic-specialisation`.++Consider+    class M a where { foo :: a -> Int }++    instance M (ST s) where ...+    -- dMST :: forall s. M (ST s)++    wimwam :: forall a. M a => a -> Int+    wimwam = /\a \(d::M a). body++    f :: ST s -> Int+    f = /\s \(x::ST s). wimwam @(ST s) (dMST @s) dx + 1++We'd like to specialise wimwam at (ST s), thus+    $swimwam :: forall s. ST s -> Int+    $swimwam = /\s. body[ST s/a, (dMST @s)/d]++    RULE forall s (d :: M (ST s)).+         wimwam @(ST s) d = $swimwam @s++Here are the moving parts:++(MP1) We must /not/ dump the CallInfo+        CIS wimwam (CI { ci_key = [@(ST s), dMST @s]+                       , ci_fvs = {dMST} })+      when we come to the /\s.  Instead, we simply let it continue to float+      upwards. Hence ci_fvs is an IdSet, listing the /Ids/ that+      are free in the call, but not the /TyVars/.  Hence using specArgFreeIds+      in singleCall.++  NB to be fully kosher we should explicitly quantifying the CallInfo+  over 's', but we don't bother.  This would matter if there was an+  enclosing binding of the same 's', which I don't expect to happen.++(MP2) When we come to specialise the call, we must remember to quantify+      over 's'.  That is done in the SpecType case of specHeader, where+      we add 's' (called qvars) to the binders of the RULE and the specialised+      function.++(MP3) If we have f :: forall m. Monoid m => blah, and two calls+        (f @(Endo b)      (d1 :: Monoid (Endo b))+        (f @(Endo (c->c)) (d2 :: Monoid (Endo (c->c)))+      we want to generate a specialisation only for the first.  The second+      is just a substitution instance of the first, with no greater specialisation.+      Hence the use of `removeDupCalls` in `filterCalls`.++      You might wonder if `d2` might be more specialised than `d1`; but no.+      This `removeDupCalls` thing is at the definition site of `f`, and both `d1`+      and `d2` are in scope. So `d1` is simply more polymorphic than `d2`, but+      is just as specialised.++      This distinction is sadly lost once we build a RULE, so `alreadyCovered`+      can't be so clever.  E.g if we have an existing RULE+            forall @a (d1:Ord Int) (d2: Eq a). f @a @Int d1 d2 = ...+      and a putative new rule+            forall (d1:Ord Int) (d2: Eq Int). f @Int @Int d1 d2 = ...+      we /don't/ want the existing rule to subsume the new one.++      So we sadly put up with having two rather different places where we+      eliminate duplicates: `alreadyCovered` and `removeDupCalls`.++All this arose in #13873, in the unexpected form that a SPECIALISE+pragma made the program slower!  The reason was that the specialised+function $sinsertWith arising from the pragma looked rather like `f`+above, and failed to specialise a call in its body like wimwam.+Without the pragma, the original call to `insertWith` was completely+monomorpic, and specialised in one go.++Wrinkles.++* See Note [Weird special case for SpecDict]++* With -XOverlappingInstances you might worry about this:+    class C a where ...+    instance C (Maybe Int) where ...   -- $df1 :: C (Maybe Int)+    instance C (Maybe a)   where ...   -- $df2 :: forall a. C (Maybe a)++    f :: C a => blah+    f = rhs++    g = /\a.  ...(f @(Maybe a) ($df2 a))...+    h = ...f @(Maybe Int) $df1++  There are two calls to f, but with different evidence.  This patch will+  combine them into one.  But it's OK: this code will never arise unless you+  use -XIncoherentInstances.  Even with -XOverlappingInstances, GHC tries hard+  to keep dictionaries as singleton types.  But that goes out of the window+  with -XIncoherentInstances -- and that is true even with ordianry type-class+  specialisation (at least if any inlining has taken place).++  GHC makes very few guarantees when you use -XIncoherentInstances, and its+  not worth crippling the normal case for the incoherent corner.  (The best+  thing might be to switch off specialisation altogether if incoherence is+  involved... but incoherence is a property of an instance, not a class, so+  it's a hard test to make.)++  But see Note [Specialisation and overlapping instances].++Note [Weird special case for SpecDict]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+Suppose we are trying to specialise for this this call:+   $wsplit @T (mkD @k @(a::k) :: C T)+where+   mkD :: forall k (a::k). C T+is a top-level dictionary-former.  This actually happened in #22459,+because of (MP1) of Note [Specialising polymorphic dictionaries].++How can we specialise $wsplit?  We might try++   RULE "SPEC" forall (d :: C T). $wsplit @T d = $s$wsplit++but then in the body of $s$wsplit what will we use for the dictionary+evidence?  We can't use (mkD @k @(a::k)) because k and a aren't in scope.+We could zap `k` to (Any @Type) and `a` to (Any @(Any @Type)), but that+is a lot of hard work for a very strange case.++So we simply refrain from specialising in this case; hence the guard+   allVarSet (`elemInScopeSet` in_scope) (exprFreeVars d)+in the SpecDict cased of specHeader.++How did this strange polymorphic mkD arise in the first place?+From GHC.Core.Opt.Utils.abstractFloats, which was abstracting+over too many type variables. But that too is now fixed;+see Note [Which type variables to abstract over] in that module.+-}++instance Outputable DictBind where+  ppr (DB { db_bind = bind, db_fvs = fvs })+    = text "DB" <+> braces (sep [ text "fvs: " <+> ppr fvs+                                , text "bind:" <+> ppr bind ])++instance Outputable UsageDetails where+  ppr (MkUD { ud_binds = dbs, ud_calls = calls })+        = text "MkUD" <+> braces (sep (punctuate comma+                [text "binds" <+> equals <+> ppr dbs,+                 text "calls" <+> equals <+> ppr calls]))++instance Outputable FloatedDictBinds where+  ppr (FDB { fdb_binds = binds }) = ppr binds++emptyUDs :: UsageDetails+emptyUDs = MkUD { ud_binds = emptyFDBs, ud_calls = emptyDVarEnv }+++emptyFDBs :: FloatedDictBinds+emptyFDBs = FDB { fdb_binds = nilOL, fdb_bndrs = emptyVarSet }++------------------------------------------------------------+type CallDetails  = DIdEnv CallInfoSet+  -- The order of specialized binds and rules depends on how we linearize+  -- CallDetails, so to get determinism we must use a deterministic set here.+  -- See Note [Deterministic UniqFM] in GHC.Types.Unique.DFM++data CallInfoSet = CIS Id (Bag CallInfo)+  -- The list of types and dictionaries is guaranteed to+  -- match the type of f+  -- The Bag may contain duplicate calls (i.e. f @T and another f @T)+  -- These dups are eliminated by alreadyCovered in specCalls++data CallInfo+  = CI { ci_key  :: [SpecArg]   -- Arguments of the call+                                -- See Note [The (CI-KEY) invariant]++       , ci_fvs  :: IdSet       -- Free Ids of the ci_key call+                                -- /not/ including the main id itself, of course+                                -- NB: excluding tyvars:+                                --     See Note [Specialising polymorphic dictionaries]+    }++{- Note [The (CI-KEY) invariant]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+Invariant (CI-KEY):+   In the `ci_key :: [SpecArg]` field of `CallInfo`,+     * The list is non-empty+     * The least element is always a `SpecDict`++In this way the RULE has as few args as possible, which broadens its+applicability, since rules only fire when saturated.+-}++type DictExpr = CoreExpr++ciSetFilter :: (CallInfo -> Bool) -> CallInfoSet -> CallInfoSet+ciSetFilter p (CIS id a) = CIS id (filterBag p a)++instance Outputable CallInfoSet where+  ppr (CIS fn map) = hang (text "CIS" <+> ppr fn)+                        2 (ppr map)++pprCallInfo :: Id -> CallInfo -> SDoc+pprCallInfo fn (CI { ci_key = key })+  = ppr fn <+> ppr key++instance Outputable CallInfo where+  ppr (CI { ci_key = key, ci_fvs = _fvs })+    = text "CI" <> braces (sep (map ppr key))++unionCalls :: CallDetails -> CallDetails -> CallDetails+unionCalls c1 c2 = plusDVarEnv_C unionCallInfoSet c1 c2++unionCallInfoSet :: CallInfoSet -> CallInfoSet -> CallInfoSet+unionCallInfoSet (CIS f calls1) (CIS _ calls2) =+  CIS f (calls1 `unionBags` calls2)++callDetailsFVs :: CallDetails -> VarSet+callDetailsFVs calls =+  nonDetStrictFoldUDFM (unionVarSet . callInfoFVs) emptyVarSet calls+  -- It's OK to use nonDetStrictFoldUDFM here because we forget the ordering+  -- immediately by converting to a nondeterministic set.++callInfoFVs :: CallInfoSet -> VarSet+callInfoFVs (CIS _ call_info) =+  foldr (\(CI { ci_fvs = fv }) vs -> unionVarSet fv vs) emptyVarSet call_info++getTheta :: [PiTyBinder] -> [PredType]+getTheta = fmap piTyBinderType . filter isInvisiblePiTyBinder . filter isAnonPiTyBinder+++------------------------------------------------------------+singleCall :: SpecEnv -> Id -> [SpecArg] -> UsageDetails+singleCall spec_env id args+  = MkUD {ud_binds = emptyFDBs,+          ud_calls = unitDVarEnv id $ CIS id $+                     unitBag (CI { ci_key  = args+                                 , ci_fvs  = fvVarSet call_fvs }) }+  where+    poly_spec = gopt Opt_PolymorphicSpecialisation (se_dflags spec_env)++    -- With -fpolymorphic-specialisation, keep just local /Ids/+    -- Otherwise, keep /all/ free vars including TyVars+    -- See (MP1) in Note [Specialising polymorphic dictionaries]+    -- But NB: we don't include the 'id' itself.+    call_fvs | poly_spec = specArgsFVs isLocalId args+             | otherwise = specArgsFVs isLocalVar args++mkCallUDs :: SpecEnv -> OutExpr -> [OutExpr] -> UsageDetails+mkCallUDs env fun args+  | (_, Var f) <- stripTicksTop tickishFloatable fun -- See Note [Ticks on applications]+  = -- pprTraceWith "mkCallUDs" (\res -> vcat [ ppr f, ppr args, ppr res ]) $+    mkCallUDs' env f args+  | otherwise+  = emptyUDs++mkCallUDs' :: SpecEnv -> Id -> [OutExpr] -> UsageDetails+mkCallUDs' env f args+  | wantCallsFor env f    -- We want it, and...+  , not (null ci_key)     -- this call site has a useful specialisation+  = -- pprTrace "mkCallUDs: keeping" _trace_doc+    singleCall env f ci_key++  | otherwise  -- See also Note [Specialisations already covered]+  = -- pprTrace "mkCallUDs: discarding" _trace_doc+    emptyUDs++  where+    _trace_doc = vcat [ppr f, ppr args, ppr ci_key]+    pis                = fst $ splitPiTys $ idType f+    constrained_tyvars = tyCoVarsOfTypes $ getTheta pis++    ci_key :: [SpecArg]+    ci_key = dropWhileEndLE (not . isSpecDict) $+             zipWith mk_spec_arg args pis+             -- Establish (CI-KEY): drop trailing args until we get to a SpecDict++    mk_spec_arg :: OutExpr -> PiTyBinder -> SpecArg+    mk_spec_arg (Type ty) (Named bndr)+      |  binderVar bndr `elemVarSet` constrained_tyvars+      = SpecType ty+      | otherwise+      = UnspecType+    mk_spec_arg non_type_arg (Named bndr)+      = pprPanic "ci_key" $ (ppr non_type_arg $$ ppr bndr)++    -- For "invisibleFunArg", which are the type-class dictionaries,+    -- we decide on a case by case basis if we want to specialise+    -- on this argument; if so, SpecDict, if not UnspecArg+    mk_spec_arg arg (Anon _pred af)+      | isInvisibleFunArg af+      , interestingDict env arg+              -- See Note [Interesting dictionary arguments]+      = SpecDict arg++      | otherwise = UnspecArg++wantCallsFor :: SpecEnv -> Id -> Bool+-- See Note [wantCallsFor]+wantCallsFor _env f+  = case idDetails f of+      RecSelId {}      -> False+      DataConWorkId {} -> False+      DataConWrapId {} -> False+      ClassOpId {}     -> False+      PrimOpId {}      -> False+      FCallId {}       -> False+      TickBoxOpId {}   -> False+      CoVarId {}       -> False++      DFunId {}        -> True+      VanillaId {}     -> True+      JoinId {}        -> True+      WorkerLikeId {}  -> True+      RepPolyId {}     -> True++interestingDict :: SpecEnv -> CoreExpr -> Bool+-- This is a subtle and important function+-- See Note [Interesting dictionary arguments]+interestingDict env (Var v)  -- See (ID3) and (ID5)+  | Just rhs <- maybeUnfoldingTemplate (idUnfolding v)+  -- Might fail for loop breaker dicts but that seems fine.+  = interestingDict env rhs++interestingDict env arg  -- Main Plan: use exprIsConApp_maybe+  | Cast inner_arg _ <- arg  -- See (ID5)+  = if | isConstraintKind $ typeKind $ exprType inner_arg+       -- If coercions were always homo-kinded, we'd know+       -- that this would be the only case+       -> interestingDict env inner_arg++       -- Check for an implicit parameter at the top+       | Just (cls,_) <- getClassPredTys_maybe arg_ty+       , isIPClass cls      -- See (ID5)+       -> False++       -- Otherwise we are unwrapping a unary type class+       | otherwise+       -> exprIsHNF arg   -- See (ID7)++  | Just (_, _, data_con, _tys, args) <- exprIsConApp_maybe in_scope_env arg+  , Just cls <- tyConClass_maybe (dataConTyCon data_con)+  , definitely_not_ip_like       -- See (ID4)+  = if null (classMethods cls)   -- See (ID6)+    then any (interestingDict env) args+    else True++  | otherwise+  = not (exprIsTrivial arg) && definitely_not_ip_like  -- See (ID8)+  where+    arg_ty                  = exprType arg+    definitely_not_ip_like  = not (couldBeIPLike arg_ty)+    in_scope_env = ISE (substInScopeSet $ se_subst env) realIdUnfolding++{- Note [Ticks on applications]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+Ticks such as source location annotations can sometimes make their way+onto applications (see e.g. #21697). So if we see something like++    App (Tick _ f) e++we need to descend below the tick to find what the real function being+applied is.++The resulting RULE also has to be able to match this annotated use+site, so we only look through ticks that RULE matching looks through+(see Note [Tick annotations in RULE matching] in GHC.Core.Rules).++Note [wantCallsFor]+~~~~~~~~~~~~~~~~~~~+`wantCallsFor env f` says whether the Specialiser should collect calls for+function `f`; other thing being equal, the fewer calls we collect the better. It+is False for things we can't specialise:++* ClassOpId: never inline and we don't have a defn to specialise; we specialise+  them through fireRewriteRules.+* PrimOpId: are never overloaded+* Data constructors: we never specialise them++We could reduce the size of the UsageDetails by being less eager about+collecting calls for some LocalIds: there is no point for ones that are+lambda-bound.  We can't decide this by looking at the (absence of an) unfolding,+because unfoldings for local functions are discarded by cloneBindSM, so no local+binder will have an unfolding at this stage.  We'd have to keep a candidate set+of let-binders.++Not many lambda-bound variables have dictionary arguments, so this would make+little difference anyway.++For imported Ids we could check for an unfolding, but we have to do so anyway in+canSpecImport, and it seems better to have it all in one place.  So we simply+collect usage info for imported overloaded functions.++Note [Interesting dictionary arguments]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+Consider this+         \a.\d:Eq a.  let f = ... in ...(f d)...+There really is not much point in specialising f wrt the dictionary d,+because the code for the specialised f is not improved at all, because+d is lambda-bound.  We simply get junk specialisations.++What is "interesting"?  Our Main Plan is to use `exprIsConApp_maybe` to see+if the argument is a dictionary constructor applied to some arguments, in which+case we can clearly specialise. But there are wrinkles:++(ID1) Note that we look at the argument /term/, not its /type/.  Suppose the+  argument is+         (% d1, d2 %) |> co+  where co :: (% Eq [a], Show [a] %) ~ F Int a, and `F` is a type family.+  Then its type (F Int a) looks very un-informative, but the term is super+  helpful.  See #19747 (where missing this point caused a 70x slow down)+  and #7785.++(ID2) Note that the Main Plan works fine for an argument that is a DFun call,+   e.g.    $fOrdList $dOrdInt+   because `exprIsConApp_maybe` cleverly deals with DFunId applications.  Good!++(ID3) For variables, we look in the variable's /unfolding/.  And that means+   that we must be careful to ensure that dictionaries /have/ unfoldings:+   * cloneBndrSM discards non-Stable unfoldings+   * specBind updates the unfolding after specialisation+     See Note [Update unfolding after specialisation]+   * bindAuxiliaryDict adds an unfolding for an aux dict+     see Note [Specialisation modulo dictionary selectors]+   * specCase adds unfoldings for the new bindings it creates++   We accidentally lost accurate tracking of local variables for a long+   time, because cloned variables didn't have unfoldings. But makes a+   massive difference in a few cases, eg #5113. For nofib as a+   whole it's only a small win: 2.2% improvement in allocation for ansi,+   1.2% for bspt, but mostly 0.0!  Average 0.1% increase in binary size.++(ID4) We must be very careful not to specialise on a "dictionary" that is, or contains+   an implicit parameter, because implicit parameters are emphatically not singleton+   types.  See #25999:+     useImplicit :: (?i :: Int) => Int+     useImplicit = ?i + 1++     foo = let ?i = 1 in (useImplicit, let ?i = 2 in useImplicit)+   Both calls to `useImplicit` are at type `?i::Int`, but they pass different values.+   We must not specialise on implicit parameters!  Hence the call to `couldBeIPLike`+   in `definitely_not_ip_like`.++(ID5) Suppose the argument is (e |> co).  Can we rely on `exprIsConApp_maybe` to deal+   with the coercion.  No!  That only works if (co :: C t1 ~ C t2) with the same type+   constructor at the top of both sides.  But see the example in (ID1), where that+   is not true.  For the same reason, we can't rely on `exprIsConApp_maybe` to look+   through unfoldings (because there might be a cast inside), hence dealing with+   expandable unfoldings in `interestingDict` directly.++   For the same reasons as in (ID4), we must take care to not allow an implicit+   parameter to sneak through, so we must not unwrap the newtype cast for the+   unary IP class; hence the `isIPClass` call.  (We don't need to call+   `couldBeIPLike`, as implicit parameters hidden behind a type family are+   detected by the recursive call to `interestingDict` on the argument inside the+   cast.)++(ID6) The Main Plan says that it's worth specialising if the argument is an application+   of a dictionary contructor.  But what if the dictionary has no methods?  Then we+   gain nothing by specialising, unless the /superclasses/ are interesting.   A case+   in point is constraint tuples (% d1, .., dn %); a constraint N-tuple is a class+   with N superclasses and no methods.++(ID7) A unary (single-method) class is currently represented by (meth |> co).  We+   will unwrap the cast (see (ID5)) and then want to reply "yes" if the method+   has any struture.  We rather arbitrarily use `exprIsHNF` for this.  (We plan a+   new story for unary classes, see #23109, and this special case will become+   irrelevant.)++(ID8) Sadly, if `exprIsConApp_maybe` says Nothing, we still want to treat a+   non-trivial argument as interesting. In T19695 we have this:+      askParams :: Monad m => blah+      mhelper   :: MonadIO m => blah+      mhelper (d:MonadIO m) = ...(askParams @m ($p1 d))....+   where `$p1` is the superclass selector for `MonadIO`.  Now, if `mhelper` is+   specialised at `Handler` we'll get this call in the specialised `$smhelper`:+            askParams @Handler ($p1 $fMonadIOHandler)+   and we /definitely/ want to specialise that, even though the argument isn't+   visibly a dictionary application.  In fact the specialiser fires the superclass+   selector rule (see Note [Fire rules in the specialiser]), so we get+            askParams @Handler ($cp1MonadIO $fMonadIOIO)+   but it /still/ doesn't look like a dictionary application.++   Conclusion: we optimistically assume that any non-trivial argument is worth+   specialising on.++   So why do the `exprIsConApp_maybe` and `Cast` stuff? Because we want to look+   under type-family casts (ID1) and constraint tuples (ID6).++Note [Update unfolding after specialisation]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+Consider (#21848)++  wombat :: Show b => Int -> b -> String+  wombat a b | a>0       = wombat (a-1) b+             | otherwise = show a ++ wombat a b++  class C a where+    meth :: Show b => a -> b -> String+    dummy :: a -> () -- Force a datatype dictionary representation++  instance C Int where+    meth = wombat+    dummy _ = ()++  class C a => D a   -- D has C as a superclass+  instance D Int++  f :: (D a, Show b) => a -> b -> String+  {-# INLINABLE[0] f #-}+  f a b = meth a b ++ "!" ++ meth a b++Now `f` turns into:++  f @a @b (dd :: D a) (ds :: Show b) a b++     = let dc :: D a = %p1 dd  -- Superclass selection+       in meth @a dc ....+          meth @a dc ....++When we specialise `f`, at a=Int say, that superclass selection can+fire (via rewiteClassOps), but that info (that 'dc' is now a+particular dictionary `C`, of type `C Int`) must be available to+the call `meth @a dc`, so that we can fire the `meth` class-op, and+thence specialise `wombat`.++We deliver on this idea by updating the unfolding for the binder+in the NonRec case of specBind.  (This is too exotic to trouble with+the Rec case.)+-}++thenUDs :: UsageDetails -> UsageDetails -> UsageDetails+thenUDs (MkUD {ud_binds = db1, ud_calls = calls1})+        (MkUD {ud_binds = db2, ud_calls = calls2})+  = MkUD { ud_binds       = db1    `thenFDBs`   db2+         , ud_calls       = calls1 `unionCalls`  calls2 }++thenFDBs :: FloatedDictBinds -> FloatedDictBinds -> FloatedDictBinds+-- Combine FloatedDictBinds+-- In (dbs1 `thenFDBs` dbs2), dbs2 may mention dbs1 but not vice versa+thenFDBs (FDB { fdb_binds = dbs1, fdb_bndrs = bs1 })+         (FDB { fdb_binds = dbs2, fdb_bndrs = bs2 })+  = FDB { fdb_binds = dbs1 `appOL` dbs2+        , fdb_bndrs = bs1  `unionVarSet` bs2 }++-----------------------------+_dictBindBndrs :: OrdList DictBind -> [Id]+_dictBindBndrs dbs = foldr ((++) . bindersOf . db_bind) [] dbs++-- | Construct a 'DictBind' from a 'CoreBind'+mkDB :: CoreBind -> DictBind+mkDB bind = DB { db_bind = bind, db_fvs = bind_fvs bind }++-- | Identify the free variables of a 'CoreBind'+bind_fvs :: CoreBind -> VarSet+bind_fvs (NonRec bndr rhs) = pair_fvs (bndr,rhs)+bind_fvs (Rec prs)         = rhs_fvs `delVarSetList` (map fst prs)+                           where+                             rhs_fvs = unionVarSets (map pair_fvs prs)++pair_fvs :: (Id, CoreExpr) -> VarSet+pair_fvs (bndr, rhs) = exprSomeFreeVars interesting rhs+                       `unionVarSet` idFreeVars bndr+        -- idFreeVars: don't forget variables mentioned in+        -- the rules of the bndr.  C.f. OccAnal.addRuleUsage+        -- Also tyvars mentioned in its type; they may not appear+        -- in the RHS+        --      type T a = Int+        --      x :: T a = 3+  where+    interesting :: InterestingVarFun+    interesting v = isLocalVar v || (isId v && isDFunId v)+        -- Very important: include DFunIds /even/ if it is imported+        -- Reason: See Note [Avoiding loops in specImports], the #13429+        --         example involving an imported dfun.  We must know+        --         whether a dictionary binding depends on an imported+        --         DFun in case we try to specialise that imported DFun++-- | Flatten a set of "dumped" 'DictBind's, and some other binding+-- pairs, into a single recursive binding.+recWithDumpedDicts :: [(Id,CoreExpr)] -> OrdList DictBind -> DictBind+recWithDumpedDicts pairs dbs+  = DB { db_bind = Rec bindings+       , db_fvs = fvs `delVarSetList` map fst bindings }+  where+    (bindings, fvs) = foldr add ([], emptyVarSet)+                                (dbs `snocOL` mkDB (Rec pairs))+    add (DB { db_bind = bind, db_fvs = fvs }) (prs_acc, fvs_acc)+      = case bind of+          NonRec b r -> ((b,r) : prs_acc, fvs')+          Rec prs1   -> (prs1 ++ prs_acc, fvs')+      where+        fvs' = fvs_acc `unionVarSet` fvs++snocDictBind :: UsageDetails -> DictBind -> UsageDetails+snocDictBind uds@MkUD{ud_binds= FDB { fdb_binds = dbs, fdb_bndrs = bs }} db+  = uds { ud_binds = FDB { fdb_binds = dbs `snocOL` db+                         , fdb_bndrs = bs `extendVarSetList` bindersOfDictBind db } }++snocDictBinds :: UsageDetails -> [DictBind] -> UsageDetails+-- Add ud_binds to the tail end of the bindings in uds+snocDictBinds uds@MkUD{ud_binds=FDB{ fdb_binds = binds, fdb_bndrs = bs }} dbs+  = uds { ud_binds = FDB { fdb_binds = binds `appOL`        (toOL dbs)+                         , fdb_bndrs = bs    `extendVarSetList` bindersOfDictBinds dbs } }++consDictBinds :: [DictBind] -> UsageDetails -> UsageDetails+consDictBinds dbs uds@MkUD{ud_binds=FDB{fdb_binds = binds, fdb_bndrs = bs}}+  = uds { ud_binds = FDB{ fdb_binds = toOL dbs `appOL` binds+                        , fdb_bndrs = bs `extendVarSetList` bindersOfDictBinds dbs } }++wrapDictBinds :: FloatedDictBinds -> [CoreBind] -> [CoreBind]+wrapDictBinds (FDB { fdb_binds = dbs }) binds+  = foldr add binds dbs+  where+    add (DB { db_bind = bind }) binds = bind : binds++wrapDictBindsE :: OrdList DictBind -> CoreExpr -> CoreExpr+wrapDictBindsE dbs expr+  = foldr add expr dbs+  where+    add (DB { db_bind = bind }) expr = Let bind expr++----------------------+dumpUDs :: [CoreBndr] -> UsageDetails -> (UsageDetails, OrdList DictBind)+-- Used at a lambda or case binder; just dump anything mentioning the binder+dumpUDs bndrs uds@(MkUD { ud_binds = orig_dbs, ud_calls = orig_calls })+  | null bndrs = (uds, nilOL)  -- Common in case alternatives+  | otherwise  = -- pprTrace "dumpUDs" (vcat+                 --    [ text "bndrs" <+> ppr bndrs+                 --    , text "uds" <+> ppr uds+                 --    , text "free_uds" <+> ppr free_uds+                 --    , text "dump-dbs" <+> ppr dump_dbs ]) $+                 (free_uds, dump_dbs)+  where+    free_uds = uds { ud_binds = free_dbs, ud_calls = free_calls }+    bndr_set = mkVarSet bndrs+    (free_dbs, dump_dbs, dump_set) = splitDictBinds orig_dbs bndr_set+    free_calls = deleteCallsMentioning dump_set $   -- Drop calls mentioning bndr_set on the floor+                 deleteCallsFor bndrs orig_calls    -- Discard calls for bndr_set; there should be+                                                    -- no calls for any of the dicts in dump_dbs++dumpBindUDs :: [CoreBndr] -> UsageDetails -> (UsageDetails, OrdList DictBind, Bool)+-- Used at a let(rec) binding.+-- We return a boolean indicating whether the binding itself is mentioned,+-- directly or indirectly, by any of the ud_calls; in that case we want to+-- float the binding itself;+-- See Note [Floated dictionary bindings]+dumpBindUDs bndrs (MkUD { ud_binds = orig_dbs, ud_calls = orig_calls })+  = -- pprTrace "dumpBindUDs" (ppr bndrs $$ ppr free_uds $$ ppr dump_dbs $$ ppr float_all) $+    (free_uds, dump_dbs, float_all)+  where+    free_uds = MkUD { ud_binds = free_dbs, ud_calls = free_calls }+    bndr_set = mkVarSet bndrs+    (free_dbs, dump_dbs, dump_set) = splitDictBinds orig_dbs bndr_set+    free_calls = deleteCallsFor bndrs orig_calls+    float_all = dump_set `intersectsVarSet` callDetailsFVs free_calls++callsForMe :: Id -> UsageDetails -> (UsageDetails, [CallInfo])+callsForMe fn uds@MkUD { ud_binds = orig_dbs, ud_calls = orig_calls }+  = -- pprTrace ("callsForMe")+    --          (vcat [ppr fn,+    --                 text "Orig dbs ="     <+> ppr (_dictBindBndrs orig_dbs),+    --                 text "Orig calls ="   <+> ppr orig_calls,+    --                 text "Calls for me =" <+> ppr calls_for_me]) $+    (uds_without_me, calls_for_me)+  where+    uds_without_me = uds { ud_calls = delDVarEnv orig_calls fn }+    calls_for_me = case lookupDVarEnv orig_calls fn of+                        Nothing -> []+                        Just cis -> filterCalls cis orig_dbs++----------------------+filterCalls :: CallInfoSet -> FloatedDictBinds -> [CallInfo]+-- Remove+--   (a) dominated calls: (MP3) in Note [Specialising polymorphic dictionaries]+--   (b) loopy DFuns: Note [Avoiding loops (DFuns)]+filterCalls (CIS fn call_bag) (FDB { fdb_binds = dbs })+  | isDFunId fn  = filter ok_call de_dupd_calls  -- Deals with (b)+  | otherwise    = de_dupd_calls+  where+    de_dupd_calls = removeDupCalls call_bag -- Deals with (a)++    dump_set = foldl' go (unitVarSet fn) dbs+      -- This dump-set could also be computed by splitDictBinds+      --   (_,_,dump_set) = splitDictBinds dbs {fn}+      -- But this variant is shorter++    go so_far (DB { db_bind = bind, db_fvs = fvs })+       | fvs `intersectsVarSet` so_far+       = extendVarSetList so_far (bindersOf bind)+       | otherwise = so_far++    ok_call (CI { ci_fvs = fvs }) = fvs `disjointVarSet` dump_set++removeDupCalls :: Bag CallInfo -> [CallInfo]+-- Calls involving more generic instances beat more specific ones.+-- See (MP3) in Note [Specialising polymorphic dictionaries]+removeDupCalls calls = foldr add [] calls+  where+    add :: CallInfo -> [CallInfo] -> [CallInfo]+    add ci [] = [ci]+    add ci1 (ci2:cis) | ci2 `beats_or_same` ci1 = ci2:cis+                      | ci1 `beats_or_same` ci2 = ci1:cis+                      | otherwise               = ci2 : add ci1 cis++beats_or_same :: CallInfo -> CallInfo -> Bool+-- (beats_or_same ci1 ci2) is True if specialising on ci1 subsumes ci2+-- That is: ci1's types are less specialised than ci2+--          ci1   specialises on the same dict args as ci2+beats_or_same (CI { ci_key = args1 }) (CI { ci_key = args2 })+  = go args1 args2+  where+    go []           []           = True+    go (arg1:args1) (arg2:args2) = go_arg arg1 arg2 && go args1 args2++    -- If one or the other runs dry, the other must still have a SpecDict+    -- because of the (CI-KEY) invariant.  So neither subsumes the other;+    -- one is more specialised (faster code) but the other is more generally+    -- applicable.+    go  _ _ = False++    go_arg (SpecType ty1) (SpecType ty2) = isJust (tcMatchTy ty1 ty2)+    go_arg (SpecDict {})  (SpecDict {})  = True+    go_arg UnspecType     UnspecType     = True+    go_arg UnspecArg      UnspecArg      = True+    go_arg _              _              = False++----------------------+splitDictBinds :: FloatedDictBinds -> IdSet -> (FloatedDictBinds, OrdList DictBind, IdSet)+-- splitDictBinds dbs bndrs returns+--   (free_dbs, dump_dbs, dump_set)+-- where+--   * dump_dbs depends, transitively on bndrs+--   * free_dbs does not depend on bndrs+--   * dump_set = bndrs `union` bndrs(dump_dbs)+splitDictBinds (FDB { fdb_binds = dbs, fdb_bndrs = bs }) bndr_set+   = (FDB { fdb_binds = free_dbs+          , fdb_bndrs = bs `minusVarSet` dump_set }+     , dump_dbs, dump_set)+   where+    (free_dbs, dump_dbs, dump_set)+      = foldl' split_db (nilOL, nilOL, bndr_set) dbs+                -- Important that it's foldl' not foldr;+                -- we're accumulating the set of dumped ids in dump_set++    split_db (free_dbs, dump_dbs, dump_idset) db+        | DB { db_bind = bind, db_fvs = fvs } <- db+        , dump_idset `intersectsVarSet` fvs     -- Dump it+        = (free_dbs, dump_dbs `snocOL` db,+           extendVarSetList dump_idset (bindersOf bind))++        | otherwise     -- Don't dump it+        = (free_dbs `snocOL` db, dump_dbs, dump_idset)+++----------------------+deleteCallsMentioning :: VarSet -> CallDetails -> CallDetails+-- Remove calls mentioning any Id in bndrs+-- NB: The call is allowed to mention TyVars in bndrs+--     Note [Specialising polymorphic dictionaries]+--     ci_fvs are just the free /Ids/+deleteCallsMentioning bndrs calls+  = mapDVarEnv (ciSetFilter keep_call) calls+  where+    keep_call (CI { ci_fvs = fvs }) = fvs `disjointVarSet` bndrs++deleteCallsFor :: [Id] -> CallDetails -> CallDetails+-- Remove calls *for* bndrs+deleteCallsFor bndrs calls = delDVarEnvList calls bndrs++{-+************************************************************************+*                                                                      *+\subsubsection{Boring helper functions}+*                                                                      *+************************************************************************+-}++type SpecM a = UniqSM a++runSpecM :: SpecM a -> CoreM a+runSpecM thing_inside+  = do { us <- getUniqueSupplyM+       ; return (initUs_ us thing_inside) }++mapAndCombineSM :: (a -> SpecM (b, UsageDetails)) -> [a] -> SpecM ([b], UsageDetails)+mapAndCombineSM _ []     = return ([], emptyUDs)+mapAndCombineSM f (x:xs) = do (y, uds1) <- f x+                              (ys, uds2) <- mapAndCombineSM f xs+                              return (y:ys, uds1 `thenUDs` uds2)++-- extendTvSubst :: SpecEnv -> TyVar -> Type -> SpecEnv+-- extendTvSubst env tv ty+--   = env { se_subst = Core.extendTvSubst (se_subst env) tv ty }++extendInScope :: SpecEnv -> OutId -> SpecEnv+extendInScope env@(SE { se_subst = subst }) bndr+  = env { se_subst = subst `Core.extendSubstInScope` bndr }++zapSubst :: SpecEnv -> SpecEnv+zapSubst env@(SE { se_subst = subst })+  = env { se_subst = Core.zapSubst subst }++substTy :: SpecEnv -> Type -> Type+substTy env ty = substTyUnchecked (se_subst env) ty++substCo :: SpecEnv -> Coercion -> Coercion+substCo env co = Core.substCo (se_subst env) co++substBndr :: SpecEnv -> CoreBndr -> (SpecEnv, CoreBndr)+substBndr env bs = case Core.substBndr (se_subst env) bs of+                      (subst', bs') -> (env { se_subst = subst' }, bs')++substBndrs :: Traversable f => SpecEnv -> f CoreBndr -> (SpecEnv, f CoreBndr)+substBndrs env bs = case Core.substBndrs (se_subst env) bs of+                      (subst', bs') -> (env { se_subst = subst' }, bs')++cloneBndrSM :: SpecEnv -> Id -> SpecM (SpecEnv, Id)+-- Clone the binders of the bind; return new bind with the cloned binders+-- Return the substitution to use for RHSs, and the one to use for the body+-- Discards non-Stable unfoldings+cloneBndrSM env@(SE { se_subst = subst }) bndr+  = do { us <- getUniqueSupplyM+       ; let (subst', bndr') = Core.cloneIdBndr subst us bndr+       ; return (env { se_subst = subst' }, bndr') }++cloneRecBndrsSM :: SpecEnv -> [Id] -> SpecM (SpecEnv, [Id])+cloneRecBndrsSM env@(SE { se_subst = subst }) bndrs+  = do { (subst', bndrs') <- Core.cloneRecIdBndrsM subst bndrs+       ; let env' = env { se_subst = subst' }+       ; return (env', bndrs') }  newSpecIdSM :: Name -> Type -> IdDetails -> IdInfo -> SpecM Id     -- Give the new Id a similar occurrence name to the old one
GHC/Core/Opt/StaticArgs.hs view
@@ -111,7 +111,7 @@     let (binders, rhss) = unzip pairs     rhss_SATed <- mapM (\e -> satTopLevelExpr e interesting_ids) rhss     let (rhss', sat_info_rhss') = unzip rhss_SATed-    return (Rec (zipEqual "satBind" binders rhss'), mergeIdSATInfos sat_info_rhss')+    return (Rec (zipEqual binders rhss'), mergeIdSATInfos sat_info_rhss')  data App = VarApp Id | TypeApp Type | CoApp Coercion data Staticness a = Static a | NotStatic
GHC/Core/Opt/WorkWrap.hs view
@@ -176,9 +176,8 @@ mischief.)  Notice that we refrain from w/w'ing an INLINE function even if it is-in a recursive group.  It might not be the loop breaker.  (We used to-test for loop-breaker-hood, but see (CWW4) in Note [Cast worker/wrapper]-in GHC.Core.Opt.Simplify.Iteration.)+in a recursive group.  It might not be the loop breaker.  (We could+test for loop-breaker-hood, but I'm not sure that ever matters.)  Note [Worker/wrapper for INLINABLE functions] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
GHC/Core/Opt/WorkWrap/Utils.hs view
@@ -16,6 +16,7 @@    , mkAbsentFiller    , isWorkerSmallEnough, dubiousDataConInstArgTys    , boringSplit, usefulSplit, workWrapArity+   , canUnboxType, canUnboxTyCon    ) where @@ -32,6 +33,7 @@ import GHC.Core.Predicate( isDictTy ) import GHC.Core.Reduction import GHC.Core.FamInstEnv+import GHC.Core.Predicate( isEqualityClass ) import GHC.Core.TyCon import GHC.Core.TyCon.Set import GHC.Core.TyCon.RecWalk@@ -218,7 +220,7 @@         ; let args_free_tcvs = tyCoVarsOfTypes (res_ty : map varType arg_vars)               empty_subst = mkEmptySubst (mkInScopeSet args_free_tcvs)               zapped_arg_vars = map zap_var arg_vars-        ; (subst, cloned_arg_vars) <- cloneBndrs empty_subst zapped_arg_vars+        ; (subst, cloned_arg_vars) <- cloneBndrsM empty_subst zapped_arg_vars         ; let res_ty' = substTyUnchecked subst res_ty               init_str_marks = map (const NotMarkedStrict) cloned_arg_vars @@ -611,7 +613,7 @@ -- 's' will be 'Demand' or 'Cpr'. data DataConPatContext s   = DataConPatContext-  { dcpc_dc      :: !DataCon+  { dcpc_dc      :: !DataCon  -- INVARIANT: canUnboxTyCon is true of this DataCon's tycon   , dcpc_tc_args :: ![Type]   , dcpc_co      :: !Coercion   , dcpc_args    :: ![s]@@ -664,7 +666,7 @@    -- From here we are strict and not absent   | Just (tc, tc_args, co) <- normSplitTyConApp_maybe fam_envs ty-  , Just dc <- tyConSingleAlgDataCon_maybe tc+  , Just [dc] <- canUnboxTyCon tc  -- tc is never a newtype   , let arity = dataConRepArity dc   , Just (Unboxed, dmds) <- viewProd arity sd -- See Note [Boxity analysis]   , dmds `lengthIs` dataConRepArity dc@@ -682,7 +684,7 @@ canUnboxResult fam_envs ty cpr   | Just (con_tag, arg_cprs) <- asConCpr cpr   , Just (tc, tc_args, co) <- normSplitTyConApp_maybe fam_envs ty-  , Just dcs <- tyConAlgDataCons_maybe tc <|> open_body_ty_warning+  , Just dcs <- canUnboxTyCon tc <|> open_body_ty_warning   , dcs `lengthAtLeast` con_tag -- This might not be true if we import the                                 -- type constructor via a .hs-boot file (#8743)   , let dc = dcs `getNth` (con_tag - fIRST_TAG)@@ -702,8 +704,101 @@     -- See Note [non-algebraic or open body type warning]     open_body_ty_warning = warnPprTrace True "canUnboxResult: non-algebraic or open body type" (ppr ty) Nothing -{- Note [Which types are unboxed?]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+++canUnboxType :: HasDebugCallStack => Type -> Maybe [DataCon]+canUnboxType arg_ty = case tyConAppTyCon_maybe arg_ty of+                        Just tc -> canUnboxTyCon tc+                        Nothing -> Nothing++canUnboxTyCon :: HasDebugCallStack => TyCon -> Maybe [DataCon]+-- True for+--   boxed algebraic datatypes+--   unboxed tuples and sums+--+-- False for+--   class dictionaries, except equality classes and tuples+--               See Note [Do not unbox class dictionaries]+--+-- Precondition: tc is not a newtype+canUnboxTyCon tc+  | Just cls <- tyConClass_maybe tc+  , not (isEqualityClass cls)+  = Nothing     -- See (DNB2) and (DNB1) in Note [Do not unbox class dictionaries]++  | otherwise+  = assertPpr (not (isNewTyCon tc)) (ppr tc) $  -- Check precondition+    tyConDataCons_maybe tc++{- Note [Do not unbox class dictionaries]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+We never unbox class dictionaries in worker/wrapper.++1. INLINABLE functions+   If we have+      f :: Ord a => [a] -> Int -> a+      {-# INLINABLE f #-}+   and we worker/wrapper f, we'll get a worker with an INLINABLE pragma+   (see Note [Worker/wrapper for INLINABLE functions] in GHC.Core.Opt.WorkWrap),+   which can still be specialised by the type-class specialiser, something like+      fw :: Ord a => [a] -> Int# -> a++   BUT if f is strict in the Ord dictionary, we might unpack it, to get+      fw :: (a->a->Bool) -> [a] -> Int# -> a+   and the type-class specialiser can't specialise that. An example is #6056.++   Historical note: #14955 describes how I got this fix wrong the first time.+   I got aware of the issue in T5075 by the change in boxity of loop between+   demand analysis runs.++2. -fspecialise-aggressively.  As #21286 shows, the same phenomenon can occur+   occur without INLINABLE, when we use -fexpose-all-unfoldings and+   -fspecialise-aggressively to do vigorous cross-module specialisation.++3. #18421 found that unboxing a dictionary can also make the worker less likely+   to inline; the inlining heuristics seem to prefer to inline a function+   applied to a dictionary over a function applied to a bunch of functions.++TL;DR we /never/ unbox class dictionaries. Unboxing the dictionary, and passing+a raft of higher-order functions isn't a huge win anyway -- you really want to+specialise the function.++Wrinkle (DNB1): we /do not/ to unbox tuple dictionaries either.  We used to+  have a special case to unbox tuple dictionaries (#23398), but it ultimately+  turned out to be a very bad idea (see !19747#note_626297).   In summary:++  - If w/w unboxes tuple dictionaries we get things like+         case d of CTuple2 d1 d2 -> blah+    rather than+         let { d1 = sc_sel1 d; d2 = sc_sel2 d } in blah+    The latter works much better with the specialiser: when `d` is instantiated+    to some useful dictionary the `sc_sel1 d` selection can fire.++   - The attempt to deal with unpacking dictionaries with `case` led to+     significant extra complexity in the type-class specialiser (#26158) that is+     rendered unnecessary if we only take do superclass selection with superclass+     selectors, never with `case` expressions.++     Even with that extra complexity, specialisation was /still/ sometimes worse,+     and sometimes /tremendously/ worse (a factor of 70x); see #19747.++   - Suppose f :: forall a. (% Eq a, Show a %) => blah+     The specialiser is perfectly capable of specialising a call like+             f @Int (% dEqInt, dShowInt %)+     so the tuple doesn't get in the way.++   - It's simpler and more uniform.  There is nothing special about constraint+     tuples; anyone can write   class (C1 a, C2 a) => D a  where {}++Wrinkle (DNB2): we /do/ want to unbox equality dictionaries,+  for (~), (~~), and Coercible (#23398).  Their payload is a single unboxed+  coercion.  We never want to specialise on `(t1 ~ t2)`.  All that would do is+  to make a copy of the function's RHS with a particular coercion.  Unlike+  normal class methods, that does not unlock any new optimisation+  opportunities in the specialised RHS.++Note [Which types are unboxed?]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Worker/wrapper will unbox    1. A strict data type argument, that@@ -835,7 +930,7 @@ before calling the partially applied function. But this would be neither a small nor simple change so we stick with A) and a flag for B) for now. -See also Note [Tag Inference] and Note [CBV Function Ids]+See also Note [EPT enforcement] and Note [CBV Function Ids]  Note [Worker/wrapper for strict arguments] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~@@ -861,7 +956,7 @@  The worker `$wf` is a CBV function (see `Note [CBV Function Ids]` in GHC.Types.Id.Info) and the code generator guarantees that every-call to `$wf` has a properly tagged argument (see `GHC.Stg.InferTags.Rewrite`).+call to `$wf` has a properly tagged argument (see `GHC.Stg.EnforceEpt.Rewrite`).  Is this a win?  Not always: * It can cause slight codesize increases. This is since we push evals to every@@ -984,7 +1079,7 @@              -- don't end up in lambda binders of the worker.              -- See Note [Never put `OtherCon` unfoldings on lambda binders]              arg_ids' = map zapIdUnfolding $-                        zipWithEqual "unbox_one_arg" setIdDemandInfo arg_ids ds+                        zipWithEqual setIdDemandInfo arg_ids ds               unbox_fn = mkUnpackCase (Var arg_var) co (idMult arg_var)                                      dc (ex_tvs' ++ arg_ids')@@ -1352,7 +1447,8 @@        | Just (HetReduction (Reduction _ rhs) _) <- topReduceTyFamApp_maybe fam_envs tc tc_args        = go rec_tc rhs -       | Just con <- tyConSingleAlgDataCon_maybe tc+       | not (isNewTyCon tc)+       , Just con <- tyConSingleDataCon_maybe tc        , Just rec_tc <- if isTupleTyCon tc                         then Just rec_tc                         else checkRecTc rec_tc tc
GHC/Core/PatSyn.hs view
@@ -12,7 +12,8 @@         PatSyn, PatSynMatcher, PatSynBuilder, mkPatSyn,          -- ** Type deconstruction-        patSynName, patSynArity, patSynIsInfix, patSynResultType,+        patSynName, patSynArity, patSynVisArity,+        patSynIsInfix, patSynResultType,         isVanillaPatSyn,         patSynArgs,         patSynMatcher, patSynBuilder,@@ -421,6 +422,13 @@ -- | Arity of the pattern synonym patSynArity :: PatSyn -> Arity patSynArity = psArity++-- | Number of visible arguments of the pattern synonym+patSynVisArity :: PatSyn -> VisArity+patSynVisArity ps = n_of_required_ty_args + n_of_val_args+  where+    n_of_val_args = psArity ps+    n_of_required_ty_args = 0   -- no visible forall in pattern synonyms yet (#23704)  -- | Is this a \'vanilla\' pattern synonym (no existentials, no provided constraints)? isVanillaPatSyn :: PatSyn -> Bool
GHC/Core/Ppr.hs view
@@ -694,10 +694,10 @@             ppr modl, comma,             ppr ix,             text ">"]-  ppr (Breakpoint _ext ix vars modl) =+  ppr (Breakpoint _ext bid vars) =       hcat [text "break<",-            ppr modl, comma,-            ppr ix,+            ppr (bi_tick_mod bid), comma,+            ppr (bi_tick_index bid),             text ">",             parens (hcat (punctuate comma (map ppr vars)))]   ppr (ProfNote { profNoteCC = cc,
GHC/Core/Predicate.hs view
@@ -8,50 +8,117 @@  module GHC.Core.Predicate (   Pred(..), classifyPredType,-  isPredTy, isEvVarType,+  isPredTy, isSimplePredTy,    -- Equality predicates   EqRel(..), eqRelRole,-  isEqPrimPred, isNomEqPred, isReprEqPrimPred, isEqPred, isCoVarType,+  isEqPred, isReprEqPred, isEqClassPred, isCoVarType,   getEqPredTys, getEqPredTys_maybe, getEqPredRole,-  predTypeEqRel,-  mkPrimEqPred, mkReprPrimEqPred, mkPrimEqPredRole,-  mkNomPrimEqPred,+  predTypeEqRel, pprPredType,+  mkNomEqPred, mkReprEqPred, mkEqPred, mkEqPredRole,    -- Class predicates   mkClassPred, isDictTy, typeDeterminesValue,-  isClassPred, isEqualityClass, isCTupleClass,+  isClassPred, isEqualityClass, isCTupleClass, isUnaryClass,   getClassPredTys, getClassPredTys_maybe,   classMethodTy, classMethodInstTy,    -- Implicit parameters-  isIPLikePred, mentionsIP, isIPTyCon, isIPClass,+  couldBeIPLike, mightMentionIP, isIPTyCon, isIPClass, decomposeIPPred,   isCallStackTy, isCallStackPred, isCallStackPredTy,   isExceptionContextPred, isExceptionContextTy,   isIPPred_maybe,    -- Evidence variables-  DictId, isEvVar, isDictId+  DictId, isEvId, isDictId, +  -- * Well-scoped free variables+  scopedSort, tyCoVarsOfTypeWellScoped,+  tyCoVarsOfTypesWellScoped,++  -- Equality left-hand sides+  CanEqLHS(..), canEqLHS_maybe, canTyFamEqLHS_maybe,+  canEqLHSKind, canEqLHSType, eqCanEqLHS+   ) where  import GHC.Prelude  import GHC.Core.Type import GHC.Core.Class+import GHC.Core.TyCo.Compare( tcEqTyConApps )+import GHC.Core.TyCo.FVs( tyCoVarsOfTypeList, tyCoVarsOfTypesList ) import GHC.Core.TyCon import GHC.Core.TyCon.RecWalk+import GHC.Types.Name( getOccName ) import GHC.Types.Var-import GHC.Core.Coercion+import GHC.Types.Var.Set import GHC.Core.Multiplicity ( scaledThing )  import GHC.Builtin.Names+import GHC.Builtin.Types.Prim( eqPrimTyCon, eqReprPrimTyCon )  import GHC.Utils.Outputable import GHC.Utils.Misc import GHC.Utils.Panic import GHC.Data.FastString ++{- *********************************************************************+*                                                                      *+*                   Pred and PredType                                  *+*                                                                      *+********************************************************************* -}++{- Note [Types for coercions, predicates, and evidence]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+A "predicate" or "predicate type",+    type synonym `PredType`+    returns True to `isPredTy`+is any type of kind (CONSTRAINT r) for some `r`.++  (a) A "class predicate" (aka dictionary type) is the type of a (boxed)+      type-class dictionary+        Test: isDictTy+        Binders: DictIds+        Kind: Constraint+        Examples: (Eq a), and (a ~ b)++  (b) An "equality predicate" is a primitive, unboxed equalities+        Test: isEqPred+        Binders: CoVars (can appear in coercions)+        Kind: CONSTRAINT (TupleRep [])+        Examples: (t1 ~# t2) or (t1 ~R# t2)++  (c) A "simple predicate type" is either a class predicate or an equality predicate+        Test: isSimplePredTy+        Kind: Constraint or CONSTRAINT (TupleRep [])+        Examples: all coercion types and dictionary types++  (d) A "forall-predicate" is the type of a possibly-polymorphic function+      returning a predicate; e.g.+           forall a. Eq a => Eq [a]++  (e) An "irred predicate" is any other type of kind (CONSTRAINT r),+      typically something like `c` or `c Int`, for some suitably-kinded `c`+++* Predicates are classified by `classifyPredType`.++* Equality types and dictionary types are mutually exclusive.++* Predicates are the things solved by the constraint solver; and+  /evidence terms/ witness those solutions.  An /evidence variable/+  (or EvId) has a type that is a PredType.++* Generally speaking, the /type/ of a predicate determines its /value/;+  that is, predicates are singleton types.  The big exception is implicit+  parameters.  See Note [Type determines value]++* In a FunTy { ft_af = af }, where af = FTF_C_T or FTF_C_C,+  the argument type is always a Predicate type.+-}+ -- | A predicate in the solver. The solver tries to prove Wanted predicates -- from Given ones. data Pred@@ -75,43 +142,136 @@   --     as ClassPred, as if we had a tuple class with two superclasses   --        class (c1, c2) => CTuple2 c1 c2 -classifyPredType :: PredType -> Pred-classifyPredType ev_ty = case splitTyConApp_maybe ev_ty of-    Just (tc, [_, _, ty1, ty2])-      | tc `hasKey` eqReprPrimTyConKey -> EqPred ReprEq ty1 ty2-      | tc `hasKey` eqPrimTyConKey     -> EqPred NomEq  ty1 ty2+classifyPredType :: HasDebugCallStack => PredType -> Pred+-- Precondition: the argument is a predicate type, with kind (CONSTRAINT _)+classifyPredType ev_ty+  = assertPpr (isPredTy ev_ty) (ppr ev_ty) $+    case splitTyConApp_maybe ev_ty of+      Just (tc, [_, _, ty1, ty2])+        | tc `hasKey` eqReprPrimTyConKey -> EqPred ReprEq ty1 ty2+        | tc `hasKey` eqPrimTyConKey     -> EqPred NomEq  ty1 ty2 -    Just (tc, tys)-      | Just clas <- tyConClass_maybe tc-      -> ClassPred clas tys+      Just (tc, tys)+        | Just clas <- tyConClass_maybe tc+        -> ClassPred clas tys -    _ | (tvs, rho) <- splitForAllTyCoVars ev_ty-      , (theta, pred) <- splitFunTys rho-      , not (null tvs && null theta)-      -> ForAllPred tvs (map scaledThing theta) pred+      _ | (tvs, rho) <- splitForAllTyCoVars ev_ty+        , (theta, pred) <- splitFunTys rho+        , not (null tvs && null theta)+        -> ForAllPred tvs (map scaledThing theta) pred -      | otherwise-      -> IrredPred ev_ty+        | otherwise+        -> IrredPred ev_ty --- --------------------- Dictionary types ---------------------------------+isSimplePredTy :: HasDebugCallStack => Type -> Bool+-- Return True for (t1 ~# t2) regardless of role, and (C tys)+-- /Not/ true of quantified-predicate type like (forall a. Eq a => Eq [a])+-- Precondition: expects a type that classifies values (i.e. not a type constructor)+-- See Note [Types for coercions, predicates, and evidence]+isSimplePredTy ty+  = case tyConAppTyCon_maybe ty of+       Nothing -> False+       Just tc -> isClassTyCon tc ||+                  tc `hasKey` eqPrimTyConKey ||+                  tc `hasKey` eqReprPrimTyConKey +isPredTy :: Type -> Bool+-- True of all types of kind (CONSTRAINT r) for some `r`+-- See Note [Types for coercions, predicates, and evidence]+--+-- In particular it is True of+--    - the constraints handled by the constraint solver,+--      including quantified constraints+--    - dictionary functions (forall a. Eq a => Eq [a])+isPredTy ty = case typeTypeOrConstraint ty of+                        TypeLike       -> False+                        ConstraintLike -> True++typeDeterminesValue :: PredType -> Bool+-- ^ Is the type *guaranteed* to determine the value?+-- Might say No even if the type does determine the value.+-- See Note [Type determines value]+typeDeterminesValue ty = isDictTy ty && not (couldBeIPLike ty)+++{-+Note [Evidence for quantified constraints]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+The superclass mechanism in GHC.Tc.Solver.Dict.makeSuperClasses risks+taking a quantified constraint like+   (forall a. C a => a ~ b)+and generate superclass evidence+   (forall a. C a => a ~# b)++This is a funny thing: neither isPredTy nor isCoVarType are true+of it.  So we are careful not to generate it in the first place:+see Note [Equality superclasses in quantified constraints]+in GHC.Tc.Solver.Dict.+-}++-- --------------------- Equality predicates ---------------------------------++-- | Does this type classify a core (unlifted) Coercion?+-- At either role nominal or representational+--    (t1 ~# t2) or (t1 ~R# t2)+-- See Note [Types for coercions, predicates, and evidence] in "GHC.Core.TyCo.Rep"+isEqPred :: PredType -> Bool+-- True of (s ~# t) (s ~R# t)+-- NB: but NOT true of (s ~ t) or (s ~~ t) or (Coecible s t)+isEqPred ty+  | Just tc <- tyConAppTyCon_maybe ty+  = tc `hasKey` eqPrimTyConKey || tc `hasKey` eqReprPrimTyConKey+  | otherwise+  = False++isCoVarType :: Type -> Bool+-- Just a synonym for isEqPred+isCoVarType = isEqPred++isReprEqPred :: PredType -> Bool+-- True of (s ~R# t)+isReprEqPred ty+  | Just tc <- tyConAppTyCon_maybe ty+  = tc `hasKey` eqReprPrimTyConKey+  | otherwise+  = False++-- --------------------- Class predicates ---------------------------------+ mkClassPred :: Class -> [Type] -> PredType mkClassPred clas tys = mkTyConApp (classTyCon clas) tys +isClassPred :: PredType -> Bool+isClassPred ty = case tyConAppTyCon_maybe ty of+    Just tc -> isClassTyCon tc+    _       -> False+ isDictTy :: Type -> Bool--- True of dictionaries (Eq a) and---         dictionary functions (forall a. Eq a => Eq [a])--- See Note [Type determines value]--- See #24370 (and the isDictId call in GHC.HsToCore.Binds.decomposeRuleLhs)---     for why it's important to catch dictionary bindings-isDictTy ty = isClassPred pred-  where-    (_, pred) = splitInvisPiTys ty+isDictTy = isClassPred -typeDeterminesValue :: Type -> Bool--- See Note [Type determines value]-typeDeterminesValue ty = isDictTy ty && not (isIPLikePred ty)+isEqClassPred :: PredType -> Bool+isEqClassPred ty  -- True of (s ~ t) and (s ~~ t)+                  -- ToDo: should we check saturation?+  | Just tc <- tyConAppTyCon_maybe ty+  , Just cls <- tyConClass_maybe tc+  = isEqualityClass cls+  | otherwise+  = False +isEqualityClass :: Class -> Bool+-- True of (~), (~~), and Coercible+-- These all have a single primitive-equality superclass, either (~N# or ~R#)+isEqualityClass cls+  = cls `hasKey` heqTyConKey+    || cls `hasKey` eqTyConKey+    || cls `hasKey` coercibleTyConKey++isCTupleClass :: Class -> Bool+isCTupleClass cls = isTupleTyCon (classTyCon cls)++isUnaryClass :: Class -> Bool+isUnaryClass cls = isUnaryClassTyCon (classTyCon cls)+ getClassPredTys :: HasDebugCallStack => PredType -> (Class, [Type]) getClassPredTys ty = case getClassPredTys_maybe ty of         Just (clas, tys) -> (clas, tys)@@ -153,6 +313,10 @@ purposes of specialisation.  Note that we still want to specialise functions with implicit params if they have *other* dicts which are class params; see #17930.++It's also not always possible to infer that a type determines the value+if type families are in play. See #19747 for one such example.+ -}  -- --------------------- Equality predicates ---------------------------------@@ -170,6 +334,37 @@ eqRelRole NomEq  = Nominal eqRelRole ReprEq = Representational +-- | Creates a primitive nominal type equality predicate.+--      t1 ~# t2+-- Invariant: the types are not Coercions+mkNomEqPred :: Type -> Type -> Type+mkNomEqPred ty1 ty2+  = mkTyConApp eqPrimTyCon [k1, k2, ty1, ty2]+  where+    k1 = typeKind ty1+    k2 = typeKind ty2++-- | Creates a primitive representational type equality predicate.+--      t1 ~R# t2+-- Invariant: the types are not Coercions+mkReprEqPred :: Type -> Type -> Type+mkReprEqPred ty1  ty2+  = mkTyConApp eqReprPrimTyCon [k1, k2, ty1, ty2]+  where+    k1 = typeKind ty1+    k2 = typeKind ty2++-- | Makes a lifted equality predicate at the given role+mkEqPred :: EqRel -> Type -> Type -> PredType+mkEqPred NomEq  = mkNomEqPred+mkEqPred ReprEq = mkReprEqPred++-- | Makes a lifted equality predicate at the given role+mkEqPredRole :: Role -> Type -> Type -> PredType+mkEqPredRole Nominal          = mkNomEqPred+mkEqPredRole Representational = mkReprEqPred+mkEqPredRole Phantom          = panic "mkEqPred phantom"+ getEqPredTys :: PredType -> (Type, Type) getEqPredTys ty   = case splitTyConApp_maybe ty of@@ -195,90 +390,19 @@ -- Returns NomEq for dictionary predicates, etc predTypeEqRel :: PredType -> EqRel predTypeEqRel ty-  | isReprEqPrimPred ty = ReprEq-  | otherwise           = NomEq--{--------------------------------------------Predicates on PredType---------------------------------------------}--{--Note [Evidence for quantified constraints]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-The superclass mechanism in GHC.Tc.Solver.Dict.makeSuperClasses risks-taking a quantified constraint like-   (forall a. C a => a ~ b)-and generate superclass evidence-   (forall a. C a => a ~# b)--This is a funny thing: neither isPredTy nor isCoVarType are true-of it.  So we are careful not to generate it in the first place:-see Note [Equality superclasses in quantified constraints]-in GHC.Tc.Solver.Dict.--}---- | Does this type classify a core (unlifted) Coercion?--- At either role nominal or representational---    (t1 ~# t2) or (t1 ~R# t2)--- See Note [Types for coercions, predicates, and evidence] in "GHC.Core.TyCo.Rep"-isCoVarType :: Type -> Bool-  -- ToDo: should we check saturation?-isCoVarType ty = isEqPrimPred ty--isEvVarType :: Type -> Bool--- True of (a) predicates, of kind Constraint, such as (Eq t), and (s ~ t)---         (b) coercion types, such as (s ~# t) or (s ~R# t)--- See Note [Types for coercions, predicates, and evidence] in GHC.Core.TyCo.Rep--- See Note [Evidence for quantified constraints]-isEvVarType ty = isCoVarType ty || isPredTy ty--isEqPrimPred :: PredType -> Bool--- True of (s ~# t) (s ~R# t)-isEqPrimPred ty-  | Just tc <- tyConAppTyCon_maybe ty-  = tc `hasKey` eqPrimTyConKey || tc `hasKey` eqReprPrimTyConKey-  | otherwise-  = False--isReprEqPrimPred :: PredType -> Bool-isReprEqPrimPred ty-  | Just tc <- tyConAppTyCon_maybe ty-  = tc `hasKey` eqReprPrimTyConKey-  | otherwise-  = False--isNomEqPred :: PredType -> Bool--- A nominal equality, primitive or not  (s ~# t), (s ~ t), or (s ~~ t)-isNomEqPred ty-  | Just tc <- tyConAppTyCon_maybe ty-  = tc `hasKey` eqPrimTyConKey || tc `hasKey` heqTyConKey || tc `hasKey` eqTyConKey-  | otherwise-  = False--isClassPred :: PredType -> Bool-isClassPred ty = case tyConAppTyCon_maybe ty of-    Just tc -> isClassTyCon tc-    _       -> False--isEqPred :: PredType -> Bool-isEqPred ty  -- True of (s ~ t) and (s ~~ t)-             -- ToDo: should we check saturation?-  | Just tc <- tyConAppTyCon_maybe ty-  , Just cls <- tyConClass_maybe tc-  = isEqualityClass cls-  | otherwise-  = False--isEqualityClass :: Class -> Bool--- True of (~), (~~), and Coercible--- These all have a single primitive-equality superclass, either (~N# or ~R#)-isEqualityClass cls-  = cls `hasKey` heqTyConKey-    || cls `hasKey` eqTyConKey-    || cls `hasKey` coercibleTyConKey+  | isReprEqPred ty = ReprEq+  | otherwise       = NomEq -isCTupleClass :: Class -> Bool-isCTupleClass cls = isTupleTyCon (classTyCon cls)+pprPredType :: PredType -> SDoc+-- Special case for (t1 ~# t2) and (t1 ~R# t2)+pprPredType pred+  = case classifyPredType pred of+      EqPred eq_rel t1 t2 -> sep [ ppr t1, ppr (getOccName eq_tc) <+> ppr t2 ]+         where+           eq_tc = case eq_rel of+                     NomEq  -> eqPrimTyCon+                     ReprEq -> eqReprPrimTyCon+      _ -> ppr pred  {- ********************************************************************* *                                                                      *@@ -286,6 +410,8 @@ *                                                                      * ********************************************************************* -} +-- --------------------- Nomal implicit-parameter predicates ---------------+ isIPTyCon :: TyCon -> Bool isIPTyCon tc = tc `hasKey` ipClassKey   -- Class and its corresponding TyCon have the same Unique@@ -303,6 +429,18 @@   | otherwise   = Nothing +-- | Take a type (IP sym ty), where IP is the built in IP class+-- and return (ip, MkIP, [sym,ty]), where+--    `ip` is the class-op for class IP+--    `MkIP` is the data constructor for class IP+decomposeIPPred :: Type -> (Id, [Type])+decomposeIPPred ty+  | Just (cls, tys) <- getClassPredTys_maybe ty+  , [ip_op] <- classMethods cls+  = assertPpr (isIPClass cls && isUnaryClass cls) (ppr ty) $+    (ip_op, tys)+  | otherwise = pprPanic "decomposeIP" (ppr ty)+ -- --------------------- ExceptionContext predicates --------------------------  -- | Is a 'PredType' an @ExceptionContext@ implicit parameter?@@ -357,44 +495,44 @@   | otherwise   = False --- --------------------- isIPLike and mentionsIP  --------------------------+-- --------------------- couldBeIPLike and mightMentionIP  -------------------------- --                 See Note [Local implicit parameters] -isIPLikePred :: Type -> Bool+couldBeIPLike :: Type -> Bool -- Is `pred`, or any of its superclasses, an implicit parameter? -- See Note [Local implicit parameters]-isIPLikePred pred =-  mentions_ip_pred initIPRecTc (const True) (const True) pred+couldBeIPLike pred+  = might_mention_ip1 initIPRecTc (const True) (const True) pred -mentionsIP :: (Type -> Bool) -- ^ predicate on the string-           -> (Type -> Bool) -- ^ predicate on the type-           -> Class-           -> [Type] -> Bool--- ^ @'mentionsIP' str_cond ty_cond cls tys@ returns @True@ if:+mightMentionIP :: (Type -> Bool) -- ^ predicate on the string+               -> (Type -> Bool) -- ^ predicate on the type+               -> Class+               -> [Type] -> Bool+-- ^ @'mightMentionIP' str_cond ty_cond cls tys@ returns @True@ if: -- --    - @cls tys@ is of the form @IP str ty@, where @str_cond str@ and @ty_cond ty@ --      are both @True@, --    - or any superclass of @cls tys@ has this property. -- -- See Note [Local implicit parameters]-mentionsIP = mentions_ip initIPRecTc+mightMentionIP = might_mention_ip initIPRecTc -mentions_ip :: RecTcChecker -> (Type -> Bool) -> (Type -> Bool) -> Class -> [Type] -> Bool-mentions_ip rec_clss str_cond ty_cond cls tys+might_mention_ip :: RecTcChecker -> (Type -> Bool) -> (Type -> Bool) -> Class -> [Type] -> Bool+might_mention_ip rec_clss str_cond ty_cond cls tys   | Just (str_ty, ty) <- isIPPred_maybe cls tys   = str_cond str_ty && ty_cond ty   | otherwise-  = or [ mentions_ip_pred rec_clss str_cond ty_cond (classMethodInstTy sc_sel_id tys)+  = or [ might_mention_ip1 rec_clss str_cond ty_cond (classMethodInstTy sc_sel_id tys)        | sc_sel_id <- classSCSelIds cls ]  -mentions_ip_pred :: RecTcChecker -> (Type -> Bool) -> (Type -> Bool) -> Type -> Bool-mentions_ip_pred rec_clss str_cond ty_cond ty+might_mention_ip1 :: RecTcChecker -> (Type -> Bool) -> (Type -> Bool) -> Type -> Bool+might_mention_ip1 rec_clss str_cond ty_cond ty   | Just (cls, tys) <- getClassPredTys_maybe ty   , let tc = classTyCon cls   , Just rec_clss' <- if isTupleTyCon tc then Just rec_clss                       else checkRecTc rec_clss tc-  = mentions_ip rec_clss' str_cond ty_cond cls tys+  = might_mention_ip rec_clss' str_cond ty_cond cls tys   | otherwise   = False -- Includes things like (D []) where D is           -- a Constraint-ranged family; #7785@@ -407,7 +545,7 @@ See also wrinkle (SIP1) in Note [Shadowing of implicit parameters] in GHC.Tc.Solver.Dict. -The function isIPLikePred tells if this predicate, or any of its+The function couldBeIPLike tells if this predicate, or any of its superclasses, is an implicit parameter.  Why are implicit parameters special?  Unlike normal classes, we can@@ -415,7 +553,7 @@    let ?x = True in ... So in various places we must be careful not to assume that any value of the right type will do; we must carefully look for the innermost binding.-So isIPLikePred checks whether this is an implicit parameter, or has+So couldBeIPLike checks whether this is an implicit parameter, or has a superclass that is an implicit parameter.  Several wrinkles@@ -456,16 +594,16 @@   think nothing does. * I'm a little concerned about type variables; such a variable might   be instantiated to an implicit parameter.  I don't think this-  matters in the cases for which isIPLikePred is used, and it's pretty+  matters in the cases for which couldBeIPLike is used, and it's pretty   obscure anyway. * The superclass hunt stops when it encounters the same class again,   but in principle we could have the same class, differently instantiated,   and the second time it could have an implicit parameter I'm going to treat these as problems for another day. They are all exotic. -Note [Using typesAreApart when calling mentionsIP]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-We call 'mentionsIP' in two situations:+Note [Using typesAreApart when calling mightMentionIP]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+We call 'mightMentionIP' in two situations:    (1) to check that a predicate does not contain any implicit parameters       IP str ty, for a fixed literal str and any type ty,@@ -500,8 +638,175 @@ *                                                                      * ********************************************************************* -} -isEvVar :: Var -> Bool-isEvVar var = isEvVarType (varType var)+isEvId :: Var -> Bool+isEvId var = isPredTy (varType var)  isDictId :: Id -> Bool isDictId id = isDictTy (varType id)+++{- *********************************************************************+*                                                                      *+                 scopedSort++       This function lives here becuase it uses isEvId+*                                                                      *+********************************************************************* -}++{- Note [ScopedSort]+~~~~~~~~~~~~~~~~~~~~+Consider++  foo :: Proxy a -> Proxy (b :: k) -> Proxy (a :: k2) -> ()++This function type is implicitly generalised over [a, b, k, k2]. These+variables will be Specified; that is, they will be available for visible+type application. This is because they are written in the type signature+by the user.++However, we must ask: what order will they appear in? In cases without+dependency, this is easy: we just use the lexical left-to-right ordering+of first occurrence. With dependency, we cannot get off the hook so+easily.++We thus state:++ * These variables appear in the order as given by ScopedSort, where+   the input to ScopedSort is the left-to-right order of first occurrence.++Note that this applies only to *implicit* quantification, without a+`forall`. If the user writes a `forall`, then we just use the order given.++ScopedSort is defined thusly (as proposed in #15743):+  * Work left-to-right through the input list, with a cursor.+  * If variable v at the cursor is depended on by any earlier variable w,+    move v immediately before the leftmost such w.++INVARIANT: The prefix of variables before the cursor form a valid telescope.++Note that ScopedSort makes sense only after type inference is done and all+types/kinds are fully settled and zonked.++-}++-- | Do a topological sort on a list of tyvars,+--   so that binders occur before occurrences+-- E.g. given  @[ a::k, k::Type, b::k ]@+-- it'll return a well-scoped list @[ k::Type, a::k, b::k ]@.+--+-- This is a deterministic sorting operation+-- (that is, doesn't depend on Uniques).+--+-- It is also meant to be stable: that is, variables should not+-- be reordered unnecessarily. This is specified in Note [ScopedSort]+-- See also Note [Ordering of implicit variables] in "GHC.Rename.HsType"++scopedSort :: [Var] -> [Var]+scopedSort = go [] []+  where+    go :: [Var] -- already sorted, in reverse order+       -> [TyCoVarSet] -- each set contains all the variables which must be placed+                       -- before the tv corresponding to the set; they are accumulations+                       -- of the fvs in the sorted Var's types++                       -- This list is in 1-to-1 correspondence with the sorted Vars+                       -- INVARIANT:+                       --   all (\tl -> all (`subVarSet` head tl) (tail tl)) (tails fv_list)+                       -- That is, each set in the list is a superset of all later sets.++       -> [Var] -- yet to be sorted+       -> [Var]+    go acc _fv_list [] = reverse acc+    go acc  fv_list (tv:tvs)+      = go acc' fv_list' tvs+      where+        (acc', fv_list') = insert tv acc fv_list++    insert :: Var           -- var to insert+           -> [Var]         -- sorted list, in reverse order+           -> [TyCoVarSet]  -- list of fvs, as above+           -> ([Var], [TyCoVarSet])   -- augmented lists+    -- Generally we put the new Var at the front of the accumulating list+    -- (leading to a stable sort) unless there is are reason to put it later.+    insert v []     []         = ([v], [tyCoVarsOfType (varType v)])+    insert v (a:as) (fvs:fvss)+      | (isTyVar v && isId a) ||          -- TyVars precede Ids+        (isEvId v && isId a && not (isEvId a)) || -- DictIds precede non-DictIds+        (v `elemVarSet` fvs)+          -- (a) put Ids after TyVars, and (b) respect dependencies+      , (as', fvss') <- insert v as fvss+      = (a:as', fvs `unionVarSet` fv_v : fvss')++      | otherwise  -- Put `v` at the front+      = (v:a:as, fvs `unionVarSet` fv_v : fvs : fvss)+      where+        fv_v = tyCoVarsOfType (varType v)++       -- lists not in correspondence+    insert _ _ _ = panic "scopedSort"++-- | Get the free vars of a type in scoped order+tyCoVarsOfTypeWellScoped :: Type -> [TyVar]+tyCoVarsOfTypeWellScoped = scopedSort . tyCoVarsOfTypeList++-- | Get the free vars of types in scoped order+tyCoVarsOfTypesWellScoped :: [Type] -> [TyVar]+tyCoVarsOfTypesWellScoped = scopedSort . tyCoVarsOfTypesList+++{- *********************************************************************+*                                                                      *+*                   Equality left-hand sides+*                                                                      *+********************************************************************* -}++-- | A 'CanEqLHS' is a type that can appear on the left of a canonical+-- equality: a type variable or /exactly-saturated/ type family application.+data CanEqLHS+  = TyVarLHS TyVar+  | TyFamLHS TyCon  -- ^ TyCon of the family+             [Type]   -- ^ Arguments, /exactly saturating/ the family++instance Outputable CanEqLHS where+  ppr (TyVarLHS tv)              = ppr tv+  ppr (TyFamLHS fam_tc fam_args) = ppr (mkTyConApp fam_tc fam_args)++-----------------------------------+-- | Is a type a canonical LHS? That is, is it a tyvar or an exactly-saturated+-- type family application?+-- Does not look through type synonyms.+canEqLHS_maybe :: Type -> Maybe CanEqLHS+canEqLHS_maybe xi+  | Just tv <- getTyVar_maybe xi+  = Just $ TyVarLHS tv++  | otherwise+  = canTyFamEqLHS_maybe xi++canTyFamEqLHS_maybe :: Type -> Maybe CanEqLHS+canTyFamEqLHS_maybe xi+  | Just (tc, args) <- tcSplitTyConApp_maybe xi+  , isTypeFamilyTyCon tc+  , args `lengthIs` tyConArity tc+  = Just $ TyFamLHS tc args++  | otherwise+  = Nothing++-- | Convert a 'CanEqLHS' back into a 'Type'+canEqLHSType :: CanEqLHS -> Type+canEqLHSType (TyVarLHS tv) = mkTyVarTy tv+canEqLHSType (TyFamLHS fam_tc fam_args) = mkTyConApp fam_tc fam_args++-- | Retrieve the kind of a 'CanEqLHS'+canEqLHSKind :: CanEqLHS -> Kind+canEqLHSKind (TyVarLHS tv) = tyVarKind tv+canEqLHSKind (TyFamLHS fam_tc fam_args) = piResultTys (tyConKind fam_tc) fam_args++-- | Are two 'CanEqLHS's equal?+eqCanEqLHS :: CanEqLHS -> CanEqLHS -> Bool+eqCanEqLHS (TyVarLHS tv1) (TyVarLHS tv2) = tv1 == tv2+eqCanEqLHS (TyFamLHS fam_tc1 fam_args1) (TyFamLHS fam_tc2 fam_args2)+  = tcEqTyConApps fam_tc1 fam_args1 fam_tc2 fam_args2+eqCanEqLHS _ _ = False+
GHC/Core/Rules.hs view
@@ -9,7 +9,7 @@ -- The 'CoreRule' datatype itself is declared elsewhere. module GHC.Core.Rules (         -- ** Looking up rules-        lookupRule, matchExprs,+        lookupRule, matchExprs, ruleLhsIsMoreSpecific,          -- ** RuleBase, RuleEnv         RuleBase, RuleEnv(..), mkRuleEnv, emptyRuleEnv,@@ -30,7 +30,8 @@         rulesOfBinds, getRules, pprRulesForUser,          -- * Making rules-        mkRule, mkSpecRule, roughTopNames+        mkRule, mkSpecRule, roughTopNames,+        ruleIsOrphan      ) where @@ -484,6 +485,10 @@ ruleIsVisible vis_orphs Rule { ru_orphan = orph, ru_origin = origin }     = notOrphan orph || origin `elemModuleSet` vis_orphs +ruleIsOrphan :: CoreRule -> Bool+ruleIsOrphan (BuiltinRule {})            = False+ruleIsOrphan (Rule { ru_orphan = orph }) = isOrphan orph+ {- Note [Where rules are found] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The rules for an Id come from two places:@@ -538,7 +543,8 @@ -- supplied rules to this instance of an application in a given -- context, returning the rule applied and the resulting expression if -- successful.-lookupRule :: RuleOpts -> InScopeEnv+lookupRule :: HasDebugCallStack+           => RuleOpts -> InScopeEnv            -> (Activation -> Bool)      -- When rule is active            -> Id -- Function head            -> [CoreExpr] -- Args@@ -568,7 +574,7 @@       = go ((r,mkTicks ticks e):ms) rs       | otherwise       = -- pprTrace "match failed" (ppr r $$ ppr args $$-        --   ppr [ (arg_id, unfoldingTemplate unf)+        --   ppr [ (arg_id, maybeUnfoldingTemplate unf)         --       | Var arg_id <- args         --       , let unf = idUnfolding arg_id         --       , isCheapUnfolding unf] )@@ -582,8 +588,8 @@  findBest _        _      (rule,ans)   [] = (rule,ans) findBest in_scope target (rule1,ans1) ((rule2,ans2):prs)-  | isMoreSpecific in_scope rule1 rule2 = findBest in_scope target (rule1,ans1) prs-  | isMoreSpecific in_scope rule2 rule1 = findBest in_scope target (rule2,ans2) prs+  | ruleIsMoreSpecific in_scope rule1 rule2 = findBest in_scope target (rule1,ans1) prs+  | ruleIsMoreSpecific in_scope rule2 rule1 = findBest in_scope target (rule2,ans2) prs   | debugIsOn = let pp_rule rule                       = ifPprDebug (ppr rule)                                    (doubleQuotes (ftext (ruleName rule)))@@ -598,15 +604,25 @@   where     (fn,args) = target -isMoreSpecific :: InScopeSet -> CoreRule -> CoreRule -> Bool--- The call (rule1 `isMoreSpecific` rule2)+ruleIsMoreSpecific :: InScopeSet -> CoreRule -> CoreRule -> Bool+-- The call (rule1 `ruleIsMoreSpecific` rule2) -- sees if rule2 can be instantiated to look like rule1--- See Note [isMoreSpecific]-isMoreSpecific _        (BuiltinRule {}) _                = False-isMoreSpecific _        (Rule {})        (BuiltinRule {}) = True-isMoreSpecific in_scope (Rule { ru_bndrs = bndrs1, ru_args = args1 })-                        (Rule { ru_bndrs = bndrs2, ru_args = args2 })-  = isJust (matchExprs in_scope_env bndrs2 args2 args1)+-- See Note [ruleIsMoreSpecific]+ruleIsMoreSpecific in_scope rule1 rule2+  = case rule1 of+       BuiltinRule {} -> False+       Rule { ru_bndrs = bndrs1, ru_args = args1 }+                      -> ruleLhsIsMoreSpecific in_scope bndrs1 args1 rule2++ruleLhsIsMoreSpecific :: InScopeSet+                      -> [Var] -> [CoreExpr]  -- LHS of a possible new rule+                      -> CoreRule             -- An existing rule+                      -> Bool                 -- New one is more specific+ruleLhsIsMoreSpecific in_scope bndrs1 args1 rule2+  = case rule2 of+       BuiltinRule {} -> True+       Rule { ru_bndrs = bndrs2, ru_args = args2 }+                      -> isJust (matchExprs in_scope_env bndrs2 args2 args1)   where    full_in_scope = in_scope `extendInScopeSetList` bndrs1    in_scope_env  = ISE full_in_scope noUnfoldingFun@@ -615,9 +631,9 @@ noBlackList :: Activation -> Bool noBlackList _ = False           -- Nothing is black listed -{- Note [isMoreSpecific]+{- Note [ruleIsMoreSpecific] ~~~~~~~~~~~~~~~~~~~~~~~~-The call (rule1 `isMoreSpecific` rule2)+The call (rule1 `ruleIsMoreSpecific` rule2) sees if rule2 can be instantiated to look like rule1.  Wrinkle:@@ -660,7 +676,8 @@ -}  -------------------------------------matchRule :: RuleOpts -> InScopeEnv -> (Activation -> Bool)+matchRule :: HasDebugCallStack+          => RuleOpts -> InScopeEnv -> (Activation -> Bool)           -> Id -> [CoreExpr] -> [Maybe Name]           -> CoreRule -> Maybe CoreExpr @@ -705,7 +722,8 @@   ----------------------------------------matchN  :: InScopeEnv+matchN  :: HasDebugCallStack+        => InScopeEnv         -> RuleName -> [Var] -> [CoreExpr]         -> [CoreExpr] -> CoreExpr           -- ^ Target; can have more elements than the template         -> Maybe CoreExpr@@ -724,7 +742,8 @@        ; return (bind_wrapper $                  mkLams tmpl_vars rhs `mkApps` matched_es) } -matchExprs :: InScopeEnv -> [Var] -> [CoreExpr] -> [CoreExpr]+matchExprs :: HasDebugCallStack+           => InScopeEnv -> [Var] -> [CoreExpr] -> [CoreExpr]            -> Maybe (BindWrapper, [CoreExpr])  -- 1-1 with the [Var] matchExprs (ISE in_scope id_unf) tmpl_vars tmpl_es target_es   = do  { rule_subst <- match_exprs init_menv emptyRuleSubst tmpl_es target_es@@ -780,7 +799,8 @@               , text "Actual args:" <+> ppr target_es ]  -----------------------match_exprs :: RuleMatchEnv -> RuleSubst+match_exprs :: HasDebugCallStack+            => RuleMatchEnv -> RuleSubst             -> [CoreExpr]       -- Templates             -> [CoreExpr]       -- Targets             -> Maybe RuleSubst@@ -820,7 +840,7 @@    The rule looks like     forall (a::*) (d::Eq Char) (x :: Foo a Char).-         f (Foo a Char) d x = True+         f @(Foo a Char) d x = True    Matching the rule won't bind 'a', and legitimately so.  We fudge by   pretending that 'a' is bound to (Any :: *).@@ -996,17 +1016,17 @@ variable.  And SpecConstr no longer does so: see Note [SpecConstr and casts] in SpecConstr. -It is, however, OK for a cast to appear in a template.  For example-    newtype N a = MkN (a,a)    -- Axiom ax:N a :: (a,a) ~R N a-    f :: N a -> bah-    RULE forall b x:b y:b. f @b ((x,y) |> (axN @b)) = ...--When matching we can just move these casts to the other side:-    match (tmpl |> co) tgt  -->   match tmpl (tgt |> sym co)-See matchTemplateCast.- Wrinkles: +(CT0) It is, however, OK for a cast to appear in a template provided the cast mentions+  none of the template variables.  For example+      newtype N a = MkN (a,a)    -- Axiom ax:N a :: (a,a) ~R N a+      f :: N a -> bah+      RULE forall b x:b y:b. f @b ((x,y) |> (axN @b)) = ...+  When matching we can just move these casts to the other side:+      match (tmpl |> co) tgt  -->   match tmpl (tgt |> sym co)+  See matchTemplateCast.+ (CT1) We need to be careful about scoping, and to match left-to-right, so that we   know the substitution [a :-> b] before we meet (co :: (a,a) ~R N a), and so we   can apply that substitition@@ -1041,7 +1061,8 @@ -}  -----------------------match :: RuleMatchEnv+match :: HasDebugCallStack+      => RuleMatchEnv       -> RuleSubst              -- Substitution applies to template only       -> CoreExpr               -- Template       -> CoreExpr               -- Target@@ -1277,7 +1298,7 @@              f (\(MkT @b (d::Num b) (x::b)) -> h @b d x) = ...      where the HOP is (h @b d x). In principle this might be possible, but      it seems fragile; e.g. we would still need to insist that the (invisible)-     @b was a type variable.  And since `h` gets a polymoprhic type, that+     @b was a type variable.  And since `h` gets a polymorphic type, that      type would have to be declared by the programmer.       Maybe one day.  But for now, we insist (in `arg_as_lcl_var`)that a HOP@@ -1491,11 +1512,12 @@     filterFV (`elemVarSet` rv_tmpls renv) $    -- Check that the coercion does not     tyCoFVsOfCo substed_co                     -- mention any of the template variables   = -- This is the good path-    -- See Note [Casts in the template]+    -- See Note [Casts in the template] wrinkle (CT0)     match renv subst e1 e2 (checkReflexiveMCo (mkTransMCoL mco (mkSymCo substed_co)))    | otherwise   = -- This is the Deeply Suspicious Path+    -- See Note [Casts in the template]     do { let co2 = case mco of                      MRefl   -> mkRepReflCo (exprType e2)                      MCo co2 -> co2@@ -1577,7 +1599,8 @@     not_captured fv = not (inRnEnvR rn_env fv)  -------------------------------------------match_var :: RuleMatchEnv+match_var :: HasDebugCallStack+          => RuleMatchEnv           -> RuleSubst           -> Var        -- Template           -> CoreExpr   -- Target@@ -1613,7 +1636,8 @@         -- template x, so we must rename first!  -------------------------------------------match_tmpl_var :: RuleMatchEnv+match_tmpl_var :: HasDebugCallStack+               => RuleMatchEnv                -> RuleSubst                -> Var                -- Template                -> CoreExpr           -- Target
GHC/Core/Rules/Config.hs view
@@ -5,9 +5,15 @@  -- | Rule options data RuleOpts = RuleOpts-   { roPlatform                :: !Platform -- ^ Target platform-   , roNumConstantFolding      :: !Bool     -- ^ Enable more advanced numeric constant folding-   , roExcessRationalPrecision :: !Bool     -- ^ Cut down precision of Rational values to that of Float/Double if disabled-   , roBignumRules             :: !Bool     -- ^ Enable rules for bignums+   { roPlatform                :: !Platform+     -- ^ Target platform+   , roNumConstantFolding      :: !Bool+     -- ^ Enable constant folding through nested expressions.+     --+     -- See Note [Constant folding through nested expressions] in GHC.Core.Opt.ConstantFold+   , roExcessRationalPrecision :: !Bool+     -- ^ Cut down precision of Rational values to that of Float/Double if disabled+   , roBignumRules             :: !Bool+     -- ^ Enable rules for bignums    } 
GHC/Core/SimpleOpt.hs view
@@ -8,7 +8,7 @@         SimpleOpts (..), defaultSimpleOpts,          -- ** Simple expression optimiser-        simpleOptPgm, simpleOptExpr, simpleOptExprWith,+        simpleOptPgm, simpleOptExpr, simpleOptExprNoInline, simpleOptExprWith,          -- ** Join points         joinPointBinding_maybe, joinPointBindings_maybe,@@ -89,6 +89,24 @@ expression.  In fact, the simple optimiser is a good example of this little dance in action; the full Simplifier is a lot more complicated. +Note [The InScopeSet for simpleOptExpr]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+Care must be taken to remove unfoldings from `Var`s collected by exprFreeVars+before using them to construct an in-scope set hence `zapIdUnfolding` in `init_subst`.+Consider calling `simpleOptExpr` on an expression like++```+ case x of (a,b) -> (x,a)+```++* One of those two occurrences of x has an unfolding (the one in (x,a), with+unfolding x = (a,b)) and the other does not. (Inside a case GHC adds+unfolding-info to the scrutinee's Id.)+* But exprFreeVars just builds a set, so it's a bit random which occurrence is collected.+* Then simpleOptExpr replaces each occurrence of x with the one in the in-scope set.+* Bad bad bad: then the x in  case x of ... may be replaced with a version that has an unfolding.++See ticket #25790 -}  -- | Simple optimiser options@@ -96,6 +114,8 @@    { so_uf_opts :: !UnfoldingOpts   -- ^ Unfolding options    , so_co_opts :: !OptCoercionOpts -- ^ Coercion optimiser options    , so_eta_red :: !Bool            -- ^ Eta reduction on?+   , so_inline :: !Bool             -- ^ False <=> do no inlining whatsoever,+                                    --    even for trivial or used-once things    }  -- | Default options for the Simple optimiser.@@ -104,6 +124,7 @@    { so_uf_opts = defaultUnfoldingOpts    , so_co_opts = OptCoercionOpts { optCoercionEnabled = False }    , so_eta_red = False+   , so_inline  = True    }  simpleOptExpr :: HasDebugCallStack => SimpleOpts -> CoreExpr -> CoreExpr@@ -135,17 +156,23 @@   = -- pprTrace "simpleOptExpr" (ppr init_subst $$ ppr expr)     simpleOptExprWith opts init_subst expr   where-    init_subst = mkEmptySubst (mkInScopeSet (exprFreeVars expr))-        -- It's potentially important to make a proper in-scope set-        -- Consider  let x = ..y.. in \y. ...x...-        -- Then we should remember to clone y before substituting-        -- for x.  It's very unlikely to occur, because we probably-        -- won't *be* substituting for x if it occurs inside a-        -- lambda.-        --+    init_subst = mkEmptySubst (mkInScopeSet (mapVarSet zapIdUnfolding (exprFreeVars expr)))+        -- zapIdUnfolding: see Note [The InScopeSet for simpleOptExpr]+         -- It's a bit painful to call exprFreeVars, because it makes         -- three passes instead of two (occ-anal, and go) +simpleOptExprNoInline :: HasDebugCallStack => SimpleOpts -> CoreExpr -> CoreExpr+-- A variant of simpleOptExpr, but without+-- occurrence analysis or inlining of any kind.+-- Result: we don't inline evidence bindings, which is useful for the specialiser+simpleOptExprNoInline opts expr+  = simple_opt_expr init_env expr+  where+    init_opts  = opts { so_inline = False }+    init_env   = (emptyEnv init_opts) { soe_subst = init_subst }+    init_subst = mkEmptySubst (mkInScopeSet (exprFreeVars expr))+ simpleOptExprWith :: HasDebugCallStack => SimpleOpts -> Subst -> InExpr -> OutExpr -- See Note [The simple optimiser] simpleOptExprWith opts subst expr@@ -219,7 +246,7 @@   = env { soe_inl = emptyVarEnv, soe_subst = zapSubst subst }  soeInScope :: SimpleOptEnv -> InScopeSet-soeInScope (SOE { soe_subst = subst }) = getSubstInScope subst+soeInScope (SOE { soe_subst = subst }) = substInScopeSet subst  soeSetInScope :: InScopeSet -> SimpleOptEnv -> SimpleOptEnv soeSetInScope in_scope env2@(SOE { soe_subst = subst2 })@@ -246,7 +273,7 @@   where     rec_ids      = soe_rec_ids env     subst        = soe_subst env-    in_scope     = getSubstInScope subst+    in_scope     = substInScopeSet subst     in_scope_env = ISE in_scope alwaysActiveUnfoldingFun      ---------------@@ -277,7 +304,7 @@           _       -> foldr wrapLet (simple_opt_expr env' rhs) mb_prs             where               (env', mb_prs) = mapAccumL (simple_out_bind NotTopLevel) env $-                               zipEqual "simpleOptExpr" bs es+                               zipEqual bs es           -- See Note [Getting the map/coerce RULE to work]       | isDeadBinder b@@ -339,10 +366,12 @@   = simple_app (soeSetInScope (soeInScope env) env') e as    | let unf = idUnfolding v-  , isCompulsoryUnfolding (idUnfolding v)+  , isCompulsoryUnfolding unf   , isAlwaysActive (idInlineActivation v)     -- See Note [Unfold compulsory unfoldings in RULE LHSs]-  = simple_app (soeZapSubst env) (unfoldingTemplate unf) as+  , Just rhs <- maybeUnfoldingTemplate unf+    -- Always succeeds if isCompulsoryUnfolding does+  = simple_app (soeZapSubst env) rhs as    | otherwise   , let out_fn = lookupIdSubst (soe_subst env) v@@ -453,7 +482,7 @@     -- (simple_bind_pair subst in_var out_rhs)     --   either extends subst with (in_var -> out_rhs)     --   or     returns Nothing-simple_bind_pair env@(SOE { soe_inl = inl_env, soe_subst = subst })+simple_bind_pair env@(SOE { soe_inl = inl_env, soe_subst = subst, soe_opts = opts })                  in_bndr mb_out_bndr clo@(rhs_env, in_rhs)                  top_level   | Type ty <- in_rhs        -- let a::* = TYPE ty in <body>@@ -479,7 +508,7 @@     stable_unf = isStableUnfolding (idUnfolding in_bndr)     active     = isAlwaysActive (idInlineActivation in_bndr)     occ        = idOccInfo in_bndr-    in_scope   = getSubstInScope subst+    in_scope   = substInScopeSet subst      out_rhs | JoinPoint join_arity <- idJoinPointHood in_bndr             = simple_join_rhs join_arity@@ -495,6 +524,7 @@      pre_inline_unconditionally :: Bool     pre_inline_unconditionally+       | not (so_inline opts)     = False    -- Not if so_inline is False        | isExportedId in_bndr     = False        | stable_unf               = False        | not active               = False    -- Note [Inline prag in simplOpt]@@ -546,13 +576,14 @@                      -> InId -> Maybe OutId -> OutExpr                      -> OccInfo -> Bool -> Bool -> TopLevelFlag                      -> (SimpleOptEnv, Maybe (OutVar, OutExpr))-simple_out_bind_pair env in_bndr mb_out_bndr out_rhs+simple_out_bind_pair env@(SOE { soe_subst = subst, soe_opts = opts })+                     in_bndr mb_out_bndr out_rhs                      occ_info active stable_unf top_level   | assertPpr (isNonCoVarId in_bndr) (ppr in_bndr)     -- Type and coercion bindings are caught earlier     -- See Note [Core type and coercion invariant]     post_inline_unconditionally-  = ( env' { soe_subst = extendIdSubst (soe_subst env) in_bndr out_rhs }+  = ( env' { soe_subst = extendIdSubst subst in_bndr out_rhs }     , Nothing)    | otherwise@@ -565,6 +596,7 @@      post_inline_unconditionally :: Bool     post_inline_unconditionally+       | not (so_inline opts)  = False -- Not if so_inline is False        | isExportedId in_bndr  = False -- Note [Exported Ids and trivial RHSs]        | stable_unf            = False -- Note [Stable unfoldings and postInlineUnconditionally]        | not active            = False --     in GHC.Core.Opt.Simplify.Utils@@ -837,7 +869,7 @@ (MC1) We must compulsorily unfold MkAge to a cast.       See Note [Compulsory newtype unfolding] in GHC.Types.Id.Make -(MC2) We must compulsorily unfolding coerce on the rule LHS, yielding+(MC2) We must compulsorily unfold coerce on the rule LHS, yielding         forall a b (dict :: Coercible * a b).           map @a @b (\(x :: a) -> case dict of             MkCoercible (co :: a ~R# b) -> x |> co) = ...@@ -854,7 +886,6 @@   Unfortunately, this still abstracts over a Coercible dictionary. We really   want it to abstract over the ~R# evidence. So, we have Desugar.unfold_coerce,   which transforms the above to-  Desugar)      forall a b (co :: a ~R# b).       let dict = MkCoercible @* @a @b co in@@ -879,7 +910,7 @@  (MC4) The map/coerce rule is the only compelling reason for having a RULE that   quantifies over a coercion variable, something that is otherwise Very Deeply-  Suspicous.  See Note [Casts in the template] in GHC.Core.Rules. Ugh!+  Suspicious.  See Note [Casts in the template] in GHC.Core.Rules. Ugh!  This is all a fair amount of special-purpose hackery, but it's for a good cause. And it won't hurt other RULES and such that it comes across.@@ -1284,11 +1315,8 @@        --       simplifier produces rhs[exp/a], changing semantics if exp is not ok-for-spec        -- Good: returning (Mk#, [x]) with a float of  case exp of x { DEFAULT -> [] }        --       simplifier produces case exp of a { DEFAULT -> exp[x/a] }-       = let arg' = subst_expr subst arg-             bndr = uniqAway (subst_in_scope subst) (mkWildValBinder ManyTy arg_type)-             float = FloatCase arg' bndr DEFAULT []-             subst' = subst_extend_in_scope subst bndr-         in go subst' (float:floats) fun (CC (Var bndr : args) mco)+       , (subst', float, bndr) <- case_bind subst arg arg_type+       = go subst' (float:floats) fun (CC (Var bndr : args) mco)        | otherwise        = go subst floats fun (CC (subst_expr subst arg : args) mco) @@ -1322,7 +1350,7 @@           scrut'           = subst_expr subst scrut      go (Right sub) floats (Var v) cont-       = go (Left (getSubstInScope sub))+       = go (Left (substInScopeSet sub))             floats             (lookupIdSubst sub v)             cont@@ -1331,15 +1359,16 @@          | Just con <- isDataConWorkId_maybe fun         , count isValArg args == idArity fun-        = succeedWith in_scope floats $-          pushCoDataCon con args mco+        , (in_scope', seq_floats, args') <- mkFieldSeqFloats in_scope con args+          -- mkFieldSeqFloats: See (SFC2) in Note [Strict fields in Core]+        = succeedWith in_scope' (seq_floats ++ floats) $+          pushCoDataCon con args' mco          -- Look through data constructor wrappers: they inline late (See Note         -- [Activation for data constructor wrappers]) but we want to do         -- case-of-known-constructor optimisation eagerly (see Note         -- [exprIsConApp_maybe on data constructors with wrappers]).-        | isDataConWrapId fun-        , let rhs = uf_tmpl (realIdUnfolding fun)+        | Just rhs <- dataConWrapUnfolding_maybe fun         = go (Left in_scope) floats rhs cont          -- Look through dictionary functions; see Note [Unfolding DFuns]@@ -1394,7 +1423,7 @@     -- The Left case is wildly dominant      subst_in_scope (Left in_scope) = in_scope-    subst_in_scope (Right s) = getSubstInScope s+    subst_in_scope (Right s) = substInScopeSet s      subst_extend_in_scope (Left in_scope) v = Left (in_scope `extendInScopeSet` v)     subst_extend_in_scope (Right s) v = Right (s `extendSubstInScope` v)@@ -1418,6 +1447,38 @@     extend (Left in_scope) v e = Right (extendSubst (mkEmptySubst in_scope) v e)     extend (Right s)       v e = Right (extendSubst s v e) +    case_bind :: Either InScopeSet Subst -> CoreExpr -> Type -> (Either InScopeSet Subst, FloatBind, Id)+    case_bind subst expr expr_ty = (subst', float, bndr)+      where+        bndr   = setCaseBndrEvald MarkedStrict $+                 uniqAway (subst_in_scope subst) $+                 mkWildValBinder ManyTy expr_ty+        subst' = subst_extend_in_scope subst bndr+        expr'  = subst_expr subst expr+        float  = FloatCase expr' bndr DEFAULT []++    mkFieldSeqFloats :: InScopeSet -> DataCon -> [CoreExpr] -> (InScopeSet, [FloatBind], [CoreExpr])+    -- See Note [Strict fields in Core] for what a field seq is and (SFC2) for+    -- why we insert them+    mkFieldSeqFloats in_scope dc args+      | isLazyDataConRep dc+      = (in_scope, [], args)+      | otherwise+      = (in_scope', floats', ty_args ++ val_args')+      where+        (ty_args, val_args) = splitAtList (dataConUnivAndExTyCoVars dc) args+        (in_scope', floats', val_args') = foldr do_one (in_scope, [], []) $ zipEqual str_marks val_args+        str_marks = dataConRepStrictness dc+        do_one (str, arg) (in_scope,floats,args)+          | NotMarkedStrict <- str   = no_seq+          | exprIsHNF arg            = no_seq+          | otherwise                = (in_scope', float:floats, Var bndr:args)+          where+            no_seq = (in_scope, floats, arg:args)+            (in_scope', float, bndr) =+               case case_bind (Left in_scope) arg (exprType arg) of+                 (Left in_scope', float, bndr) -> (in_scope', float, bndr)+                 (right, _, _) -> pprPanic "case_bind did not preserve Left" (ppr in_scope $$ ppr arg $$ ppr right)  -- See Note [exprIsConApp_maybe on literal strings] dealWithStringLiteral :: Var -> BS.ByteString -> MCoercion
GHC/Core/Subst.hs view
@@ -24,13 +24,14 @@         extendIdSubstWithClone,         extendSubst, extendSubstList, extendSubstWithVar,         extendSubstInScope, extendSubstInScopeList, extendSubstInScopeSet,-        isInScope, setInScope, getSubstInScope,+        isInScope, setInScope, substInScopeSet,         extendTvSubst, extendCvSubst,         delBndr, delBndrs, zapSubst,          -- ** Substituting and cloning binders         substBndr, substBndrs, substRecBndrs, substTyVarBndr, substCoVarBndr,         cloneBndr, cloneBndrs, cloneIdBndr, cloneIdBndrs, cloneRecIdBndrs,+        cloneBndrsM, cloneRecIdBndrsM,      ) where @@ -162,12 +163,14 @@ -- | Add a substitution appropriate to the thing being substituted --   (whether an expression, type, or coercion). See also --   'extendIdSubst', 'extendTvSubst', 'extendCvSubst'-extendSubst :: Subst -> Var -> CoreArg -> Subst+extendSubst :: HasDebugCallStack => Subst -> Var -> CoreArg -> Subst extendSubst subst var arg   = case arg of-      Type ty     -> assert (isTyVar var) $ extendTvSubst subst var ty-      Coercion co -> assert (isCoVar var) $ extendCvSubst subst var co-      _           -> assert (isId    var) $ extendIdSubst subst var arg+      Type ty     -> assertPpr (isTyVar var) doc $ extendTvSubst subst var ty+      Coercion co -> assertPpr (isCoVar var) doc $ extendCvSubst subst var co+      _           -> assertPpr (isId    var) doc $ extendIdSubst subst var arg+  where+   doc = ppr var <+> text ":=" <+> ppr arg  extendSubstWithVar :: Subst -> Var -> Var -> Subst extendSubstWithVar subst v1 v2@@ -238,8 +241,7 @@ -- their canonical representatives in the in-scope set substExprSC subst orig_expr   | isEmptySubst subst = orig_expr-  | otherwise          = -- pprTrace "enter subst-expr" (doc $$ ppr orig_expr) $-                         substExpr subst orig_expr+  | otherwise          = substExpr subst orig_expr  -- | substExpr applies a substitution to an entire 'CoreExpr'. Remember, -- you may only apply the substitution /once/:@@ -418,25 +420,32 @@ cloneIdBndrs subst us ids   = mapAccumL (clone_id subst) subst (ids `zip` uniqsFromSupply us) -cloneBndrs :: MonadUnique m => Subst -> [Var] -> m (Subst, [Var])+cloneBndrs :: Subst -> UniqSupply -> [Var] -> (Subst, [Var]) -- Works for all kinds of variables (typically case binders) -- not just Ids-cloneBndrs subst vs-  = do us <- getUniquesM-       pure $ mapAccumL (\subst (v, u) -> cloneBndr subst u v) subst (vs `zip` us)+cloneBndrs subst us vs+  = mapAccumL (\subst (v, u) -> cloneBndr subst u v) subst (vs `zip` uniqsFromSupply us) +cloneBndrsM :: MonadUnique m => Subst -> [Var] -> m (Subst, [Var])+-- Works for all kinds of variables (typically case binders)+-- not just Ids+cloneBndrsM subst vs = cloneBndrs subst `flip` vs <$> getUniqueSupplyM+ cloneBndr :: Subst -> Unique -> Var -> (Subst, Var) cloneBndr subst uniq v   | isTyVar v = cloneTyVarBndr subst v uniq   | otherwise = clone_id subst subst (v,uniq)  -- Works for coercion variables too  -- | Clone a mutually recursive group of 'Id's-cloneRecIdBndrs :: MonadUnique m => Subst -> [Id] -> m (Subst, [Id])-cloneRecIdBndrs subst ids-  = do us <- getUniquesM-       let (subst', ids') = mapAccumL (clone_id subst') subst (ids `zip` us)-       pure (subst', ids')+cloneRecIdBndrs :: Subst -> UniqSupply -> [Id] -> (Subst, [Id])+cloneRecIdBndrs subst us ids =+    let x@(subst', _) = mapAccumL (clone_id subst') subst (ids `zip` uniqsFromSupply us)+    in x +-- | Clone a mutually recursive group of 'Id's+cloneRecIdBndrsM :: MonadUnique m => Subst -> [Id] -> m (Subst, [Id])+cloneRecIdBndrsM subst ids = cloneRecIdBndrs subst `flip` ids <$> getUniqueSupplyM+ -- Just like substIdBndr, except that it always makes a new unique -- It is given the unique to use -- Discards non-Stable unfoldings@@ -482,7 +491,7 @@         -- in a Note in the id's type itself   where     old_ty = idType id-    old_w  = varMult id+    old_w  = idMult id  ------------------ -- | Substitute into some 'IdInfo' with regard to the supplied new 'Id'.@@ -590,13 +599,13 @@      = tyCoFVsOfCo fv_co (const True) emptyVarSet $! acc      | otherwise      , let fv_expr = lookupIdSubst subst fv-     = exprFVs fv_expr (const True) emptyVarSet $! acc+     = exprLocalFVs fv_expr (const True) emptyVarSet $! acc  ------------------ -- | Drop free vars from the breakpoint if they have a non-variable substitution. substTickish :: Subst -> CoreTickish -> CoreTickish-substTickish subst (Breakpoint ext n ids modl)-   = Breakpoint ext n (mapMaybe do_one ids) modl+substTickish subst (Breakpoint ext bid ids)+   = Breakpoint ext bid (mapMaybe do_one ids)  where     do_one = getIdFromTrivialExpr_maybe . lookupIdSubst subst 
GHC/Core/Tidy.hs view
@@ -16,12 +16,12 @@  import GHC.Core import GHC.Core.Type-+import GHC.Core.TyCo.Tidy import GHC.Core.Seq ( seqUnfolding )+ import GHC.Types.Id import GHC.Types.Id.Info import GHC.Types.Demand ( zapDmdEnvSig, isStrUsedDmd )-import GHC.Core.Coercion ( tidyCo ) import GHC.Types.Var import GHC.Types.Var.Env import GHC.Types.Unique (getUnique)@@ -30,6 +30,7 @@ import GHC.Types.Name.Set import GHC.Types.SrcLoc import GHC.Types.Tickish+ import GHC.Data.Maybe import GHC.Utils.Misc import Data.List (mapAccumL)@@ -234,8 +235,8 @@  ------------  Tickish  -------------- tidyTickish :: TidyEnv -> CoreTickish -> CoreTickish-tidyTickish env (Breakpoint ext ix ids modl)-  = Breakpoint ext ix (map (tidyVarOcc env) ids) modl+tidyTickish env (Breakpoint ext bid ids)+  = Breakpoint ext bid (map (tidyVarOcc env) ids) tidyTickish _   other_tickish       = other_tickish  ------------  Rules  --------------
GHC/Core/TyCo/Compare.hs view
@@ -12,7 +12,7 @@     eqVarBndrs,      pickyEqType, tcEqType, tcEqKind, tcEqTypeNoKindCheck,-    tcEqTyConApps,+    tcEqTyConApps, tcEqTyConAppArgs,     mayLookIdentical,      -- * Type comparison@@ -226,12 +226,16 @@ -- are different, just checks the common prefix of arguments. tcEqTyConApps :: TyCon -> [Type] -> TyCon -> [Type] -> Bool tcEqTyConApps tc1 args1 tc2 args2-  = tc1 == tc2 &&-    and (zipWith tcEqTypeNoKindCheck args1 args2)+  = tc1 == tc2 && tcEqTyConAppArgs args1 args2++tcEqTyConAppArgs :: [Type] -> [Type] -> Bool+-- Args do not have to have equal length;+-- we discard the excess of the longer one+tcEqTyConAppArgs args1 args2+  = and (zipWith tcEqTypeNoKindCheck args1 args2)     -- No kind check necessary: if both arguments are well typed, then     -- any difference in the kinds of later arguments would show up     -- as differences in earlier (dependent) arguments-  -- | Type equality on lists of types, looking through type synonyms eqTypes :: [Type] -> [Type] -> Bool
GHC/Core/TyCo/FVs.hs view
@@ -40,10 +40,6 @@         -- * Occurrence-check expansion         occCheckExpand, -        -- * Well-scoped free variables-        scopedSort, tyCoVarsOfTypeWellScoped,-        tyCoVarsOfTypesWellScoped,-         -- * Closing over kinds         closeOverKindsDSet, closeOverKindsList,         closeOverKinds,@@ -72,7 +68,6 @@ import GHC.Types.Var.Set import GHC.Types.Var.Env import GHC.Utils.Misc-import GHC.Utils.Panic import GHC.Data.Pair  import Data.Semigroup@@ -988,107 +983,6 @@ noFreeVarsOfCo co = not $ DM.getAny (f co)   where (_, _, f, _) = foldTyCo (afvFolder (const True)) emptyVarSet --{- *********************************************************************-*                                                                      *-                 scopedSort-*                                                                      *-********************************************************************* -}--{- Note [ScopedSort]-~~~~~~~~~~~~~~~~~~~~-Consider--  foo :: Proxy a -> Proxy (b :: k) -> Proxy (a :: k2) -> ()--This function type is implicitly generalised over [a, b, k, k2]. These-variables will be Specified; that is, they will be available for visible-type application. This is because they are written in the type signature-by the user.--However, we must ask: what order will they appear in? In cases without-dependency, this is easy: we just use the lexical left-to-right ordering-of first occurrence. With dependency, we cannot get off the hook so-easily.--We thus state:-- * These variables appear in the order as given by ScopedSort, where-   the input to ScopedSort is the left-to-right order of first occurrence.--Note that this applies only to *implicit* quantification, without a-`forall`. If the user writes a `forall`, then we just use the order given.--ScopedSort is defined thusly (as proposed in #15743):-  * Work left-to-right through the input list, with a cursor.-  * If variable v at the cursor is depended on by any earlier variable w,-    move v immediately before the leftmost such w.--INVARIANT: The prefix of variables before the cursor form a valid telescope.--Note that ScopedSort makes sense only after type inference is done and all-types/kinds are fully settled and zonked.---}---- | Do a topological sort on a list of tyvars,---   so that binders occur before occurrences--- E.g. given  [ a::k, k::*, b::k ]--- it'll return a well-scoped list [ k::*, a::k, b::k ]------ This is a deterministic sorting operation--- (that is, doesn't depend on Uniques).------ It is also meant to be stable: that is, variables should not--- be reordered unnecessarily. This is specified in Note [ScopedSort]--- See also Note [Ordering of implicit variables] in "GHC.Rename.HsType"--scopedSort :: [TyCoVar] -> [TyCoVar]-scopedSort = go [] []-  where-    go :: [TyCoVar] -- already sorted, in reverse order-       -> [TyCoVarSet] -- each set contains all the variables which must be placed-                       -- before the tv corresponding to the set; they are accumulations-                       -- of the fvs in the sorted tvs' kinds--                       -- This list is in 1-to-1 correspondence with the sorted tyvars-                       -- INVARIANT:-                       --   all (\tl -> all (`subVarSet` head tl) (tail tl)) (tails fv_list)-                       -- That is, each set in the list is a superset of all later sets.--       -> [TyCoVar] -- yet to be sorted-       -> [TyCoVar]-    go acc _fv_list [] = reverse acc-    go acc  fv_list (tv:tvs)-      = go acc' fv_list' tvs-      where-        (acc', fv_list') = insert tv acc fv_list--    insert :: TyCoVar       -- var to insert-           -> [TyCoVar]     -- sorted list, in reverse order-           -> [TyCoVarSet]  -- list of fvs, as above-           -> ([TyCoVar], [TyCoVarSet])   -- augmented lists-    insert tv []     []         = ([tv], [tyCoVarsOfType (tyVarKind tv)])-    insert tv (a:as) (fvs:fvss)-      | tv `elemVarSet` fvs-      , (as', fvss') <- insert tv as fvss-      = (a:as', fvs `unionVarSet` fv_tv : fvss')--      | otherwise-      = (tv:a:as, fvs `unionVarSet` fv_tv : fvs : fvss)-      where-        fv_tv = tyCoVarsOfType (tyVarKind tv)--       -- lists not in correspondence-    insert _ _ _ = panic "scopedSort"---- | Get the free vars of a type in scoped order-tyCoVarsOfTypeWellScoped :: Type -> [TyVar]-tyCoVarsOfTypeWellScoped = scopedSort . tyCoVarsOfTypeList---- | Get the free vars of types in scoped order-tyCoVarsOfTypesWellScoped :: [Type] -> [TyVar]-tyCoVarsOfTypesWellScoped = scopedSort . tyCoVarsOfTypesList  {- ************************************************************************
GHC/Core/TyCo/Ppr.hs view
@@ -41,8 +41,11 @@ import GHC.Core.TyCo.Tidy import GHC.Core.TyCo.FVs import GHC.Core.Class-import GHC.Types.Var+import GHC.Core.Predicate( scopedSort ) import GHC.Core.Multiplicity( pprArrowWithMultiplicity )++import GHC.Types.Var+ import GHC.Iface.Type  import GHC.Types.Var.Set@@ -321,7 +324,7 @@ pprDataConWithArgs dc = sep [forAllDoc, thetaDoc, ppr dc <+> argsDoc]   where     (_univ_tvs, _ex_tvs, _eq_spec, theta, arg_tys, _res_ty) = dataConFullSig dc-    user_bndrs = tyVarSpecToBinders $ dataConUserTyVarBinders dc+    user_bndrs = dataConUserTyVarBinders dc     forAllDoc  = pprUserForAll user_bndrs     thetaDoc   = pprThetaArrowTy theta     argsDoc    = hsep (fmap pprParendType (map scaledThing arg_tys))
GHC/Core/TyCo/Rep.hs view
@@ -37,7 +37,7 @@         -- * Coercions         Coercion(..), CoSel(..), FunSel(..),         UnivCoProvenance(..),-        CoercionHole(..), coHoleCoVar, setCoHoleCoVar, isHeteroKindCoHole,+        CoercionHole(..), coHoleCoVar, setCoHoleCoVar,         CoercionN, CoercionR, CoercionP, KindCoercion,         MCoercion(..), MCoercionR, MCoercionN, @@ -261,47 +261,9 @@   multiplicity argument nondependent in #20164.  * Re the ft_af field: see Note [FunTyFlag] in GHC.Types.Var-  See Note [Types for coercions, predicates, and evidence]-  This visibility info makes no difference in Core; it matters-  only when we regard the type as a Haskell source type.--Note [Types for coercions, predicates, and evidence]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-We treat differently:--  (a) Predicate types-        Test: isPredTy-        Binders: DictIds-        Kind: Constraint-        Examples: (Eq a), and (a ~ b)--  (b) Coercion types are primitive, unboxed equalities-        Test: isCoVarTy-        Binders: CoVars (can appear in coercions)-        Kind: TYPE (TupleRep [])-        Examples: (t1 ~# t2) or (t1 ~R# t2)--  (c) Evidence types is the type of evidence manipulated by-      the type constraint solver.-        Test: isEvVarType-        Binders: EvVars-        Kind: Constraint or TYPE (TupleRep [])-        Examples: all coercion types and predicate types--Coercion types and predicate types are mutually exclusive,-but evidence types are a superset of both.--When treated as a user type,--  - Predicates (of kind Constraint) are invisible and are-    implicitly instantiated--  - Coercion types, and non-pred evidence types (i.e. not-    of kind Constraint), are just regular old types, are-    visible, and are not implicitly instantiated.--In a FunTy { ft_af = af } and af = FTF_C_T or FTF_C_C, the argument-type is always a Predicate type.+  See Note [Types for coercions, predicates, and evidence] in+  GHC.Core.Predicate.  This visibility info makes no difference in Core;+  it matter only when we regard the type as a Haskell source type.  Note [Weird typing rule for ForAllTy] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~@@ -983,7 +945,6 @@   ppr SelForAll      = text "All"   ppr (SelFun fs)    = text "Fun" <> parens (ppr fs) - pprOneCharRole :: Role -> SDoc pprOneCharRole Nominal          = char 'N' pprOneCharRole Representational = char 'R'@@ -994,6 +955,11 @@   ppr SelArg  = text "arg"   ppr SelRes  = text "res" +instance NFData FunSel where+  rnf SelMult = ()+  rnf SelArg  = ()+  rnf SelRes  = ()+ instance Binary CoSel where    put_ bh (SelTyCon n r)   = do { putByte bh 0; put_ bh n; put_ bh r }    put_ bh SelForAll        = putByte bh 1@@ -1010,9 +976,9 @@                    _ -> return (SelFun SelRes) }  instance NFData CoSel where-  rnf (SelTyCon n r) = n `seq` r `seq` ()+  rnf (SelTyCon n r) = rnf n `seq` rnf r `seq` ()   rnf SelForAll      = ()-  rnf (SelFun fs)    = fs `seq` ()+  rnf (SelFun fs)    = rnf fs `seq` ()  -- | A semantically more meaningful type to represent what may or may not be a -- useful 'Coercion'.@@ -1092,19 +1058,21 @@ between ForallTys, or TyConApps, or FunTys.  There are three forms, split by the CoSel field inside the SelCo:-SelTyCon, SelForAll, and SelFun.+SelTyCon, SelForAll, and SelFun.  The typing rules below are directly+checked by the SelCo case of GHC.Core.Lint.lintCoercion.  * SelTyCon: -      co : (T s1..sn) ~r0 (T t1..tn)-      T is a data type, not a newtype, nor an arrow type-      r = tyConRole tc r0 i+      co : (T s1..sn) ~r (T t1..tn)+      T is not a saturated FunTyCon (use SelFun for that)+      T is injective at role r+      ri = tyConRole tc r i       i < n    (i is zero-indexed)       -----------------------------------      SelCo (SelTyCon i r) co : si ~r ti+      SelCo (SelTyCon i ri) co : si ~ri ti -  "Not a newtype": see Note [SelCo and newtypes]-  "Not an arrow type": see SelFun below+  "Injective at role r": see Note [SelCo and newtypes]+  "Not saturated FunTyCon": see SelFun below     See Note [SelCo Cached Roles] @@ -1200,11 +1168,12 @@    forall a. e_ty Note the Specified visibility of (forall a. e_ty); the Core type just isn't able to express more than one visiblity, and we pick `Specified`.  See `exprType` and-`mkLamType` in GHC.Core.Utils, and `GHC.Type.Var.coreLamForAllTyFlag`.+`mkLamType` in GHC.Core.Utils, and `GHC.Type.Var.coreTyLamForAllTyFlag`.  So how can we ever get a term of type (forall a -> e_ty)?  Answer: /only/ via a-cast built with ForAllCo.  See `GHC.Tc.Types.Evidence.mkWpForAllCast`.  This does-not seem very satisfying, but it does the job.+cast built with ForAllCo.  See `GHC.Core.Coercion.mkForAllVisCos`,+`GHC.Tc.Types.Evidence.mkWpForAllCast` and `GHC.Core.Make.mkCoreTyLams`.+This does not seem very satisfying, but it does the job.  An alternative would be to put a visibility flag into `Lam` (a huge change), or into a `TyVar` (a more plausible change), but we leave that for the future.@@ -1220,14 +1189,15 @@  The typing rule is: -  kind_co : k1 ~N k2-  tv1:k1 |- co : t1 ~r t2+  G |- kind_co : k1 ~N k2+  tv1 \not\in fv(typeKind(t1),typeKind(t2))  -- Skolem escape+  G, tv1:k1 |- co : t1 ~r t2   if r=N, then vis1=vis2   -------------------------------------  ForAllCo (tv1:k1) vis1 vis2 kind_co co-     : forall (tv1:k1) <vis1>. t1+  G |- ForAllCo (tv1:k1) vis1 vis2 kind_co co+         : forall (tv1:k1) <vis1>. t1               ~r-       forall (tv1:k2) <vis2>. (t2[tv1 |-> (tv1:k2) |> sym kind_co])+           forall (tv1:k2) <vis2>. (t2[tv1 |-> (tv1:k2) |> sym kind_co])  Several things to note here @@ -1471,6 +1441,10 @@  Yikes! Clearly, this is terrible. The solution is simple: forbid SelCo to be used on newtypes if the internal coercion is representational.+More specifically, we use isInjectiveTyCon to determine whether+T is injective at role r:+* Newtypes and datatypes are both injective at Nominal role, but+* Newtypes are not injective at Representational role See the SelCo equation for GHC.Core.Lint.lintCoercion.  This is not just some corner case discovered by a segfault somewhere;@@ -1566,9 +1540,9 @@   -- Why Ord?  See Note [Ord instance of IfaceType] in GHC.Iface.Type  instance Outputable UnivCoProvenance where-  ppr PhantomProv      = text "(phantom)"-  ppr ProofIrrelProv   = text "(proof irrel)"-  ppr (PluginProv str) = parens (text "plugin" <+> brackets (text str))+  ppr PhantomProv          = text "(phantom)"+  ppr (ProofIrrelProv {})  = text "(proof irrel)"+  ppr (PluginProv str)     = parens (text "plugin" <+> brackets (text str))  instance NFData UnivCoProvenance where   rnf p = p `seq` ()@@ -1679,19 +1653,11 @@                        -- See Note [CoercionHoles and coercion free variables]                   , ch_ref :: IORef (Maybe Coercion)--                 , ch_hetero_kind :: Bool-                       -- True <=> arises from a kind-level equality-                       -- See Note [Equalities with incompatible kinds]-                       --     in GHC.Tc.Solver.Equality, wrinkle (EIK2)                  }  coHoleCoVar :: CoercionHole -> CoVar coHoleCoVar = ch_co_var -isHeteroKindCoHole :: CoercionHole -> Bool-isHeteroKindCoHole = ch_hetero_kind- setCoHoleCoVar :: CoercionHole -> CoVar -> CoercionHole setCoHoleCoVar h cv = h { ch_co_var = cv } @@ -1702,8 +1668,7 @@   dataTypeOf _ = mkNoRepType "CoercionHole"  instance Outputable CoercionHole where-  ppr (CoercionHole { ch_co_var = cv, ch_hetero_kind = hk })-    = braces (ppr cv <> ppWhen hk (text "[hk]"))+  ppr (CoercionHole { ch_co_var = cv }) = braces (ppr cv)  instance Uniquable CoercionHole where   getUnique (CoercionHole { ch_co_var = cv }) = getUnique cv
GHC/Core/TyCo/Subst.hs view
@@ -13,9 +13,9 @@         Subst(..), TvSubstEnv, CvSubstEnv, IdSubstEnv,         emptyIdSubstEnv, emptyTvSubstEnv, emptyCvSubstEnv, composeTCvSubst,         emptySubst, mkEmptySubst, isEmptyTCvSubst, isEmptySubst,-        mkTCvSubst, mkTvSubst, mkCvSubst, mkIdSubst,+        mkSubst, mkTCvSubst, mkTvSubst, mkCvSubst, mkIdSubst,         getTvSubstEnv, getIdSubstEnv,-        getCvSubstEnv, getSubstInScope, setInScope, getSubstRangeTyCoFVs,+        getCvSubstEnv, substInScopeSet, setInScope, getSubstRangeTyCoFVs,         isInScope, elemSubst, notElemSubst, zapSubst,         extendSubstInScope, extendSubstInScopeList, extendSubstInScopeSet,         extendTCvSubst, extendTCvSubstWithClone,@@ -60,7 +60,7 @@    , mkAxiomCo, mkAppCo, mkGReflCo    , mkInstCo, mkLRCo, mkTyConAppCo    , mkCoercionType-   , coercionKind, coercionLKind, coVarTypesRole )+   , coercionLKind, coVarTypesRole ) import {-# SOURCE #-} GHC.Core.TyCo.Ppr ( pprTyVar ) import {-# SOURCE #-} GHC.Core.Ppr ( ) -- instance Outputable CoreExpr import {-# SOURCE #-} GHC.Core ( CoreExpr )@@ -68,12 +68,10 @@ import GHC.Core.TyCo.Rep import GHC.Core.TyCo.FVs -import GHC.Types.Basic( SwapFlag(..), isSwapped, pickSwap, notSwapped ) import GHC.Types.Var import GHC.Types.Var.Set import GHC.Types.Var.Env -import GHC.Data.Pair import GHC.Utils.Constants (debugIsOn) import GHC.Utils.Misc import GHC.Types.Unique.Supply@@ -104,9 +102,9 @@ data Subst   = Subst InScopeSet  -- Variables in scope (both Ids and TyVars) /after/                       -- applying the substitution-          IdSubstEnv  -- Substitution from NcIds to CoreExprs-          TvSubstEnv  -- Substitution from TyVars to Types-          CvSubstEnv  -- Substitution from CoVars to Coercions+          IdSubstEnv  -- Substitution from InId    to OutExpr+          TvSubstEnv  -- Substitution from InTyVar to OutType+          CvSubstEnv  -- Substitution from InCoVar to OutCoercion          -- INVARIANT 1: See Note [The substitution invariant]         -- This is what lets us deal with name capture properly@@ -115,7 +113,7 @@         --              see Note [Substitutions apply only once]         --         -- INVARIANT 3: See Note [Extending the IdSubstEnv] in "GHC.Core.Subst"-        -- and Note [Extending the TvSubstEnv and CvSubstEnv]+        -- and              Note [Extending the TvSubstEnv and CvSubstEnv]         --         -- INVARIANT 4: See Note [Substituting types, coercions, and expressions] @@ -183,8 +181,10 @@ we use during unifications, it must not be repeatedly applied.  Note [Extending the TvSubstEnv and CvSubstEnv]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-See #tcvsubst_invariant# for the invariants that must hold.+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+The TvSubstEnv and CvSubstEnv have a binding for each TyCoVar+  - whose unique has changed, OR+  - whose kind has changed  This invariant allows a short-cut when the subst envs are empty: if the TvSubstEnv and CvSubstEnv are empty --- i.e. (isEmptyTCvSubst subst)@@ -207,7 +207,7 @@ * In substTy, substTheta, we can short-circuit when the TvSubstEnv is empty  Note [Substituting types, coercions, and expressions]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Types and coercions are mutually recursive, and either may have variables "belonging" to the other. Thus, every time we wish to substitute in a type, we may also need to substitute in a coercion, and vice versa.@@ -271,6 +271,9 @@ isEmptyTCvSubst (Subst _ _ tv_env cv_env)   = isEmptyVarEnv tv_env && isEmptyVarEnv cv_env +mkSubst :: InScopeSet -> IdSubstEnv -> TvSubstEnv -> CvSubstEnv -> Subst+mkSubst = Subst+ mkTCvSubst :: InScopeSet -> TvSubstEnv -> CvSubstEnv -> Subst mkTCvSubst in_scope tvs cvs = Subst in_scope emptyIdSubstEnv tvs cvs @@ -295,8 +298,8 @@ getCvSubstEnv (Subst _ _ _ cenv) = cenv  -- | Find the in-scope set: see Note [The substitution invariant]-getSubstInScope :: Subst -> InScopeSet-getSubstInScope (Subst in_scope _ _ _) = in_scope+substInScopeSet :: Subst -> InScopeSet+substInScopeSet (Subst in_scope _ _ _) = in_scope  setInScope :: Subst -> InScopeSet -> Subst setInScope (Subst _ ids tvs cvs) in_scope = Subst in_scope ids tvs cvs@@ -501,7 +504,7 @@   , not (all isCoVar cvs)   = pprPanic "zipCoEnv" (ppr cvs <+> ppr cos)   | otherwise-  = mkVarEnv (zipEqual "zipCoEnv" cvs cos)+  = mkVarEnv (zipEqual cvs cos)  -- Pretty printing, for debugging only @@ -917,7 +920,7 @@ substForAllCoBndr :: Subst -> TyCoVar -> KindCoercion                   -> (Subst, TyCoVar, Coercion) substForAllCoBndr subst-  = substForAllCoBndrUsing NotSwapped (substCo subst) subst+  = substForAllCoBndrUsing (substCo subst) subst  -- | Like 'substForAllCoBndr', but disables sanity checks. -- The problems that the sanity checks in substCo catch are described in@@ -927,33 +930,26 @@ substForAllCoBndrUnchecked :: Subst -> TyCoVar -> KindCoercion                            -> (Subst, TyCoVar, Coercion) substForAllCoBndrUnchecked subst-  = substForAllCoBndrUsing NotSwapped (substCoUnchecked subst) subst+  = substForAllCoBndrUsing (substCoUnchecked subst) subst  -- See Note [Sym and ForAllCo]-substForAllCoBndrUsing :: SwapFlag  -- Apply sym to binder?-                       -> (Coercion -> Coercion)  -- transformation to kind co+substForAllCoBndrUsing :: (Coercion -> Coercion)  -- transformation to kind co                        -> Subst -> TyCoVar -> KindCoercion                        -> (Subst, TyCoVar, KindCoercion)-substForAllCoBndrUsing sym sco subst old_var-  | isTyVar old_var = substForAllCoTyVarBndrUsing sym sco subst old_var-  | otherwise       = substForAllCoCoVarBndrUsing sym sco subst old_var+substForAllCoBndrUsing sco subst old_var+  | isTyVar old_var = substForAllCoTyVarBndrUsing sco subst old_var+  | otherwise       = substForAllCoCoVarBndrUsing sco subst old_var -substForAllCoTyVarBndrUsing :: SwapFlag  -- Apply sym to binder?-                            -> (Coercion -> Coercion)  -- transformation to kind co+substForAllCoTyVarBndrUsing :: (Coercion -> Coercion)  -- transformation to kind co                             -> Subst -> TyVar -> KindCoercion                             -> (Subst, TyVar, KindCoercion)-substForAllCoTyVarBndrUsing sym sco (Subst in_scope idenv tenv cenv) old_var old_kind_co+substForAllCoTyVarBndrUsing sco (Subst in_scope idenv tenv cenv) old_var old_kind_co   = assert (isTyVar old_var )     ( Subst (in_scope `extendInScopeSet` new_var) idenv new_env cenv     , new_var, new_kind_co )   where-    new_env | no_change, notSwapped sym-            = delVarEnv tenv old_var-            | isSwapped sym-            = extendVarEnv tenv old_var $-              TyVarTy new_var `CastTy` new_kind_co-            | otherwise-            = extendVarEnv tenv old_var (TyVarTy new_var)+    new_env | no_change = delVarEnv tenv old_var+            | otherwise = extendVarEnv tenv old_var (TyVarTy new_var)      no_kind_change = noFreeVarsOfCo old_kind_co     no_change = no_kind_change && (new_var == old_var)@@ -969,20 +965,17 @@      new_var  = uniqAway in_scope (setTyVarKind old_var new_ki1) -substForAllCoCoVarBndrUsing :: SwapFlag  -- Apply sym to binder?-                            -> (Coercion -> Coercion)  -- transformation to kind co+substForAllCoCoVarBndrUsing :: (Coercion -> Coercion)  -- transformation to kind co                             -> Subst -> CoVar -> KindCoercion                             -> (Subst, CoVar, KindCoercion)-substForAllCoCoVarBndrUsing sym sco (Subst in_scope idenv tenv cenv)+substForAllCoCoVarBndrUsing sco (Subst in_scope idenv tenv cenv)                             old_var old_kind_co   = assert (isCoVar old_var )     ( Subst (in_scope `extendInScopeSet` new_var) idenv tenv new_cenv     , new_var, new_kind_co )   where-    new_cenv | no_change, notSwapped sym-             = delVarEnv cenv old_var-             | otherwise-             = extendVarEnv cenv old_var (mkCoVarCo new_var)+    new_cenv | no_change = delVarEnv cenv old_var+             | otherwise = extendVarEnv cenv old_var (mkCoVarCo new_var)      no_kind_change = noFreeVarsOfCo old_kind_co     no_change = no_kind_change && (new_var == old_var)@@ -990,10 +983,8 @@     new_kind_co | no_kind_change = old_kind_co                 | otherwise      = sco old_kind_co -    Pair h1 h2 = coercionKind new_kind_co--    new_var       = uniqAway in_scope $ mkCoVar (varName old_var) new_var_type-    new_var_type  = pickSwap sym h1 h2+    new_ki1       = coercionLKind new_kind_co+    new_var       = uniqAway in_scope $ mkCoVar (varName old_var) new_ki1  substCoVar :: Subst -> CoVar -> Coercion substCoVar (Subst _ _ _ cenv) cv
GHC/Core/TyCo/Tidy.hs view
@@ -1,5 +1,3 @@-{-# OPTIONS_GHC -Wno-incomplete-uni-patterns   #-}- -- | Tidying types and coercions for printing in error messages. module GHC.Core.TyCo.Tidy   (@@ -21,6 +19,7 @@ import GHC.Prelude import GHC.Data.FastString +import GHC.Core.Predicate( scopedSort ) import GHC.Core.TyCo.Rep import GHC.Core.TyCo.FVs import GHC.Types.Name hiding (varName)@@ -358,7 +357,7 @@      go_cv cv = tidyTyCoVarOcc env cv -    go_hole (CoercionHole cv r h) = (CoercionHole $! go_cv cv) r h+    go_hole (CoercionHole cv r) = (CoercionHole $! go_cv cv) r     -- Tidy even the holes; tidied types should have tidied kinds  tidyCos :: TidyEnv -> [Coercion] -> [Coercion]
GHC/Core/TyCon.hs view
@@ -1,4 +1,3 @@-{-# LANGUAGE CPP  #-} {-# LANGUAGE FlexibleInstances  #-} {-# LANGUAGE LambdaCase         #-} {-# LANGUAGE DeriveDataTypeable #-}@@ -25,7 +24,8 @@         mkRequiredTyConBinder,         mkAnonTyConBinder, mkAnonTyConBinders,         tyConBinderForAllTyFlag, tyConBndrVisForAllTyFlag, isNamedTyConBinder,-        isVisibleTyConBinder, isInvisibleTyConBinder,+        isVisibleTyConBinder, isInvisSpecTyConBinder, isInvisibleTyConBinder,+        isInferredTyConBinder,         isVisibleTcbVis, isInvisSpecTcbVis,          -- ** Field labels@@ -46,8 +46,9 @@         noTcTyConScopedTyVars,          -- ** Predicates on TyCons-        isAlgTyCon, isVanillaAlgTyCon,-        isClassTyCon, isFamInstTyCon,+        isAlgTyCon, isVanillaAlgTyCon, isClassTyCon,+        isUnaryClassTyCon, isUnaryClassTyCon_maybe,+        isFamInstTyCon,         isPrimTyCon,         isTupleTyCon, isUnboxedTupleTyCon, isBoxedTupleTyCon,         isUnboxedSumTyCon, isPromotedTupleTyCon,@@ -59,7 +60,7 @@         isKindTyCon, isKindName, isLiftedTypeKindTyConName,         isTauTyCon, isFamFreeTyCon, isForgetfulSynTyCon, -        isDataTyCon,+        isBoxedDataTyCon,         isTypeDataTyCon,         isEnumerationTyCon,         isNewTyCon, isAbstractTyCon,@@ -68,7 +69,7 @@         isOpenTypeFamilyTyCon, isClosedSynFamilyTyConWithAxiom_maybe,         tyConInjectivityInfo,         isBuiltInSynFamTyCon_maybe,-        isGadtSyntaxTyCon, isInjectiveTyCon, isGenerativeTyCon, isGenInjAlgRhs,+        isGadtSyntaxTyCon, isInjectiveTyCon, isGenerativeTyCon,         isTyConAssoc, tyConAssoc_maybe, tyConFlavourAssoc_maybe,         isImplicitTyCon,         isTyConWithSrcDataCons,@@ -86,8 +87,6 @@         tyConCType_maybe,         tyConDataCons, tyConDataCons_maybe,         tyConSingleDataCon_maybe, tyConSingleDataCon,-        tyConAlgDataCons_maybe,-        tyConSingleAlgDataCon_maybe,         tyConFamilySize,         tyConStupidTheta,         tyConArity,@@ -181,6 +180,7 @@ import GHC.Utils.Misc import GHC.Types.Unique.Set import GHC.Unit.Module+import Control.DeepSeq  import Language.Haskell.Syntax.Basic (FieldLabelString(..)) @@ -488,7 +488,7 @@   | tv `elemVarSet` dep_set = mkNamedTyConBinder Required tv   | otherwise               = mkAnonTyConBinder tv -tyConBinderForAllTyFlag :: TyConBinder -> ForAllTyFlag+tyConBinderForAllTyFlag :: VarBndr a TyConBndrVis -> ForAllTyFlag tyConBinderForAllTyFlag (Bndr _ vis) = tyConBndrVisForAllTyFlag vis  tyConBndrVisForAllTyFlag :: TyConBndrVis -> ForAllTyFlag@@ -514,10 +514,22 @@ isInvisSpecTcbVis (NamedTCB Specified) = True isInvisSpecTcbVis _                    = False +isInvisInferTcbVis :: TyConBndrVis -> Bool+isInvisInferTcbVis (NamedTCB Inferred) = True+isInvisInferTcbVis _                   = False++isInvisSpecTyConBinder :: VarBndr tv TyConBndrVis -> Bool+-- Works for IfaceTyConBinder too+isInvisSpecTyConBinder (Bndr _ tcb_vis) = isInvisSpecTcbVis tcb_vis+ isInvisibleTyConBinder :: VarBndr tv TyConBndrVis -> Bool -- Works for IfaceTyConBinder too isInvisibleTyConBinder tcb = not (isVisibleTyConBinder tcb) +isInferredTyConBinder :: VarBndr var TyConBndrVis -> Bool+-- Works for IfaceTyConBinder too+isInferredTyConBinder (Bndr _ tcb_vis) = isInvisInferTcbVis tcb_vis+ -- Build the 'tyConKind' from the binders and the result kind. -- Keep in sync with 'mkTyConKind' in GHC.Iface.Type. mkTyConKind :: [TyConBinder] -> Kind -> Kind@@ -719,7 +731,12 @@                   0 -> return AnonTCB                   _ -> do { vis <- get bh; return (NamedTCB vis) } } +instance NFData TyConBndrVis where+  rnf AnonTCB        = ()+  rnf (NamedTCB vis) = rnf vis ++ {- ********************************************************************* *                                                                      *                The TyCon type@@ -1114,6 +1131,11 @@                         -- in tcHasFixedRuntimeRep.     } +  | UnaryClassTyCon {  -- See Note [Unary class magic], esp (UCM2)+                       -- INVARIANT: the algTcFlavour of this TyCon is ClassTyCon+      data_con :: DataCon+      }+ mkSumTyConRhs :: [DataCon] -> AlgTyConRhs mkSumTyConRhs data_cons = SumTyCon data_cons (length data_cons) @@ -1169,11 +1191,12 @@ -- that visibility in this sense does not correspond to visibility in -- the context of any particular user program! visibleDataCons :: AlgTyConRhs -> [DataCon]-visibleDataCons (AbstractTyCon {})            = []-visibleDataCons (DataTyCon{ data_cons = cs }) = cs-visibleDataCons (NewTyCon{ data_con = c })    = [c]-visibleDataCons (TupleTyCon{ data_con = c })  = [c]-visibleDataCons (SumTyCon{ data_cons = cs })  = cs+visibleDataCons (AbstractTyCon {})                = []+visibleDataCons (DataTyCon{ data_cons = cs })     = cs+visibleDataCons (NewTyCon{ data_con = c })        = [c]+visibleDataCons (UnaryClassTyCon{ data_con = c }) = [c]+visibleDataCons (TupleTyCon{ data_con = c })      = [c]+visibleDataCons (SumTyCon{ data_cons = cs })      = cs  -- | Describes the flavour of an algebraic type constructor. For -- classes and data families, this flavour includes a reference to@@ -1191,7 +1214,9 @@   | UnboxedSumTyCon    -- | Type constructors representing a class dictionary.-  -- See Note [ATyCon for classes] in "GHC.Core.TyCo.Rep"+  -- See Note [ATyCon for classes] in "GHC.Types.TyThing"+  -- INVARIANT: the algTcRhs is never NewTyCon; it could be+  --            TupleTyCon, DataTyCon, UnaryClassTyCon   | ClassTyCon         Class           -- INVARIANT: the classTyCon of this Class is the                         -- current tycon@@ -1409,6 +1434,194 @@  See also Note [Newtype eta and homogeneous axioms] in GHC.Tc.TyCl.Build. +Note [Unary class magic]+~~~~~~~~~~~~~~~~~~~~~~~~+Consider a class with just one method, or with no methods and one+superclass:+  class UC a where { op :: a -> a }+  class Eq a => UD a where {}+Such a class is called a /unary class/.++We could represent the dictionary for a unary class with a data type:+  data UC a where { MkUC :: (a->a) -> UC a }+  data UD a where { MkUD :: Eq a =>  UD a }+But it would be more efficent to use a newtype; and for decades GHC did+exactly that, because:++  * Unary classes are surprisingly common, so it's a useful optimisation.++  * The `reflection` library uses `unsafeCoerce` to /rely/ on the fact that+    a unary class is ultimately represented by its payload.  We may not like+    it, and I hope to ultimately eliminate the necessity for this by using+    `withDict` (see Note [withDict] in GHC.Tc.Instance.Class).  But meanwhile+    we'd prefer not to break this usage.++But alas, using a newtype representation (surprisingly) led multiple, subtle,+Bad Things: see Note [Representing unary classes with newtypes: bad, bad, bad].++This Note explains what GHC now does for unary classes.++(UCM0) Throughout the compiler, right up to the code generator, GHC thinks that a+  unary class is just like a non-unary class:+    - Represented by a data type,+    - with one constructor,+    - which has one field++(UCM1) Then when converting from Core to STG, in GHC.CoreToStg, we effectively+  transform+    - op   ta tb tc dict_arg  -->  dict_arg+    - MkUC ta tb tc meth_arg  -->  meth_arg++  Note that we do this transformation well /after/ generating an interface file,+  so importing modules only see the data constructor.++  This late transformation has a lot in common with the treatment of+  `unsafeEqualityProof`; see (U2) in Note [Implementing unsafeCoerce]+  in GHC.Internal.Unsafe.Coerce.++In this way we get the efficiency of a newtype without the bugs that we get+by exposing the newtype representation too early.++There are a number of wrinkles++(UCM2) The TyCon for a unary class is /not/ identified as a newtype.+   Rather, it has its own AlgTyConRhs, namely `UnaryClassTyCon`++(UCM3) Unlike non-unary classes, a value of type (C ty), where `C` is a unary+   class, might be bottom, because it is represented by the method type alone.+   See GHC.Core.Type.isTerminatingType.++   Similarly in exprOkForSpeculation/exprOkToDiscard/exprOkForSpecEval,+   in GHC.Core.Utils.  In the utility funcion `app_ok` we need a special+   case for the DFunIds; they generally terminate, but not for unary classes.++(UMC4) To avoid regressions, in Core we want to remember that+             (MkUC x) is really just  x+             (op d)   is really just  d+    We account for this in several places:++    - `GHC.Core.Utils.exprIsTrivial` treats the above two forms as trivial++    - `GHC.Core.Unfold.sizeExpr` (which computes the size of an expression to+      guide inlining) treats (MkUC e) as the same size as `e`, and similarly+      (op d).++    - `GHC.Core.Unfold.inlineBoringOK` where we want to ensure that we+      always-inline (MkUC op), even into a boring context. See (IB6)+      in Note [inlineBoringOk]++(UCM5) `GHC.Core.Unfold.Make.mkDFunUnfolding` builds a `DFunUnfolding` for+   non-unary classes, but just an /ordinary/ unfolding for unary classes.+       instance Num a => Num [a] where { .. }       -- (I1)+       instance UC a => UC [a] where { op = $cop }  -- (I2)+   From (I1) we get+       $fNumList = /\a \(d:Num a). MkNum (..) (..) (..)+         -- $fNumList has a DFunUnfolding+    But from (I2) we get+       $fUCList = /\a (d:UC a). MkUC ($cop a d)+       -- $fUCList has a regular CoreUnfolding++    Why?  Because we can safely inline $fUCList without code-size blow-up.+    Just one less indirection. It'd probably work ok with a DFunUnfolding;+    and it'd add another case for (UCM4) to spot.++(UCM6) In the constraint solver, when constructing evidence for a unary class+    (e.g. implicit parameters, withDict) be careful to use+    - the data constructor to build it: see `evDictApp`, `evUnaryDictAppE`+    - the class op to take it apart: see `evUnwrapIP`++(UCM7) You might worry about+           class UC1 a where { op :: Int# }    -- Single unboxed field+           class (a ~# b) => UC2 a b where {}  -- Unboxed equality superclass+  But these are illegal: predicates are always boxed, and all classes must have+  lifted fields.++(UCM8) The data constructor for a unary class has no wrapper, just a worker.+  (And the worker is turned into a cast by GHC.CoreToStg.Prep.isUnaryClassApp,+  as described above.)++(UCM9) Unary classes are treated as injective by `isInjectiveTyCon`, just like+  non-unary classes (which are TupleTyCons or DataTyCons).  This matters,+  because of the injectivity check done by lintCoercion (SelCo cs co)+  in GHC.Core.Lint.  There is a similar injectivity check in+  GHC.Core.Opt.Arity.pushCoDataCon.++  Generally, we want unary classes to behave like ordinary non-unary ones.++(UCM10) When, precisely, is a class unary?  It is unary iff+                  it has one field (superclass or method)+                  of boxed type+  The boxed-ness important. Consider+          class (a ~# b) => a ~ b where {}+  which is `eqClass` in GHC.Builtin.Types.  This has only one field, but it is+  definitely not a unary class: it is definitely represented by an ordinary+  algebraic data type with a single field of type (a ~# b).++  See `unary_class` in `GHC.Tc.TyCl.tcClassDecl1`++(UCM11) When building evidence for classes (unary or not) and implicit parameters,+  the constraint solver is careful to use functions that hide the precise+  evidence construction method.  Eg.g `evWrapIPE`.++(UCM12) In an interface-file description of a Class, we record whether or not+  the class is unary.  In theory this field is redundant, but because its value+  depends on the superclass and method fields, it's very easy to end up with+  a black hole when rehydrating interface the interface file. Easiest just to+  store the bit!  See `ifUnary` in GHC.Iface.Synatax.IfaceClassBody.+++Note [Representing unary classes with newtypes: bad, bad, bad]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+In the past we represented a unary class with a newtype, but that led to+some at least three really subtle bad consequences.++* Problem 1: When we represented unary classes via a newtype, the+    newtype axiom looked like+           t1::CONSTRAINT r ~ t2::TYPE r+    If TYPE and CONSTRAINT are apart, this can create unsoundness, via KindCo;+    see #21623.  Now we never make such a coercion, so that worry about TYPE+    being apart from CONSTRAINT has gone away entirely.  Hooray.++* Problem 2: a horrible hack in GHC.Core.Opt.OccurAnal.scrutOkForBinderSwap;+  see Historical Note [Care with binder-swap on dictionaries].+  Now the hack is gone.++* Problem 3: bogus specialisation.  The gory details are explained+  at https://gitlab.haskell.org/ghc/ghc/-/issues/23109#note_499130++  We had (using newtype classes)+     newtype SNat a = MKSNat Natural           -- axiom  snCo a :: SNat a ~ Natural+     class KNat a where { natSing :: SNat a }  -- axiom  knCo a :: KNat a ~ SNat a+  and a pattern match+    K @a (g : 32 ~ a+1) -> ...(foo @a (d :: KNat a))...+  where K is a data constructor binding `a` as an existential.++  In the code I was looking at, after lots of inlining an simplification, we find+  that (d::KNat a) is built like this:+    (d1 :: KNat 32)    = 32 |> sym (snCo 32) |> sym (knCo 32)+    (d2 :: SNat (a+1)) = d1 |> knCo g+    (d3 :: Natural)    = d2 |> snCo (a+1)+    (d4 :: Natural)    = d3 - 1+    (d  :: KNat a)     = d4 |> sym (snCo a) |> sym (knCo a)++  But d3 :: Natural = 32 |> (co's involving g) :: Natural ~ Natural+  and that is just Refl.  So we drop all the co's, including the crucial `g`,+  and just say d3 = 32; and+        d :: KNat a = (32-1) |> sym (snCo a) |> sym (knCo a)+  Now, we can float `d` outwards, crucially aided by polymorphic specialisation,+  (Note [Specialising polymorphic dictionaries] in GHC.Core.Opt.Specialise)+  and use that evidence to get an utterly bogus specialisation for the function+      foo :: forall b. KNat b => blah++  Solution: don't use newtype classes.  Then we get+    (d1 :: KNat 32)    = MkKN @32 (32 |> sym (snCo 32))+    (d2 :: SNat (a+1)) = natSing d1 |> SN g+    (d3 :: Natural)    = d2 |> snCo (a+1)+    (d4 :: Natural)    = d3 -1+    (d  :: KNat a)     = MkKN @a (d4 |> sym (snCo a))+  Now we don't get cancelling-out coercions.++ ************************************************************************ *                                                                      *                  TyConRepName@@ -1542,11 +1755,7 @@ -- "GHC.Types.RepType" and Note [VoidRep] in "GHC.Types.RepType". data PrimRep -- Unpacking of sum types is only supported since 9.6.1-#if MIN_VERSION_GLASGOW_HASKELL(9,6,0,0)   = BoxedRep {-# UNPACK #-} !(Maybe Levity) -- ^ Boxed, heap value-#else-  = BoxedRep                !(Maybe Levity) -- ^ Boxed, heap value-#endif   | Int8Rep       -- ^ Signed, 8-bit value   | Int16Rep      -- ^ Signed, 16-bit value   | Int32Rep      -- ^ Signed, 32-bit value@@ -1986,21 +2195,26 @@ -- satisfies condition DTT2 of Note [DataToTag overview] in -- GHC.Tc.Instance.Class isValidDTT2TyCon :: TyCon -> Bool-isValidDTT2TyCon = isDataTyCon+isValidDTT2TyCon = isBoxedDataTyCon -isDataTyCon :: TyCon -> Bool+isBoxedDataTyCon :: TyCon -> Bool -- ^ Returns @True@ for data types that are /definitely/ represented by -- heap-allocated constructors.  These are scrutinised by Core-level -- @case@ expressions, and they get info tables allocated for them. ----- Generally, the function will be true for all @data@ types and false--- for @newtype@s, unboxed tuples, unboxed sums and type family--- 'TyCon's. But it is not guaranteed to return @True@ in all cases+-- Generally, the function will be+-- true for all `data` types and+-- false for  newtype+--            unboxed tuples+--            unboxed sums+--            type family+--            type data+-- 'TyCon's. But it is not guaranteed to return `True` in all cases -- that it could. -- -- NB: for a data type family, only the /instance/ 'TyCon's --     get an info table.  The family declaration 'TyCon' does not-isDataTyCon (TyCon { tyConDetails = details })+isBoxedDataTyCon (TyCon { tyConDetails = details })   | AlgTyCon {algTcRhs = rhs} <- details   = case rhs of         TupleTyCon { tup_sort = sort }@@ -2011,8 +2225,9 @@             -- See Note [Type data declarations] in GHC.Rename.Module.         DataTyCon { is_type_data = type_data } -> not type_data         NewTyCon {}        -> False+        UnaryClassTyCon {} -> False         AbstractTyCon {}   -> False      -- We don't know, so return False-isDataTyCon _ = False+isBoxedDataTyCon _ = False  -- | Was this 'TyCon' declared as "type data"? -- See Note [Type data declarations] in GHC.Rename.Module.@@ -2029,23 +2244,34 @@ -- See also Note [Decomposing TyConApp equalities] in "GHC.Tc.Solver.Equality" isInjectiveTyCon :: TyCon -> Role -> Bool isInjectiveTyCon (TyCon { tyConDetails = details }) role-  = go details role+  = go details   where-    go _                             Phantom          = True -- Vacuously; (t1 ~P t2) holds for all t1, t2!-    go (AlgTyCon {})                 Nominal          = True-    go (AlgTyCon {algTcRhs = rhs})   Representational = isGenInjAlgRhs rhs-    go (SynonymTyCon {})             _                = False+    go _ | Phantom <- role = True -- Vacuously; (t1 ~P t2) holds for all t1, t2!++    go (AlgTyCon {algTcRhs = rhs})+       | Nominal <- role                                = True+       | Representational <- role                       = go_alg_rep rhs+     go (FamilyTyCon { famTcFlav = DataFamilyTyCon _ })-                                                  Nominal = True-    go (FamilyTyCon { famTcInj = Injective inj }) Nominal = and inj-    go (FamilyTyCon {})              _                = False-    go (PrimTyCon {})                _                = True-    go (PromotedDataCon {})          _                = True-    go (TcTyCon {})                  _                = True+       | Nominal <- role                                = True+    go (FamilyTyCon { famTcInj = Injective inj })+       | Nominal <- role                                = and inj+    go (FamilyTyCon {})                                 = False -  -- Reply True for TcTyCon to minimise knock on type errors-  -- See (W1) in Note [TcTyCon, MonoTcTyCon, and PolyTcTyCon] in GHC.Tc.TyCl+    go (SynonymTyCon {})    = False+    go (PrimTyCon {})       = True+    go (PromotedDataCon {}) = True+    go (TcTyCon {})         = True+       -- Reply True for TcTyCon to minimise knock on type errors+       -- See (W1) in Note [TcTyCon, MonoTcTyCon, and PolyTcTyCon] in GHC.Tc.TyCl +    -- go_alg_rep used only at Representational role+    go_alg_rep (TupleTyCon {})      = True+    go_alg_rep (SumTyCon {})        = True+    go_alg_rep (DataTyCon {})       = True+    go_alg_rep (UnaryClassTyCon {}) = True -- See (UCM9) in Note [Unary class magic]+    go_alg_rep (AbstractTyCon {})   = False+    go_alg_rep (NewTyCon {})        = False  -- | 'isGenerativeTyCon' is true of 'TyCon's for which this property holds -- (where r is the role passed in):@@ -2065,15 +2291,6 @@     -- In all other cases, injectivity implies generativity     go r _ = isInjectiveTyCon tc r --- | Is this an 'AlgTyConRhs' of a 'TyCon' that is generative and injective--- with respect to representational equality?-isGenInjAlgRhs :: AlgTyConRhs -> Bool-isGenInjAlgRhs (TupleTyCon {})          = True-isGenInjAlgRhs (SumTyCon {})            = True-isGenInjAlgRhs (DataTyCon {})           = True-isGenInjAlgRhs (AbstractTyCon {})       = False-isGenInjAlgRhs (NewTyCon {})            = False- -- | Is this 'TyCon' that for a @newtype@ isNewTyCon :: TyCon -> Bool isNewTyCon (TyCon { tyConDetails = details })@@ -2188,9 +2405,11 @@ isEnumerationTyCon (TyCon { tyConArity = arity, tyConDetails = details })   | AlgTyCon { algTcRhs = rhs } <- details   = case rhs of-       DataTyCon { is_enum = res } -> res-       TupleTyCon {}               -> arity == 0-       _                           -> False+       DataTyCon { is_enum = res }     -> res+       TupleTyCon { tup_sort = tsort }+         | arity == 0                  -> isBoxed (tupleSortBoxity tsort)+                                          -- () is an enumeration, but (##) is not+       _                               -> False   | otherwise = False  -- | Is this a 'TyCon', synonym or otherwise, that defines a family?@@ -2448,6 +2667,8 @@         SumTyCon {} -> False   -- only unboxed sums here +       UnaryClassTyCon {} -> True  -- Always boxed+        NewTyCon { nt_fixed_rep = fixed_rep } -> fixed_rep               -- A newtype might not have a fixed runtime representation               -- with UnliftedNewtypes (#17360)@@ -2579,11 +2800,12 @@ tyConDataCons_maybe (TyCon { tyConDetails = details })   | AlgTyCon {algTcRhs = rhs} <- details   = case rhs of-       DataTyCon { data_cons = cons } -> Just cons-       NewTyCon { data_con = con }    -> Just [con]-       TupleTyCon { data_con = con }  -> Just [con]-       SumTyCon { data_cons = cons }  -> Just cons-       _                              -> Nothing+       DataTyCon { data_cons = cons }     -> Just cons+       NewTyCon { data_con = con }        -> Just [con]+       UnaryClassTyCon { data_con = con } -> Just [con]+       TupleTyCon { data_con = con }      -> Just [con]+       SumTyCon { data_cons = cons }      -> Just cons+       _                                  -> Nothing tyConDataCons_maybe _ = Nothing  -- | If the given 'TyCon' has a /single/ data constructor, i.e. it is a @data@@@ -2594,11 +2816,12 @@ tyConSingleDataCon_maybe (TyCon { tyConDetails = details })   | AlgTyCon { algTcRhs = rhs } <- details   = case rhs of-      DataTyCon { data_cons = [c] } -> Just c-      TupleTyCon { data_con = c }   -> Just c-      NewTyCon { data_con = c }     -> Just c-      _                             -> Nothing-  | otherwise                        = Nothing+      DataTyCon { data_cons = [c] }    -> Just c+      TupleTyCon { data_con = c }      -> Just c+      NewTyCon { data_con = c }        -> Just c+      UnaryClassTyCon { data_con = c } -> Just c+      _                                -> Nothing+  | otherwise = Nothing  -- | Like 'tyConSingleDataCon_maybe', but panics if 'Nothing'. tyConSingleDataCon :: TyCon -> DataCon@@ -2607,23 +2830,6 @@       Just c  -> c       Nothing -> pprPanic "tyConDataCon" (ppr tc) --- | Like 'tyConSingleDataCon_maybe', but returns 'Nothing' for newtypes.-tyConSingleAlgDataCon_maybe :: TyCon -> Maybe DataCon-tyConSingleAlgDataCon_maybe tycon-  | isNewTyCon tycon = Nothing-  | otherwise        = tyConSingleDataCon_maybe tycon---- | Returns @Just dcs@ if the given 'TyCon' is a @data@ type, a tuple type--- or a sum type with data constructors dcs. If the 'TyCon' has more than one--- constructor, or represents a primitive or function type constructor then--- @Nothing@ is returned.------ Like 'tyConDataCons_maybe', but returns 'Nothing' for newtypes.-tyConAlgDataCons_maybe :: TyCon -> Maybe [DataCon]-tyConAlgDataCons_maybe tycon-  | isNewTyCon tycon = Nothing-  | otherwise        = tyConDataCons_maybe tycon- -- | Determine the number of value constructors a 'TyCon' has. Panics if the -- 'TyCon' is not algebraic or a tuple tyConFamilySize  :: TyCon -> Int@@ -2632,6 +2838,7 @@   = case rhs of       DataTyCon { data_cons_size = size } -> size       NewTyCon {}                    -> 1+      UnaryClassTyCon {}             -> 1       TupleTyCon {}                  -> 1       SumTyCon { data_cons_size = size }  -> size       _                              -> pprPanic "tyConFamilySize 1" (ppr tc)@@ -2721,6 +2928,22 @@   | FamilyTyCon {famTcFlav = flav} <- details = Just flav   | otherwise                                 = Nothing +isUnaryClassTyCon :: TyCon -> Bool+isUnaryClassTyCon tc@(TyCon { tyConDetails = details })+  | AlgTyCon { algTcFlavour = flav, algTcRhs = UnaryClassTyCon {} } <- details+  = assertPpr (case flav of { ClassTyCon {} -> True; _ -> False }) (ppr tc) $+    True+  | otherwise+  = False++isUnaryClassTyCon_maybe :: TyCon -> Maybe (Class, DataCon)+isUnaryClassTyCon_maybe (TyCon { tyConDetails = details })+  | AlgTyCon { algTcFlavour = ClassTyCon cls _+             , algTcRhs = UnaryClassTyCon { data_con = dc } } <- details+  = Just (cls, dc)+  | otherwise+  = Nothing+ -- | Is this 'TyCon' that for a class instance? isClassTyCon :: TyCon -> Bool isClassTyCon (TyCon { tyConDetails = details })@@ -2835,11 +3058,12 @@                   SumTyCon {}        -> SumFlavour                   DataTyCon {}       -> DataTypeFlavour                   NewTyCon {}        -> NewtypeFlavour+                  UnaryClassTyCon {} -> ClassFlavour                   AbstractTyCon {}   -> AbstractTypeFlavour    | FamilyTyCon { famTcFlav = flav, famTcParent = parent } <- details   = case flav of-      DataFamilyTyCon{}            -> OpenFamilyFlavour IAmData parent+      DataFamilyTyCon{}            -> OpenFamilyFlavour (IAmData DataType) parent       OpenSynFamilyTyCon           -> OpenFamilyFlavour IAmType parent       ClosedSynFamilyTyCon{}       -> ClosedTypeFamilyFlavour       AbstractClosedSynFamilyTyCon -> ClosedTypeFamilyFlavour@@ -2860,7 +3084,7 @@ tcFlavourMustBeSaturated AbstractTypeFlavour {}  = False tcFlavourMustBeSaturated BuiltInTypeFlavour      = False tcFlavourMustBeSaturated PromotedDataConFlavour  = False-tcFlavourMustBeSaturated (OpenFamilyFlavour td _)= case td of { IAmData -> False; IAmType -> True }+tcFlavourMustBeSaturated (OpenFamilyFlavour td _)= case td of { IAmData {} -> False; IAmType -> True } tcFlavourMustBeSaturated TypeSynonymFlavour      = True tcFlavourMustBeSaturated ClosedTypeFamilyFlavour = True @@ -2908,6 +3132,10 @@                     0 -> return NotInjective                     _ -> do { xs <- get bh                             ; return (Injective xs) } }++instance NFData Injectivity where+  rnf NotInjective = ()+  rnf (Injective xs) = rnf xs  -- | Returns whether or not this 'TyCon' is definite, or a hole -- that may be filled in at some later point.  See Note [Skolem abstract data]
GHC/Core/TyCon/Env.hs view
@@ -103,7 +103,7 @@ anyTyConEnv f x          = nonDetFoldUFM ((||) . f) False x disjointTyConEnv x y     = disjointUFM x y -lookupTyConEnv_NF env n = expectJust "lookupTyConEnv_NF" (lookupTyConEnv env n)+lookupTyConEnv_NF env n = expectJust (lookupTyConEnv env n)  -- | Deterministic TyCon Environment --
GHC/Core/Type.hs view
@@ -33,7 +33,7 @@         mkScaledFunTys,         mkInvisFunTy, mkInvisFunTys,         tcMkVisFunTy, tcMkScaledFunTys, tcMkInvisFunTy,-        splitFunTy, splitFunTy_maybe,+        splitFunTy, splitFunTy_maybe, splitVisibleFunTy_maybe,         splitFunTys, funResultTy, funArgTy,         funTyConAppTy_maybe, funTyFlagTyCon,         tyConAppFunTy_maybe, tyConAppFunCo_maybe,@@ -55,7 +55,7 @@         splitForAllForAllTyBinders, splitForAllForAllTyBinder_maybe,         splitForAllTyCoVar_maybe, splitForAllTyCoVar,         splitForAllTyVar_maybe, splitForAllCoVar_maybe,-        splitPiTy_maybe, splitPiTy, splitPiTys,+        splitPiTy_maybe, splitPiTy, splitPiTys, collectPiTyBinders,         getRuntimeArgTys,         mkTyConBindersPreferAnon,         mkPiTy, mkPiTys,@@ -69,8 +69,6 @@         mkCharLitTy, isCharLitTy,         isLitTy, -        isPredTy,-         getRuntimeRep, splitRuntimeRep_maybe, kindRep_maybe, kindRep,         getLevity, levityType_maybe, @@ -82,8 +80,7 @@         coAxNthLHS,         stripCoercionTy, -        splitInvisPiTys, splitInvisPiTysN,-        invisibleTyBndrCount,+        splitInvisPiTys, splitInvisPiTysN, invisibleBndrCount,         filterOutInvisibleTypes, filterOutInferredTypes,         partitionInvisibleTypes, partitionInvisibles,         tyConForAllTyFlags, appTyForAllTyFlags,@@ -122,7 +119,7 @@         mkTYPEapp, mkTYPEapp_maybe,         mkCONSTRAINTapp, mkCONSTRAINTapp_maybe,         mkBoxedRepApp_maybe, mkTupleRepApp_maybe,-        typeOrConstraintKind,+        typeOrConstraintKind, liftedTypeOrConstraintKind,          -- *** Levity and boxity         sORTKind_maybe, typeTypeOrConstraint,@@ -135,7 +132,7 @@         kindBoxedRepLevity_maybe,         mightBeLiftedType, mightBeUnliftedType,         definitelyLiftedType, definitelyUnliftedType,-        isAlgType, isDataFamilyAppType,+        isAlgType, isDataFamilyApp, isSatTyFamApp,         isPrimitiveType, isStrictType, isTerminatingType,         isLevityTy, isLevityVar,         isRuntimeRepTy, isRuntimeRepVar, isRuntimeRepKindedTy,@@ -178,10 +175,6 @@         closeOverKindsDSet, closeOverKindsList,         closeOverKinds, -        -- * Well-scoped lists of variables-        scopedSort, tyCoVarsOfTypeWellScoped,-        tyCoVarsOfTypesWellScoped,-         -- * Forcing evaluation of types         seqType, seqTypes, @@ -202,7 +195,7 @@         zipTCvSubst,         notElemSubst,         getTvSubstEnv,-        zapSubst, getSubstInScope, setInScope, getSubstRangeTyCoFVs,+        zapSubst, substInScopeSet, setInScope, getSubstRangeTyCoFVs,         extendSubstInScope, extendSubstInScopeList, extendSubstInScopeSet,         extendTCvSubst, extendCvSubst,         extendTvSubst, extendTvSubstList, extendTvSubstAndInScope,@@ -223,20 +216,10 @@         substTyCoBndr, substTyVarToTyVar,         cloneTyVarBndr, cloneTyVarBndrs, lookupTyVar, -        -- * Tidying type related things up for printing-        tidyType,      tidyTypes,-        tidyOpenType,  tidyOpenTypes,-        tidyOpenTypeX, tidyOpenTypesX,-        tidyVarBndr, tidyVarBndrs,-        tidyFreeTyCoVars,-        tidyFreeTyCoVarX, tidyFreeTyCoVarsX,-        tidyTyCoVarOcc,-        tidyTopType,-        tidyForAllTyBinder, tidyForAllTyBinders,-         -- * Kinds         isTYPEorCONSTRAINT,-        isConcreteType, isFixedRuntimeRepKind,+        isConcreteType,+        isFixedRuntimeRepKind     ) where  import GHC.Prelude@@ -248,7 +231,6 @@  import GHC.Core.TyCo.Rep import GHC.Core.TyCo.Subst-import GHC.Core.TyCo.Tidy import GHC.Core.TyCo.FVs  -- friends:@@ -291,6 +273,7 @@ import GHC.Data.FastString  import GHC.Data.Maybe   ( orElse, isJust, firstJust )+import GHC.List (build)  -- $type_classification -- #type_classification#@@ -576,11 +559,7 @@     go_co _ (HoleCo h)       = pprPanic "expandTypeSynonyms hit a hole" (ppr h) -      -- the "False" and "const" are to accommodate the type of-      -- substForAllCoBndrUsing, which is general enough to-      -- handle coercion optimization (which sometimes swaps the-      -- order of a coercion)-    go_cobndr subst = substForAllCoBndrUsing NotSwapped (go_co subst) subst+    go_cobndr subst = substForAllCoBndrUsing (go_co subst) subst  {- Notes on type synonyms ~~~~~~~~~~~~~~~~~~~~~~~~~@@ -1443,6 +1422,15 @@   | FunTy af w arg res <- coreFullView ty = Just (af, w, arg, res)   | otherwise                             = Nothing +{-# INLINE splitVisibleFunTy_maybe #-}+splitVisibleFunTy_maybe :: Type -> Maybe (Type, Type)+-- ^ Works on visible function types only (t1 -> t2), and+--   returns t1 and t2, but not the multiplicity+splitVisibleFunTy_maybe ty+  | FunTy af _ arg res <- coreFullView ty+  , isVisibleFunArg af = Just (arg, res)+  | otherwise          = Nothing+ splitFunTys :: Type -> ([Scaled Type], Type) splitFunTys ty = split [] ty ty   where@@ -2047,6 +2035,18 @@     split orig_ty ty bs | Just ty' <- coreView ty = split orig_ty ty' bs     split orig_ty _                bs = (reverse bs, orig_ty) +collectPiTyBinders :: Type -> [PiTyBinder]+collectPiTyBinders ty = build $ \c n ->+  let+    split (ForAllTy b res) = Named b `c` split res+    split (FunTy { ft_af = af, ft_mult = w, ft_arg = arg, ft_res = res })+                           = Anon (Scaled w arg) af `c` split res+    split ty | Just ty' <- coreView ty = split ty'+    split _                = n+  in+    split ty+{-# INLINE collectPiTyBinders #-}+ -- | Extracts a list of run-time arguments from a function type, -- looking through newtypes to the right of arrows. --@@ -2088,12 +2088,12 @@       | otherwise       = [] -invisibleTyBndrCount :: Type -> Int+invisibleBndrCount :: Type -> Int -- Returns the number of leading invisible forall'd binders in the type -- Includes invisible predicate arguments; e.g. for --    e.g.  forall {k}. (k ~ *) => k -> k -- returns 2 not 1-invisibleTyBndrCount ty = length (fst (splitInvisPiTys ty))+invisibleBndrCount ty = length (fst (splitInvisPiTys ty))  -- | Like 'splitPiTys', but returns only *invisible* binders, including constraints. -- Stops at the first visible binder.@@ -2291,6 +2291,21 @@ isFamFreeTy (CastTy ty _)     = isFamFreeTy ty isFamFreeTy (CoercionTy _)    = False  -- Not sure about this +-- | Check whether a type is a data family type+isDataFamilyApp :: Type -> Bool+isDataFamilyApp ty = case tyConAppTyCon_maybe ty of+                           Just tc -> isDataFamilyTyCon tc+                           _       -> False++isSatTyFamApp :: Type -> Maybe (TyCon, [Type])+-- Return the argument if we have a saturated type family application+-- Why saturated?  See (ATF4) in Note [Apartness and type families]+isSatTyFamApp (TyConApp tc tys)+  |  isTypeFamilyTyCon tc+  && not (tys `lengthExceeds` tyConArity tc)  -- Not over-saturated+  = Just (tc, tys)+isSatTyFamApp _ = Nothing+ buildSynTyCon :: Name -> [KnotTied TyConBinder] -> Kind   -- ^ /result/ kind               -> [Role] -> KnotTied Type -> TyCon -- This function is here because here is where we have@@ -2458,12 +2473,6 @@                             isAlgTyCon tc       _other             -> False --- | Check whether a type is a data family type-isDataFamilyAppType :: Type -> Bool-isDataFamilyAppType ty = case tyConAppTyCon_maybe ty of-                           Just tc -> isDataFamilyTyCon tc-                           _       -> False- -- | Computes whether an argument (or let right hand side) should -- be computed strictly or lazily, based only on its type. -- Currently, it's just 'isUnliftedType'.@@ -2478,7 +2487,9 @@ -- NB: unlifted types are not terminating types! --     e.g. you can write a term (loop 1)::Int# that diverges. isTerminatingType ty = case tyConAppTyCon_maybe ty of-    Just tc -> isClassTyCon tc && not (isNewTyCon tc)+    Just tc -> isClassTyCon tc && not (isUnaryClassTyCon tc)+               -- A non-unary class TyCon is terminating+               -- See (UCM3) in Note [Unary class magic] in GHC.Core.TyCon     _       -> False  isPrimitiveType :: Type -> Bool@@ -2664,9 +2675,7 @@ -- No need to expand synonyms typeKind (TyConApp tc tys)      = piResultTys (tyConKind tc) tys typeKind (LitTy l)              = typeLiteralKind l-typeKind (FunTy { ft_af = af }) = case funTyFlagResultTypeOrConstraint af of-                                     TypeLike       -> liftedTypeKind-                                     ConstraintLike -> constraintKind+typeKind (FunTy { ft_af = af }) = liftedTypeOrConstraintKind (funTyFlagResultTypeOrConstraint af) typeKind (TyVarTy tyvar)        = tyVarKind tyvar typeKind (CastTy _ty co)        = coercionRKind co typeKind (CoercionTy co)        = coercionType co@@ -2698,10 +2707,10 @@      lifted_kind_from_body  -- Implements (FORALL2)       = case sORTKind_maybe body_kind of-          Just (ConstraintLike, _) -> constraintKind-          Just (TypeLike,       _) -> liftedTypeKind-          Nothing -> pprPanic "typeKind" (ppr body_kind)+          Just (torc, _) -> liftedTypeOrConstraintKind torc+          Nothing        -> pprPanic "typeKind" (ppr body_kind) + ---------------------------------------------  sORTKind_maybe :: Kind -> Maybe (TypeOrConstraint, Type)@@ -2740,14 +2749,6 @@           | otherwise           -> pprPanic "typeOrConstraint" (ppr ty <+> dcolon <+> ppr (typeKind ty)) -isPredTy :: HasDebugCallStack => Type -> Bool--- Precondition: expects a type that classifies values--- See Note [Types for coercions, predicates, and evidence] in GHC.Core.TyCo.Rep--- Returns True for types of kind (CONSTRAINT _), False for ones of kind (TYPE _)-isPredTy ty = case typeTypeOrConstraint ty of-                  TypeLike       -> False-                  ConstraintLike -> True- -- | Does this classify a type allowed to have values? Responds True to things -- like *, TYPE Lifted, TYPE IntRep, TYPE v, Constraint. isTYPEorCONSTRAINT :: Kind -> Bool@@ -2850,12 +2851,14 @@ isConcreteType :: Type -> Bool isConcreteType = isConcreteTypeWith emptyVarSet -isConcreteTypeWith :: TyVarSet -> Type -> Bool+-- | Like 'isConcreteType', but allows passing in a set of 'TyVar's that+-- should be considered concrete.+-- -- See Note [Concrete types] in GHC.Tc.Utils.Concrete.--- For this "With" version we pass in a set of TyVars to be considered--- concrete.  This supports mkSynonymTyCon, which needs to test the RHS--- for concreteness, under the assumption that the binders are instantiated--- to concrete types+isConcreteTypeWith :: TyVarSet -> Type -> Bool+-- This version, with a 'TyVarSet' argument, supports 'mkSynonymTyCon',+-- which needs to test the RHS for concreteness, under the assumption that+-- the binders are instantiated to concrete types isConcreteTypeWith conc_tvs = go   where     go (TyVarTy tv)        = isConcreteTyVar tv || tv `elemVarSet` conc_tvs@@ -2869,6 +2872,7 @@     go CastTy{}            = False     go CoercionTy{}        = False +    go_tc :: TyCon -> [Type] -> Bool     go_tc tc tys       | isForgetfulSynTyCon tc  -- E.g. type S a = Int                                 -- Then (S x) is concrete even if x isn't@@ -2884,7 +2888,6 @@       | otherwise  -- E.g. type families       = False - {- %************************************************************************ %*                                                                      *@@ -3429,3 +3432,7 @@ typeOrConstraintKind :: TypeOrConstraint -> RuntimeRepType -> Kind typeOrConstraintKind TypeLike       rep = mkTYPEapp       rep typeOrConstraintKind ConstraintLike rep = mkCONSTRAINTapp rep++liftedTypeOrConstraintKind :: TypeOrConstraint -> Kind+liftedTypeOrConstraintKind TypeLike       = liftedTypeKind+liftedTypeOrConstraintKind ConstraintLike = constraintKind
GHC/Core/Type.hs-boot view
@@ -9,31 +9,18 @@ import GHC.Types.Var( FunTyFlag, TyVar ) import GHC.Types.Basic( TypeOrConstraint ) -isPredTy     :: HasDebugCallStack => Type -> Bool-isCoercionTy :: Type -> Bool -mkAppTy    :: Type -> Type -> Type-mkCastTy   :: Type -> Coercion -> Type-mkTyConApp :: TyCon -> [Type] -> Type-mkCoercionTy :: Coercion -> Type-piResultTy :: HasDebugCallStack => Type -> Type -> Type--typeKind :: HasDebugCallStack => Type -> Type-typeTypeOrConstraint :: HasDebugCallStack => Type -> TypeOrConstraint--coreView       :: Type -> Maybe Type-rewriterView   :: Type -> Maybe Type-isRuntimeRepTy :: Type -> Bool-isLevityTy :: Type -> Bool-isMultiplicityTy :: Type -> Bool+coreView         :: Type -> Maybe Type+rewriterView     :: Type -> Maybe Type+chooseFunTyFlag  :: HasDebugCallStack => Type -> Type -> FunTyFlag+typeKind         :: HasDebugCallStack => Type -> Type+isCoercionTy     :: Type -> Bool+mkAppTy          :: Type -> Type -> Type+mkCastTy         :: Type -> Coercion -> Type+mkTyConApp       :: TyCon -> [Type] -> Type+getLevity        :: HasDebugCallStack => Type -> Type+getTyVar_maybe   :: Type -> Maybe TyVar isLiftedTypeKind :: Type -> Bool -splitTyConApp_maybe :: HasDebugCallStack => Type -> Maybe (TyCon, [Type])-tyConAppTyCon_maybe :: Type -> Maybe TyCon-getTyVar_maybe      :: Type -> Maybe TyVar--getLevity :: HasDebugCallStack => Type -> Type- partitionInvisibleTypes :: TyCon -> [Type] -> ([Type], [Type])--chooseFunTyFlag :: HasDebugCallStack => Type -> Type -> FunTyFlag+typeTypeOrConstraint    :: HasDebugCallStack => Type -> TypeOrConstraint
GHC/Core/Unfold.hs view
@@ -41,6 +41,8 @@ import GHC.Core.Utils import GHC.Core.DataCon import GHC.Core.Type+import GHC.Core.Class( Class )+import GHC.Core.Predicate( isUnaryClass )  import GHC.Types.Id import GHC.Types.Literal@@ -52,11 +54,15 @@  import GHC.Builtin.PrimOps import GHC.Builtin.Names+ import GHC.Data.Bag+ import GHC.Utils.Misc import GHC.Utils.Outputable  import qualified Data.ByteString as BS+import Data.List.NonEmpty (nonEmpty)+import qualified Data.List.NonEmpty as NE  -- | Unfolding options data UnfoldingOpts = UnfoldingOpts@@ -213,35 +219,122 @@ ************************************************************************ -} +{- Note [inlineBoringOk]+~~~~~~~~~~~~~~~~~~~~~~~~+See Note [INLINE for small functions]++The function `inlineBoringOk` returns True (boringCxtOk) if the supplied+unfolding, which looks like (\x y z. body), is such that the result of+inlining a saturated call is no bigger than `body`.  Some wrinkles:++(IB1) An important case is+    - \x. (x `cast` co)++(IB2) If `body` looks like a data constructor worker, we become keener+  to inline, by ignoring the number of arguments; we just insist they+  are all trivial.  Reason: in a call like `f (g x y)`, if `g` unfolds+  to a data construtor, we can allocate a data constructor instead of+  a thunk (g x y).++  A case in point where a GADT data constructor failed to inline (#25713)+      $WK = /\a \x. K @a <co> x+  We really want to inline a boring call to $WK so that we allocate+  a data constructor not a thunk ($WK @ty x).++  But not for nullary constructors!  We don't want to turn+     f ($WRefl @ty)+  into+     f (Refl @ty <co>)+   because the latter might allocate, whereas the former shares.+   (You might wonder if (Refl @ty <co>) should allocate, but I think+   that currently it does.)  So for nullary constructors, `inlineBoringOk`+   returns False.++(IB3) Types and coercions do not count towards the expression size.+      They are ultimately erased.++(IB4) If there are no value arguments, `inlineBoringOk` we have to be+  careful (#17182).  If we have+      let y = x @Int in f y y+  there’s no reason not to inline y at both use sites — no work is+  actually duplicated.++  But not so for coercion arguments! Unlike type arguments, which have+  no runtime representation, coercion arguments *do* have a runtime+  representation (albeit the zero-width VoidRep, see Note [Coercion+  tokens] in "GHC.CoreToStg").  For example:+       let y = g @Int <co> in g y y+  Here `co` is a value argument, and calling it twice might duplicate+  work.++  Even if `g` is a data constructor, so no work is duplicated,+  inlining `y` might duplicate allocation of a data constructor object+  (#17787). See also (IB2).++  TL;DR: if `is_fun` is False, so we have no value arguments, we /do/+  count coercion arguments, despite (IB3).++(IB5) You might wonder about an unfolding like  (\x y z -> x (y z)),+  whose body is, in some sense, just as small as (g x y z).+  But `inlineBoringOk` doesn't attempt anything fancy; it just looks+  for a function call with trivial arguments, Keep it simple.++(IB6) If we have an unfolding (K op) where K is a unary-class data constructor,+  we want to inline it!  So that we get calls (f op), which in turn can see (in+  STG land) that `op` is already evaluated and properly tagged. (If `op` isn't+  trivial we will have baled out before we get to the Var case.)  This made+  a big difference in benchmarks for the `effectful` library; details in !10479.++  See Note [Unary class magic] in GHC/Core/TyCon.+-}+ inlineBoringOk :: CoreExpr -> Bool--- See Note [INLINE for small functions] -- True => the result of inlining the expression is --         no bigger than the expression itself --     eg      (\x y -> f y x)--- This is a quick and dirty version. It doesn't attempt--- to deal with  (\x y z -> x (y z))--- The really important one is (x `cast` c)+-- See Note [inlineBoringOk] inlineBoringOk e   = go 0 e   where+    is_fun = isValFun e+     go :: Int -> CoreExpr -> Bool-    go credit (Lam x e) | isId x           = go (credit+1) e-                        | otherwise        = go credit e-        -- See Note [Count coercion arguments in boring contexts]-    go credit (App f (Type {}))            = go credit f-    go credit (App f a) | credit > 0-                        , exprIsTrivial a  = go (credit-1) f-    go credit (Tick _ e)                   = go credit e -- dubious-    go credit (Cast e _)                   = go credit e+    -- credit = #(value lambdas) = #(value args)+    go credit (Lam x e) | isRuntimeVar x  = go (credit+1) e+                        | otherwise       = go credit e      -- See (IB3)++    go credit (App f (Type {}))           = go credit f      -- See (IB3)+    go credit (App f (Coercion {}))+      | is_fun                            = go credit f      -- See (IB3)+      | otherwise                         = go (credit-1) f  -- See (IB4)+    go credit (App f a) | exprIsTrivial a = go (credit-1) f+     go credit (Case e b _ alts)       | null alts       = go credit e   -- EmptyCase is like e       | Just rhs <- isUnsafeEqualityCase e b alts       = go credit rhs -- See Note [Inline unsafeCoerce]-    go _      (Var {})                     = boringCxtOk-    go _      (Lit l)                      = litIsTrivial l && boringCxtOk-    go _      _                            = boringCxtNotOk +    go credit (Tick _ e) = go credit e      -- dubious+    go credit (Cast e _) = go credit e      -- See (IB3)++    -- Lit: we assume credit >= 0; literals aren't functions+    go _      (Lit l)    = litIsTrivial l && boringCxtOk++    go credit (Var v) | isDataConWorkId v, is_fun = boringCxtOk  -- See (IB2)+                      | isUnaryClassId v          = boringCxtOk  -- See (IB6)+                      | credit >= 0               = boringCxtOk+                      | otherwise                 = boringCxtNotOk++    go _ _ = boringCxtNotOk++isValFun :: CoreExpr -> Bool+-- True of functions with at least+-- one top-level value lambda+isValFun (Lam b e) | isRuntimeVar b = True+                   | otherwise      = isValFun e+isValFun _                          = False+ calcUnfoldingGuidance         :: UnfoldingOpts         -> Bool          -- Definitely a top-level, bottoming binding@@ -398,29 +491,6 @@     NB: you might think that PostInlineUnconditionally would do this     but it doesn't fire for top-level things; see GHC.Core.Opt.Simplify.Utils     Note [Top level and postInlineUnconditionally]--Note [Count coercion arguments in boring contexts]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-In inlineBoringOK, we ignore type arguments when deciding whether an-expression is okay to inline into boring contexts. This is good, since-if we have a definition like--  let y = x @Int in f y y--there’s no reason not to inline y at both use sites — no work is-actually duplicated. It may seem like the same reasoning applies to-coercion arguments, and indeed, in #17182 we changed inlineBoringOK to-treat coercions the same way.--However, this isn’t a good idea: unlike type arguments, which have-no runtime representation, coercion arguments *do* have a runtime-representation (albeit the zero-width VoidRep, see Note [Coercion tokens]-in "GHC.CoreToStg"). This caused trouble in #17787 for DataCon wrappers for-nullary GADT constructors: the wrappers would be inlined and each use of-the constructor would lead to a separate allocation instead of just-sharing the wrapper closure.--The solution: don’t ignore coercion arguments after all. -}  uncondInline :: Bool -> CoreExpr -> [Var] -> Arity -> CoreExpr -> Int -> Bool@@ -434,19 +504,57 @@  uncondInlineJoin :: [Var] -> CoreExpr -> Bool -- See Note [Duplicating join points] point (DJ3) in GHC.Core.Opt.Simplify.Iteration-uncondInlineJoin _bndrs body+uncondInlineJoin bndrs body++  -- (DJ3)(a)   | exprIsTrivial body   = True   -- Nullary constructors, literals -  | (Var v, args) <- collectArgs body-  , all exprIsTrivial args-  , isJoinId v   -- Indirection to another join point; always inline+  -- (DJ3)(b) and (DJ3)(c) combined+  | indirectionOrAppWithoutFVs   = True    | otherwise   = False +  where+    -- (DJ3)(b):+    -- - $j1 x = $j2 y x |> co  -- YES, inline indirection regardless of free vars+    -- (DJ3)(c):+    -- - $j1 x y = K y x |> co  -- YES, inline!+    -- - $j2 x = K f x          -- No, don't! (because f is free)+    indirectionOrAppWithoutFVs = go False body +    go !seen_fv (App f a)+      | Just has_fv <- go_arg a+                          = go (seen_fv || has_fv) f+      | otherwise         = False       -- Not trivial+    go seen_fv (Var v)+      | isJoinId v        = True        -- Indirection to another join point; always inline+      | isDataConId v     = not seen_fv -- e.g. $j a b = K a b+      | v `elem` bndrs    = not seen_fv -- e.g. $j a b = b a+    go seen_fv (Cast e _) = go seen_fv e+    go seen_fv (Tick _ e) = go seen_fv e+    go _ _                = False++    -- go_arg returns:+    --  - `Nothing` if arg is not trivial+    --  - `Just True` if arg is trivial but contains free var, literal, or constructor+    --  - `Just False` if arg is trivial without free vars+    go_arg (Type {})     = Just False+    go_arg (Coercion {}) = Just False+    go_arg (Lit l)+      | litIsTrivial l   = Just True    -- e.g. $j x = $j2 x 7 YES, but $j x = K x 7 NO+      | otherwise        = Nothing+    go_arg (App f a)+      | isTyCoArg a      = go_arg f     -- e.g. $j f = K (f @a)+      | otherwise        = Nothing+    go_arg (Cast e _)    = go_arg e+    go_arg (Tick _ e)    = go_arg e+    go_arg (Var f)       = Just $! f `notElem` bndrs+    go_arg _             = Nothing++ sizeExpr :: UnfoldingOpts          -> Int             -- Bomb out if it gets bigger than this          -> [Id]            -- Arguments; we're interested in which of these@@ -490,15 +598,12 @@               (size_up body `addSizeN` sum (map (size_up_alloc . fst) pairs))               pairs -    size_up (Case e _ _ alts)-        | null alts-        = size_up e    -- case e of {} never returns, so take size of scrutinee--    size_up (Case e _ _ alts)-        -- Now alts is non-empty-        | Just v <- is_top_arg e -- We are scrutinising an argument variable-        = let-            alt_sizes = map size_up_alt alts+    size_up (Case e _ _ alts) = case nonEmpty alts of+      Nothing -> size_up e    -- case e of {} never returns, so take size of scrutinee+      Just alts+        | Just v <- is_top_arg e -> -- We are scrutinising an argument variable+          let+            alt_sizes = NE.map size_up_alt alts                    -- alts_size tries to compute a good discount for                   -- the case when we are scrutinising an argument variable@@ -525,14 +630,15 @@                 -- Good to inline if an arg is scrutinised, because                 -- that may eliminate allocation in the caller                 -- And it eliminates the case itself++        | otherwise -> size_up e  `addSizeNSD`+                                foldr (addAltSize . size_up_alt) case_size alts+         where           is_top_arg (Var v) | v `elem` top_args = Just v           is_top_arg (Cast e _) = is_top_arg e           is_top_arg _ = Nothing --    size_up (Case e _ _ alts) = size_up e  `addSizeNSD`-                                foldr (addAltSize . size_up_alt) case_size alts       where           case_size            | is_inline_scrut e, lengthAtMost alts 1 = sizeN (-10)@@ -597,11 +703,13 @@     size_up_call :: Id -> [CoreExpr] -> Int -> ExprSize     size_up_call fun val_args voids        = case idDetails fun of-           FCallId _        -> sizeN (callSize (length val_args) voids)-           DataConWorkId dc -> conSize    dc (length val_args)-           PrimOpId op _    -> primOpSize op (length val_args)-           ClassOpId {}     -> classOpSize opts top_args val_args-           _                -> funSize opts top_args fun (length val_args) voids+           FCallId _                     -> sizeN (callSize (length val_args) voids)+           DataConWorkId dc              -> conSize    dc (length val_args)+           PrimOpId op _                 -> primOpSize op (length val_args)+           ClassOpId cls _               -> classOpSize opts cls top_args val_args+           _ | fun `hasKey` buildIdKey   -> buildSize+             | fun `hasKey` augmentIdKey -> augmentSize+             | otherwise                 -> funSize opts top_args fun (length val_args) voids      ------------     size_up_alt (Alt _con _bndrs rhs) = size_up rhs `addSizeN` 10@@ -666,21 +774,24 @@                       -- Key point: if  x |-> 4, then x must inline unconditionally                       --            (eg via case binding) -classOpSize :: UnfoldingOpts -> [Id] -> [CoreExpr] -> ExprSize+classOpSize :: UnfoldingOpts -> Class -> [Id] -> [CoreExpr] -> ExprSize -- See Note [Conlike is interesting]-classOpSize _ _ []-  = sizeZero-classOpSize opts top_args (arg1 : other_args)-  = SizeIs size arg_discount 0+classOpSize opts cls top_args args+  | isUnaryClass cls+  = sizeZero   -- See (UCM4) in Note [Unary class magic] in GHC.Core.TyCon+  | otherwise+  = case args of+       []                -> sizeZero+       (arg1:other_args) -> SizeIs (size other_args) (arg_discount arg1) 0   where-    size = 20 + (10 * length other_args)+    size other_args = 20 + (10 * length other_args)+     -- If the class op is scrutinising a lambda bound dictionary then     -- give it a discount, to encourage the inlining of this function     -- The actual discount is rather arbitrarily chosen-    arg_discount = case arg1 of-                     Var dict | dict `elem` top_args-                              -> unitBag (dict, unfoldingDictDiscount opts)-                     _other   -> emptyBag+    arg_discount (Var dict) | dict `elem` top_args+                   = unitBag (dict, unfoldingDictDiscount opts)+    arg_discount _ = emptyBag  -- | The size of a function call callSize@@ -707,11 +818,9 @@   -- better solution?  funSize :: UnfoldingOpts -> [Id] -> Id -> Int -> Int -> ExprSize--- Size for functions that are not constructors or primops+-- Size for function calls where the function is not a constructor or primops -- Note [Function applications] funSize opts top_args fun n_val_args voids-  | fun `hasKey` buildIdKey   = buildSize-  | fun `hasKey` augmentIdKey = augmentSize   | otherwise = SizeIs size arg_discount res_discount   where     some_val_args = n_val_args > 0@@ -740,6 +849,8 @@  -- See Note [Unboxed tuple size and result discount]   | isUnboxedTupleDataCon dc = SizeIs 0 emptyBag 10++  | isUnaryClassDataCon dc = sizeZero  -- See Note [Constructor size and result discount]   | otherwise = SizeIs 10 emptyBag 10
GHC/Core/Unfold/Make.hs view
@@ -84,6 +84,16 @@  mkDFunUnfolding :: [Var] -> DataCon -> [CoreExpr] -> Unfolding mkDFunUnfolding bndrs con ops+  | isUnaryClassDataCon con+  = -- See (UCM5) in Note [Unary class magic] in GHC.Core.TyCon+    mkDataConUnfolding $+    mkLams bndrs  $+    mkApps (Var (dataConWrapId con)) ops+                -- This application will satisfy the Core invariants+                -- from Note [Representation polymorphism invariants] in GHC.Core,+                -- because typeclass method types are never unlifted.++  | otherwise   = DFunUnfolding { df_bndrs = bndrs                   , df_con = con                   , df_args = map occurAnalyseExpr ops }@@ -97,7 +107,10 @@   where     guide = UnfWhen { ug_arity     = manifestArity expr                     , ug_unsat_ok  = unSaturatedOk-                    , ug_boring_ok = False }+                    , ug_boring_ok = inlineBoringOk expr }+            -- inineBoringOk; sometimes wrappers are very simple, like+            --    \@a p q. K @a <coercion> p q+            -- and then we definitely want to inline it #25713  mkWrapperUnfolding :: SimpleOpts -> CoreExpr -> Arity -> Unfolding -- Make the unfolding for the wrapper in a worker/wrapper split@@ -184,6 +197,9 @@                    spec_app (mkLams old_bndrs arg)                    -- The beta-redexes created by spec_app will be                    -- simplified away by simplOptExpr+                   -- ToDo: this is VERY DELICATE for type args.  We make+                   --        (\@a @b x y. TYPE ty) ty1 ty2 d1 d2+                   -- and rely on it simplifying to ty[ty1/a, ty2/b]  specUnfolding opts spec_bndrs spec_app rule_lhs_args               (CoreUnfolding { uf_src = src, uf_tmpl = tmpl
GHC/Core/Unify.hs view
@@ -11,2201 +11,2531 @@         tcMatchTyX_BM, ruleMatchTyKiX,          -- Side-effect free unification-        tcUnifyTy, tcUnifyTyKi, tcUnifyTys, tcUnifyTyKis,-        tcUnifyTysFG, tcUnifyTyWithTFs,-        BindFun, BindFlag(..), matchBindFun, alwaysBindFun,-        UnifyResult, UnifyResultM(..), MaybeApartReason(..),-        typesCantMatch, typesAreApart,--        -- Matching a type against a lifted type (coercion)-        liftCoMatch,--        -- The core flattening algorithm-        flattenTys, flattenTysX,--   ) where--import GHC.Prelude--import GHC.Types.Var-import GHC.Types.Var.Env-import GHC.Types.Var.Set-import GHC.Types.Name( Name, mkSysTvName, mkSystemVarName )-import GHC.Builtin.Names( tYPETyConKey, cONSTRAINTTyConKey )-import GHC.Core.Type     hiding ( getTvSubstEnv )-import GHC.Core.Coercion hiding ( getCvSubstEnv )-import GHC.Core.TyCon-import GHC.Core.TyCo.Rep-import GHC.Core.TyCo.Compare ( eqType, tcEqType )-import GHC.Core.TyCo.FVs     ( tyCoVarsOfCoList, tyCoFVsOfTypes )-import GHC.Core.TyCo.Subst   ( mkTvSubst, emptyIdSubstEnv )-import GHC.Core.Map.Type-import GHC.Utils.FV( FV, fvVarList )-import GHC.Utils.Misc-import GHC.Data.Pair-import GHC.Utils.Outputable-import GHC.Types.Unique-import GHC.Types.Unique.FM-import GHC.Types.Unique.Set-import GHC.Exts( oneShot )-import GHC.Utils.Panic-import GHC.Data.FastString--import Data.List ( mapAccumL )-import Control.Monad-import qualified Data.Semigroup as S-import GHC.Builtin.Types.Prim (fUNTyCon)-import GHC.Core.Multiplicity--{---Unification is much tricker than you might think.--1. The substitution we generate binds the *template type variables*-   which are given to us explicitly.--2. We want to match in the presence of foralls;-        e.g     (forall a. t1) ~ (forall b. t2)--   That is what the RnEnv2 is for; it does the alpha-renaming-   that makes it as if a and b were the same variable.-   Initialising the RnEnv2, so that it can generate a fresh-   binder when necessary, entails knowing the free variables of-   both types.--3. We must be careful not to bind a template type variable to a-   locally bound variable.  E.g.-        (forall a. x) ~ (forall b. b)-   where x is the template type variable.  Then we do not want to-   bind x to a/b!  This is a kind of occurs check.-   The necessary locals accumulate in the RnEnv2.--Note [tcMatchTy vs tcMatchTyKi]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-This module offers two variants of matching: with kinds and without.-The TyKi variant takes two types, of potentially different kinds,-and matches them. Along the way, it necessarily also matches their-kinds. The Ty variant instead assumes that the kinds are already-eqType and so skips matching up the kinds.--How do you choose between them?--1. If you know that the kinds of the two types are eqType, use-   the Ty variant. It is more efficient, as it does less work.--2. If the kinds of variables in the template type might mention type families,-   use the Ty variant (and do other work to make sure the kinds-   work out). These pure unification functions do a straightforward-   syntactic unification and do no complex reasoning about type-   families. Note that the types of the variables in instances can indeed-   mention type families, so instance lookup must use the Ty variant.--   (Nothing goes terribly wrong -- no panics -- if there might be type-   families in kinds in the TyKi variant. You just might get match-   failure even though a reducing a type family would lead to success.)--3. Otherwise, if you're sure that the variable kinds do not mention-   type families and you're not already sure that the kind of the template-   equals the kind of the target, then use the TyKi version.--}---- | Some unification functions are parameterised by a 'BindFun', which--- says whether or not to allow a certain unification to take place.--- A 'BindFun' takes the 'TyVar' involved along with the 'Type' it will--- potentially be bound to.------ It is possible for the variable to actually be a coercion variable--- (Note [Matching coercion variables]), but only when one-way matching.--- In this case, the 'Type' will be a 'CoercionTy'.-type BindFun = TyCoVar -> Type -> BindFlag---- | @tcMatchTy t1 t2@ produces a substitution (over fvs(t1))--- @s@ such that @s(t1)@ equals @t2@.--- The returned substitution might bind coercion variables,--- if the variable is an argument to a GADT constructor.------ Precondition: typeKind ty1 `eqType` typeKind ty2------ We don't pass in a set of "template variables" to be bound--- by the match, because tcMatchTy (and similar functions) are--- always used on top-level types, so we can bind any of the--- free variables of the LHS.--- See also Note [tcMatchTy vs tcMatchTyKi]-tcMatchTy :: Type -> Type -> Maybe Subst-tcMatchTy ty1 ty2 = tcMatchTys [ty1] [ty2]--tcMatchTyX_BM :: BindFun -> Subst-              -> Type -> Type -> Maybe Subst-tcMatchTyX_BM bind_me subst ty1 ty2-  = tc_match_tys_x bind_me False subst [ty1] [ty2]---- | Like 'tcMatchTy', but allows the kinds of the types to differ,--- and thus matches them as well.--- See also Note [tcMatchTy vs tcMatchTyKi]-tcMatchTyKi :: Type -> Type -> Maybe Subst-tcMatchTyKi ty1 ty2-  = tc_match_tys alwaysBindFun True [ty1] [ty2]---- | This is similar to 'tcMatchTy', but extends a substitution--- See also Note [tcMatchTy vs tcMatchTyKi]-tcMatchTyX :: Subst            -- ^ Substitution to extend-           -> Type                -- ^ Template-           -> Type                -- ^ Target-           -> Maybe Subst-tcMatchTyX subst ty1 ty2-  = tc_match_tys_x alwaysBindFun False subst [ty1] [ty2]---- | Like 'tcMatchTy' but over a list of types.--- See also Note [tcMatchTy vs tcMatchTyKi]-tcMatchTys :: [Type]         -- ^ Template-           -> [Type]         -- ^ Target-           -> Maybe Subst    -- ^ One-shot; in principle the template-                             -- variables could be free in the target-tcMatchTys tys1 tys2-  = tc_match_tys alwaysBindFun False tys1 tys2---- | Like 'tcMatchTyKi' but over a list of types.--- See also Note [tcMatchTy vs tcMatchTyKi]-tcMatchTyKis :: [Type]         -- ^ Template-             -> [Type]         -- ^ Target-             -> Maybe Subst -- ^ One-shot substitution-tcMatchTyKis tys1 tys2-  = tc_match_tys alwaysBindFun True tys1 tys2---- | Like 'tcMatchTys', but extending a substitution--- See also Note [tcMatchTy vs tcMatchTyKi]-tcMatchTysX :: Subst       -- ^ Substitution to extend-            -> [Type]         -- ^ Template-            -> [Type]         -- ^ Target-            -> Maybe Subst -- ^ One-shot substitution-tcMatchTysX subst tys1 tys2-  = tc_match_tys_x alwaysBindFun False subst tys1 tys2---- | Like 'tcMatchTyKis', but extending a substitution--- See also Note [tcMatchTy vs tcMatchTyKi]-tcMatchTyKisX :: Subst        -- ^ Substitution to extend-              -> [Type]          -- ^ Template-              -> [Type]          -- ^ Target-              -> Maybe Subst  -- ^ One-shot substitution-tcMatchTyKisX subst tys1 tys2-  = tc_match_tys_x alwaysBindFun True subst tys1 tys2---- | Same as tc_match_tys_x, but starts with an empty substitution-tc_match_tys :: BindFun-             -> Bool          -- ^ match kinds?-             -> [Type]-             -> [Type]-             -> Maybe Subst-tc_match_tys bind_me match_kis tys1 tys2-  = tc_match_tys_x bind_me match_kis (mkEmptySubst in_scope) tys1 tys2-  where-    in_scope = mkInScopeSet (tyCoVarsOfTypes tys1 `unionVarSet` tyCoVarsOfTypes tys2)---- | Worker for 'tcMatchTysX' and 'tcMatchTyKisX'-tc_match_tys_x :: BindFun-               -> Bool          -- ^ match kinds?-               -> Subst-               -> [Type]-               -> [Type]-               -> Maybe Subst-tc_match_tys_x bind_me match_kis (Subst in_scope id_env tv_env cv_env) tys1 tys2-  = case tc_unify_tys bind_me-                      False  -- Matching, not unifying-                      False  -- Not an injectivity check-                      match_kis-                      RespectMultiplicities-                      (mkRnEnv2 in_scope) tv_env cv_env tys1 tys2 of-      Unifiable (tv_env', cv_env')-        -> Just $ Subst in_scope id_env tv_env' cv_env'-      _ -> Nothing---- | This one is called from the expression matcher,--- which already has a MatchEnv in hand-ruleMatchTyKiX-  :: TyCoVarSet          -- ^ template variables-  -> RnEnv2-  -> TvSubstEnv          -- ^ type substitution to extend-  -> Type                -- ^ Template-  -> Type                -- ^ Target-  -> Maybe TvSubstEnv-ruleMatchTyKiX tmpl_tvs rn_env tenv tmpl target--- See Note [Kind coercions in Unify]-  = case tc_unify_tys (matchBindFun tmpl_tvs) False False-                      True -- <-- this means to match the kinds-                      IgnoreMultiplicities-                        -- See Note [Rewrite rules ignore multiplicities in FunTy]-                      rn_env tenv emptyCvSubstEnv [tmpl] [target] of-      Unifiable (tenv', _) -> Just tenv'-      _                    -> Nothing---- | Allow binding only for any variable in the set. Variables may--- be bound to any type.--- Used when doing simple matching; e.g. can we find a substitution------ @--- S = [a :-> t1, b :-> t2] such that---     S( Maybe (a, b->Int )  =   Maybe (Bool, Char -> Int)--- @-matchBindFun :: TyCoVarSet -> BindFun-matchBindFun tvs tv _ty-  | tv `elemVarSet` tvs = BindMe-  | otherwise           = Apart---- | Allow the binding of any variable to any type-alwaysBindFun :: BindFun-alwaysBindFun _tv _ty = BindMe--{--************************************************************************-*                                                                      *-                GADTs-*                                                                      *-************************************************************************--Note [Pruning dead case alternatives]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-Consider        data T a where-                   T1 :: T Int-                   T2 :: T a--                newtype X = MkX Int-                newtype Y = MkY Char--                type family F a-                type instance F Bool = Int--Now consider    case x of { T1 -> e1; T2 -> e2 }--The question before the house is this: if I know something about the type-of x, can I prune away the T1 alternative?--Suppose x::T Char.  It's impossible to construct a (T Char) using T1,-        Answer = YES we can prune the T1 branch (clearly)--Suppose x::T (F a), where 'a' is in scope.  Then 'a' might be instantiated-to 'Bool', in which case x::T Int, so-        ANSWER = NO (clearly)--We see here that we want precisely the apartness check implemented within-tcUnifyTysFG. So that's what we do! Two types cannot match if they are surely-apart. Note that since we are simply dropping dead code, a conservative test-suffices.--}---- | Given a list of pairs of types, are any two members of a pair surely--- apart, even after arbitrary type function evaluation and substitution?-typesCantMatch :: [(Type,Type)] -> Bool--- See Note [Pruning dead case alternatives]-typesCantMatch prs = any (uncurry typesAreApart) prs--typesAreApart :: Type -> Type -> Bool-typesAreApart t1 t2 = case tcUnifyTysFG alwaysBindFun [t1] [t2] of-                        SurelyApart -> True-                        _           -> False-{--************************************************************************-*                                                                      *-             Unification-*                                                                      *-************************************************************************--Note [Fine-grained unification]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-Do the types (x, x) and ([y], y) unify? The answer is seemingly "no" ---no substitution to finite types makes these match. But, a substitution to-*infinite* types can unify these two types: [x |-> [[[...]]], y |-> [[[...]]] ].-Why do we care? Consider these two type family instances:--type instance F x x   = Int-type instance F [y] y = Bool--If we also have--type instance Looper = [Looper]--then the instances potentially overlap. The solution is to use unification-over infinite terms. This is possible (see [1] for lots of gory details), but-a full algorithm is a little more power than we need. Instead, we make a-conservative approximation and just omit the occurs check.--[1]: http://research.microsoft.com/en-us/um/people/simonpj/papers/ext-f/axioms-extended.pdf--tcUnifyTys considers an occurs-check problem as the same as general unification-failure.--tcUnifyTysFG ("fine-grained") returns one of three results: success, occurs-check-failure ("MaybeApart"), or general failure ("SurelyApart").--See also #8162.--It's worth noting that unification in the presence of infinite types is not-complete. This means that, sometimes, a closed type family does not reduce-when it should. See test case indexed-types/should_fail/Overlap15 for an-example.--Note [Unification result]-~~~~~~~~~~~~~~~~~~~~~~~~~-When unifying t1 ~ t2, we return-* Unifiable s, if s is a substitution such that s(t1) is syntactically the-  same as s(t2), modulo type-synonym expansion.-* SurelyApart, if there is no substitution s such that s(t1) = s(t2),-  where "=" includes type-family reductions.-* MaybeApart mar s, when we aren't sure. `mar` is a MaybeApartReason.--Examples-* [a] ~ Maybe b: SurelyApart, because [] and Maybe can't unify-* [(a,Int)] ~ [(Bool,b)]:  Unifiable-* [F Int] ~ [Bool]: MaybeApart MARTypeFamily, because F Int might reduce to Bool (the unifier-                    does not try this)-* a ~ Maybe a: MaybeApart MARInfinite. Not Unifiable clearly, but not SurelyApart either; consider-       a := Loop-       where  type family Loop where Loop = Maybe Loop--There is the possibility that two types are MaybeApart for *both* reasons:--* (a, F Int) ~ (Maybe a, Bool)--What reason should we use? The *only* consumer of the reason is described-in Note [Infinitary substitution in lookup] in GHC.Core.InstEnv. The goal-there is identify which instances might match a target later (but don't-match now) -- except that we want to ignore the possibility of infinitary-substitutions. So let's examine a concrete scenario:--  class C a b c-  instance C a (Maybe a) Bool-  -- other instances, including one that will actually match-  [W] C b b (F Int)--Do we want the instance as a future possibility? No. The only way that-instance can match is in the presence of an infinite type (infinitely-nested Maybes). We thus say that MARInfinite takes precedence, so that-InstEnv treats this case as an infinitary substitution case; the fact-that a type family is involved is only incidental. We thus define-the Semigroup instance for MaybeApartReason to prefer MARInfinite.--Note [The substitution in MaybeApart]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-The constructor MaybeApart carries data with it, typically a TvSubstEnv. Why?-Because consider unifying these:--(a, a, Int) ~ (b, [b], Bool)--If we go left-to-right, we start with [a |-> b]. Then, on the middle terms, we-apply the subst we have so far and discover that we need [b |-> [b]]. Because-this fails the occurs check, we say that the types are MaybeApart (see above-Note [Fine-grained unification]). But, we can't stop there! Because if we-continue, we discover that Int is SurelyApart from Bool, and therefore the-types are apart. This has practical consequences for the ability for closed-type family applications to reduce. See test case-indexed-types/should_compile/Overlap14.--Note [Rewrite rules ignore multiplicities in FunTy]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-Consider the following (higher-order) rule:--m :: Bool -> Bool -> Bool-{-# RULES "m" forall f. m (f True) = f #-}--let x = m ((,) @Bool @Bool True True)--The rewrite rule expects an `f :: Bool -> Bool`, but `(,) @Bool @Bool True ::-Bool %1 -> Bool` is linear (see Note [Data constructors are linear by default]-in GHC.Core.Multiplicity) Should the rule match? Yes! According to the-principles laid out in Note [Linting linearity] in GHC.Core.Lint, optimisation-shouldn't be constrained by linearity.--However, when matching the template variable `f` to `(,) True`, we do check that-their types unify (see Note [Matching variable types] in GHC.Core.Rules). So-when unifying types for the sake of rule-matching, the unification algorithm-must be able to ignore multiplicities altogether.--How is this done?-  (1) The `um_arr_mult` field of `UMEnv` recordsw when we are doing rule-matching,-      and hence want to ignore multiplicities.-  (2) The field is set to True in by `ruleMatchTyKiX`.-  (3) It is consulted when matching `FunTy` in `unify_ty`.--Wrinkle in (3). In `unify_tc_app`, in `unify_ty`, `FunTy` is handled as if it-was a regular type constructor. In this case, and when the types being unified-are *function* arrows, but not constraint arrows, then the first argument is a-multiplicity.--We select this situation by comparing the type constructor with fUNTyCon. In-this case, and this case only, we can safely drop the first argument (using the-tail function) and unify the rest.--}---- | Simple unification of two types; all type variables are bindable--- Precondition: the kinds are already equal-tcUnifyTy :: Type -> Type       -- All tyvars are bindable-          -> Maybe Subst-                       -- A regular one-shot (idempotent) substitution-tcUnifyTy t1 t2 = tcUnifyTys alwaysBindFun [t1] [t2]---- | Like 'tcUnifyTy', but also unifies the kinds-tcUnifyTyKi :: Type -> Type -> Maybe Subst-tcUnifyTyKi t1 t2 = tcUnifyTyKis alwaysBindFun [t1] [t2]---- | Unify two types, treating type family applications as possibly unifying--- with anything and looking through injective type family applications.--- Precondition: kinds are the same-tcUnifyTyWithTFs :: Bool  -- ^ True <=> do two-way unification;-                          --   False <=> do one-way matching.-                          --   See end of sec 5.2 from the paper-                 -> InScopeSet     -- Should include the free tyvars of both Type args-                 -> Type -> Type   -- Types to unify-                 -> Maybe Subst--- This algorithm is an implementation of the "Algorithm U" presented in--- the paper "Injective type families for Haskell", Figures 2 and 3.--- The code is incorporated with the standard unifier for convenience, but--- its operation should match the specification in the paper.-tcUnifyTyWithTFs twoWay in_scope t1 t2-  = case tc_unify_tys alwaysBindFun twoWay True False RespectMultiplicities-                       rn_env emptyTvSubstEnv emptyCvSubstEnv-                       [t1] [t2] of-      Unifiable          (tv_subst, _cv_subst) -> Just $ maybe_fix tv_subst-      MaybeApart _reason (tv_subst, _cv_subst) -> Just $ maybe_fix tv_subst-      -- we want to *succeed* in questionable cases. This is a-      -- pre-unification algorithm.-      SurelyApart      -> Nothing-  where-    rn_env   = mkRnEnv2 in_scope--    maybe_fix | twoWay    = niFixSubst in_scope-              | otherwise = mkTvSubst in_scope -- when matching, don't confuse-                                               -- domain with range--------------------tcUnifyTys :: BindFun-           -> [Type] -> [Type]-           -> Maybe Subst-                                -- ^ A regular one-shot (idempotent) substitution-                                -- that unifies the erased types. See comments-                                -- for 'tcUnifyTysFG'---- The two types may have common type variables, and indeed do so in the--- second call to tcUnifyTys in GHC.Tc.Instance.FunDeps.checkClsFD-tcUnifyTys bind_fn tys1 tys2-  = case tcUnifyTysFG bind_fn tys1 tys2 of-      Unifiable result -> Just result-      _                -> Nothing---- | Like 'tcUnifyTys' but also unifies the kinds-tcUnifyTyKis :: BindFun-             -> [Type] -> [Type]-             -> Maybe Subst-tcUnifyTyKis bind_fn tys1 tys2-  = case tcUnifyTyKisFG bind_fn tys1 tys2 of-      Unifiable result -> Just result-      _                -> Nothing---- This type does double-duty. It is used in the UM (unifier monad) and to--- return the final result. See Note [Fine-grained unification]-type UnifyResult = UnifyResultM Subst---- | See Note [Unification result]-data UnifyResultM a = Unifiable a        -- the subst that unifies the types-                    | MaybeApart MaybeApartReason-                                 a       -- the subst has as much as we know-                                         -- it must be part of a most general unifier-                                         -- See Note [The substitution in MaybeApart]-                    | SurelyApart-                    deriving Functor---- | Why are two types 'MaybeApart'? 'MARInfinite' takes precedence:--- This is used (only) in Note [Infinitary substitution in lookup] in GHC.Core.InstEnv--- As of Feb 2022, we never differentiate between MARTypeFamily and MARTypeVsConstraint;--- it's really only MARInfinite that's interesting here.-data MaybeApartReason-  = MARTypeFamily   -- ^ matching e.g. F Int ~? Bool--  | MARInfinite     -- ^ matching e.g. a ~? Maybe a--  | MARTypeVsConstraint  -- ^ matching Type ~? Constraint or the arrow types-    -- See Note [Type and Constraint are not apart] in GHC.Builtin.Types.Prim--instance Outputable MaybeApartReason where-  ppr MARTypeFamily       = text "MARTypeFamily"-  ppr MARInfinite         = text "MARInfinite"-  ppr MARTypeVsConstraint = text "MARTypeVsConstraint"--instance Semigroup MaybeApartReason where-  -- see end of Note [Unification result] for why-  MARTypeFamily       <> r = r-  MARInfinite         <> _ = MARInfinite-  MARTypeVsConstraint <> r = r--instance Applicative UnifyResultM where-  pure  = Unifiable-  (<*>) = ap--instance Monad UnifyResultM where-  SurelyApart  >>= _ = SurelyApart-  MaybeApart r1 x >>= f = case f x of-                            Unifiable y     -> MaybeApart r1 y-                            MaybeApart r2 y -> MaybeApart (r1 S.<> r2) y-                            SurelyApart     -> SurelyApart-  Unifiable x  >>= f = f x---- | @tcUnifyTysFG bind_tv tys1 tys2@ attempts to find a substitution @s@ (whose--- domain elements all respond 'BindMe' to @bind_tv@) such that--- @s(tys1)@ and that of @s(tys2)@ are equal, as witnessed by the returned--- Coercions. This version requires that the kinds of the types are the same,--- if you unify left-to-right.-tcUnifyTysFG :: BindFun-             -> [Type] -> [Type]-             -> UnifyResult-tcUnifyTysFG bind_fn tys1 tys2-  = tc_unify_tys_fg False bind_fn tys1 tys2--tcUnifyTyKisFG :: BindFun-               -> [Type] -> [Type]-               -> UnifyResult-tcUnifyTyKisFG bind_fn tys1 tys2-  = tc_unify_tys_fg True bind_fn tys1 tys2--tc_unify_tys_fg :: Bool-                -> BindFun-                -> [Type] -> [Type]-                -> UnifyResult-tc_unify_tys_fg match_kis bind_fn tys1 tys2-  = do { (env, _) <- tc_unify_tys bind_fn True False match_kis RespectMultiplicities rn_env-                                  emptyTvSubstEnv emptyCvSubstEnv-                                  tys1 tys2-       ; return $ niFixSubst in_scope env }-  where-    in_scope = mkInScopeSet $ tyCoVarsOfTypes tys1 `unionVarSet` tyCoVarsOfTypes tys2-    rn_env   = mkRnEnv2 in_scope---- | This function is actually the one to call the unifier -- a little--- too general for outside clients, though.-tc_unify_tys :: BindFun-             -> AmIUnifying -- ^ True <=> unify; False <=> match-             -> Bool        -- ^ True <=> doing an injectivity check-             -> Bool        -- ^ True <=> treat the kinds as well-             -> MultiplicityFlag -- ^ see Note [Rewrite rules ignore multiplicities in FunTy] in GHC.Core.Unify-             -> RnEnv2-             -> TvSubstEnv  -- ^ substitution to extend-             -> CvSubstEnv-             -> [Type] -> [Type]-             -> UnifyResultM (TvSubstEnv, CvSubstEnv)--- NB: It's tempting to ASSERT here that, if we're not matching kinds, then--- the kinds of the types should be the same. However, this doesn't work,--- as the types may be a dependent telescope, where later types have kinds--- that mention variables occurring earlier in the list of types. Here's an--- example (from typecheck/should_fail/T12709):---   template: [rep :: RuntimeRep,       a :: TYPE rep]---   target:   [LiftedRep :: RuntimeRep, Int :: TYPE LiftedRep]--- We can see that matching the first pair will make the kinds of the second--- pair equal. Yet, we still don't need a separate pass to unify the kinds--- of these types, so it's appropriate to use the Ty variant of unification.--- See also Note [tcMatchTy vs tcMatchTyKi].-tc_unify_tys bind_fn unif inj_check match_kis match_mults rn_env tv_env cv_env tys1 tys2-  = initUM tv_env cv_env $-    do { when match_kis $-         unify_tys env kis1 kis2-       ; unify_tys env tys1 tys2-       ; (,) <$> getTvSubstEnv <*> getCvSubstEnv }-  where-    env = UMEnv { um_bind_fun = bind_fn-                , um_skols    = emptyVarSet-                , um_unif     = unif-                , um_inj_tf   = inj_check-                , um_arr_mult = match_mults-                , um_rn_env   = rn_env }--    kis1 = map typeKind tys1-    kis2 = map typeKind tys2--instance Outputable a => Outputable (UnifyResultM a) where-  ppr SurelyApart      = text "SurelyApart"-  ppr (Unifiable x)    = text "Unifiable" <+> ppr x-  ppr (MaybeApart r x) = text "MaybeApart" <+> ppr r <+> ppr x--{--************************************************************************-*                                                                      *-                Non-idempotent substitution-*                                                                      *-************************************************************************--Note [Non-idempotent substitution]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-During unification we use a TvSubstEnv/CvSubstEnv pair that is-  (a) non-idempotent-  (b) loop-free; ie repeatedly applying it yields a fixed point--Note [Finding the substitution fixpoint]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-Finding the fixpoint of a non-idempotent substitution arising from a-unification is much trickier than it looks, because of kinds.  Consider-   T k (H k (f:k)) ~ T * (g:*)-If we unify, we get the substitution-   [ k -> *-   , g -> H k (f:k) ]-To make it idempotent we don't want to get just-   [ k -> *-   , g -> H * (f:k) ]-We also want to substitute inside f's kind, to get-   [ k -> *-   , g -> H k (f:*) ]-If we don't do this, we may apply the substitution to something,-and get an ill-formed type, i.e. one where typeKind will fail.-This happened, for example, in #9106.--It gets worse.  In #14164 we wanted to take the fixpoint of-this substitution-   [ xs_asV :-> F a_aY6 (z_aY7 :: a_aY6)-                        (rest_aWF :: G a_aY6 (z_aY7 :: a_aY6))-   , a_aY6  :-> a_aXQ ]--We have to apply the substitution for a_aY6 two levels deep inside-the invocation of F!  We don't have a function that recursively-applies substitutions inside the kinds of variable occurrences (and-probably rightly so).--So, we work as follows:-- 1. Start with the current substitution (which we are-    trying to fixpoint-       [ xs :-> F a (z :: a) (rest :: G a (z :: a))-       , a  :-> b ]-- 2. Take all the free vars of the range of the substitution:-       {a, z, rest, b}-    NB: the free variable finder closes over-    the kinds of variable occurrences-- 3. If none are in the domain of the substitution, stop.-    We have found a fixpoint.-- 4. Remove the variables that are bound by the substitution, leaving-       {z, rest, b}-- 5. Do a topo-sort to put them in dependency order:-       [ b :: *, z :: a, rest :: G a z ]-- 6. Apply the substitution left-to-right to the kinds of these-    tyvars, extending it each time with a new binding, so we-    finish up with-       [ xs   :-> ..as before..-       , a    :-> b-       , b    :-> b    :: *-       , z    :-> z    :: b-       , rest :-> rest :: G b (z :: b) ]-    Note that rest now has the right kind-- 7. Apply this extended substitution (once) to the range of-    the /original/ substitution.  (Note that we do the-    extended substitution would go on forever if you tried-    to find its fixpoint, because it maps z to z.)-- 8. And go back to step 1--In Step 6 we use the free vars from Step 2 as the initial-in-scope set, because all of those variables appear in the-range of the substitution, so they must all be in the in-scope-set.  But NB that the type substitution engine does not look up-variables in the in-scope set; it is used only to ensure no-shadowing.--}--niFixSubst :: InScopeSet -> TvSubstEnv -> Subst--- Find the idempotent fixed point of the non-idempotent substitution--- This is surprisingly tricky:---   see Note [Finding the substitution fixpoint]--- ToDo: use laziness instead of iteration?-niFixSubst in_scope tenv-  | not_fixpoint = niFixSubst in_scope (mapVarEnv (substTy subst) tenv)-  | otherwise    = subst-  where-    range_fvs :: FV-    range_fvs = tyCoFVsOfTypes (nonDetEltsUFM tenv)-          -- It's OK to use nonDetEltsUFM here because the-          -- order of range_fvs, range_tvs is immaterial--    range_tvs :: [TyVar]-    range_tvs = fvVarList range_fvs--    not_fixpoint  = any in_domain range_tvs-    in_domain tv  = tv `elemVarEnv` tenv--    free_tvs = scopedSort (filterOut in_domain range_tvs)--    -- See Note [Finding the substitution fixpoint], Step 6-    subst = foldl' add_free_tv-                  (mkTvSubst in_scope tenv)-                  free_tvs--    add_free_tv :: Subst -> TyVar -> Subst-    add_free_tv subst tv-      = extendTvSubst subst tv (mkTyVarTy tv')-     where-        tv' = updateTyVarKind (substTy subst) tv--niSubstTvSet :: TvSubstEnv -> TyCoVarSet -> TyCoVarSet--- Apply the non-idempotent substitution to a set of type variables,--- remembering that the substitution isn't necessarily idempotent--- This is used in the occurs check, before extending the substitution-niSubstTvSet tsubst tvs-  = nonDetStrictFoldUniqSet (unionVarSet . get) emptyVarSet tvs-  -- It's OK to use a non-deterministic fold here because we immediately forget-  -- the ordering by creating a set.-  where-    get tv-      | Just ty <- lookupVarEnv tsubst tv-      = niSubstTvSet tsubst (tyCoVarsOfType ty)--      | otherwise-      = unitVarSet tv--{--************************************************************************-*                                                                      *-                unify_ty: the main workhorse-*                                                                      *-************************************************************************--Note [Specification of unification]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-The pure unifier, unify_ty, defined in this module, tries to work out-a substitution to make two types say True to eqType. NB: eqType is-itself not purely syntactic; it accounts for CastTys;-see Note [Non-trivial definitional equality] in GHC.Core.TyCo.Rep--Unlike the "impure unifiers" in the typechecker (the eager unifier in-GHC.Tc.Utils.Unify, and the constraint solver itself in GHC.Tc.Solver.Equality),-the pure unifier does /not/ work up to ~.--The algorithm implemented here is rather delicate, and we depend on it-to uphold certain properties. This is a summary of these required-properties.--Notation:- θ,φ  substitutions- ξ    type-function-free types- τ,σ  other types- τ♭   type τ, flattened-- ≡    eqType--(U1) Soundness.-     If (unify τ₁ τ₂) = Unifiable θ, then θ(τ₁) ≡ θ(τ₂).-     θ is a most general unifier for τ₁ and τ₂.--(U2) Completeness.-     If (unify ξ₁ ξ₂) = SurelyApart,-     then there exists no substitution θ such that θ(ξ₁) ≡ θ(ξ₂).--These two properties are stated as Property 11 in the "Closed Type Families"-paper (POPL'14). Below, this paper is called [CTF].--(U3) Apartness under substitution.-     If (unify ξ τ♭) = SurelyApart, then (unify ξ θ(τ)♭) = SurelyApart,-     for any θ. (Property 12 from [CTF])--(U4) Apart types do not unify.-     If (unify ξ τ♭) = SurelyApart, then there exists no θ-     such that θ(ξ) = θ(τ). (Property 13 from [CTF])--THEOREM. Completeness w.r.t ~-    If (unify τ₁♭ τ₂♭) = SurelyApart,-    then there exists no proof that (τ₁ ~ τ₂).--PROOF. See appendix of [CTF].---The unification algorithm is used for type family injectivity, as described-in the "Injective Type Families" paper (Haskell'15), called [ITF]. When run-in this mode, it has the following properties.--(I1) If (unify σ τ) = SurelyApart, then σ and τ are not unifiable, even-     after arbitrary type family reductions. Note that σ and τ are-     not flattened here.--(I2) If (unify σ τ) = MaybeApart θ, and if some-     φ exists such that φ(σ) ~ φ(τ), then φ extends θ.---Furthermore, the RULES matching algorithm requires this property,-but only when using this algorithm for matching:--(M1) If (match σ τ) succeeds with θ, then all matchable tyvars-     in σ are bound in θ.--     Property M1 means that we must extend the substitution with,-     say (a ↦ a) when appropriate during matching.-     See also Note [Self-substitution when matching].--(M2) Completeness of matching.-     If θ(σ) = τ, then (match σ τ) = Unifiable φ,-     where θ is an extension of φ.--Sadly, property M2 and I2 conflict. Consider--type family F1 a b where-  F1 Int    Bool   = Char-  F1 Double String = Char--Consider now two matching problems:--P1. match (F1 a Bool) (F1 Int Bool)-P2. match (F1 a Bool) (F1 Double String)--In case P1, we must find (a ↦ Int) to satisfy M2.-In case P2, we must /not/ find (a ↦ Double), in order to satisfy I2. (Note-that the correct mapping for I2 is (a ↦ Int). There is no way to discover-this, but we mustn't map a to anything else!)--We thus must parameterize the algorithm over whether it's being used-for an injectivity check (refrain from looking at non-injective arguments-to type families) or not (do indeed look at those arguments).  This is-implemented  by the um_inj_tf field of UMEnv.--(It's all a question of whether or not to include equation (7) from Fig. 2-of [ITF].)--This extra parameter is a bit fiddly, perhaps, but seemingly less so than-having two separate, almost-identical algorithms.--Note [Self-substitution when matching]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-What should happen when we're *matching* (not unifying) a1 with a1? We-should get a substitution [a1 |-> a1]. A successful match should map all-the template variables (except ones that disappear when expanding synonyms).-But when unifying, we don't want to do this, because we'll then fall into-a loop.--This arrangement affects the code in three places:- - If we're matching a refined template variable, don't recur. Instead, just-   check for equality. That is, if we know [a |-> Maybe a] and are matching-   (a ~? Maybe Int), we want to just fail.-- - Skip the occurs check when matching. This comes up in two places, because-   matching against variables is handled separately from matching against-   full-on types.--Note that this arrangement was provoked by a real failure, where the same-unique ended up in the template as in the target. (It was a rule firing when-compiling Data.List.NonEmpty.)--Note [Matching coercion variables]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-Consider this:--   type family F a--   data G a where-     MkG :: F a ~ Bool => G a--   type family Foo (x :: G a) :: F a-   type instance Foo MkG = False--We would like that to be accepted. For that to work, we need to introduce-a coercion variable on the left and then use it on the right. Accordingly,-at use sites of Foo, we need to be able to use matching to figure out the-value for the coercion. (See the desugared version:--   axFoo :: [a :: *, c :: F a ~ Bool]. Foo (MkG c) = False |> (sym c)--) We never want this action to happen during *unification* though, when-all bets are off.--Note [Kind coercions in Unify]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-We wish to match/unify while ignoring casts. But, we can't just ignore-them completely, or we'll end up with ill-kinded substitutions. For example,-say we're matching `a` with `ty |> co`. If we just drop the cast, we'll-return [a |-> ty], but `a` and `ty` might have different kinds. We can't-just match/unify their kinds, either, because this might gratuitously-fail. After all, `co` is the witness that the kinds are the same -- they-may look nothing alike.--So, we pass a kind coercion to the match/unify worker. This coercion witnesses-the equality between the substed kind of the left-hand type and the substed-kind of the right-hand type. Note that we do not unify kinds at the leaves-(as we did previously). We thus have--Hence: (Unification Kind Invariant)-------------------------------------In the call-     unify_ty ty1 ty2 kco-it must be that-     subst(kco) :: subst(kind(ty1)) ~N subst(kind(ty2))-where `subst` is the ambient substitution in the UM monad.  And in the call-     unify_tys tys1 tys2-(which has no kco), after we unify any prefix of tys1,tys2, the kinds of the-head of the remaining tys1,tys2 are identical after substitution.  This-implies, for example, that the kinds of the head of tys1,tys2 are identical-after substitution.--To get this coercion, we first have to match/unify-the kinds before looking at the types. Happily, we need look only one level-up, as all kinds are guaranteed to have kind *.--When we're working with type applications (either TyConApp or AppTy) we-need to worry about establishing INVARIANT, as the kinds of the function-& arguments aren't (necessarily) included in the kind of the result.-When unifying two TyConApps, this is easy, because the two TyCons are-the same. Their kinds are thus the same. As long as we unify left-to-right,-we'll be sure to unify types' kinds before the types themselves. (For example,-think about Proxy :: forall k. k -> *. Unifying the first args matches up-the kinds of the second args.)--For AppTy, we must unify the kinds of the functions, but once these are-unified, we can continue unifying arguments without worrying further about-kinds.--The interface to this module includes both "...Ty" functions and-"...TyKi" functions. The former assume that INVARIANT is already-established, either because the kinds are the same or because the-list of types being passed in are the well-typed arguments to some-type constructor (see two paragraphs above). The latter take a separate-pre-pass over the kinds to establish INVARIANT. Sometimes, it's important-not to take the second pass, as it caused #12442.--We thought, at one point, that this was all unnecessary: why should-casts be in types in the first place? But they are sometimes. In-dependent/should_compile/KindEqualities2, we see, for example the-constraint Num (Int |> (blah ; sym blah)).  We naturally want to find-a dictionary for that constraint, which requires dealing with-coercions in this manner.--Note [Matching in the presence of casts (1)]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-When matching, it is crucial that no variables from the template-end up in the range of the matching substitution (obviously!).-When unifying, that's not a constraint; instead we take the fixpoint-of the substitution at the end.--So what should we do with this, when matching?-   unify_ty (tmpl |> co) tgt kco--Previously, wrongly, we pushed 'co' in the (horrid) accumulating-'kco' argument like this:-   unify_ty (tmpl |> co) tgt kco-     = unify_ty tmpl tgt (kco ; co)--But that is obviously wrong because 'co' (from the template) ends-up in 'kco', which in turn ends up in the range of the substitution.--This all came up in #13910.  Because we match tycon arguments-left-to-right, the ambient substitution will already have a matching-substitution for any kinds; so there is an easy fix: just apply-the substitution-so-far to the coercion from the LHS.--Note that--* When matching, the first arg of unify_ty is always the template;-  we never swap round.--* The above argument is distressingly indirect. We seek a-  better way.--* One better way is to ensure that type patterns (the template-  in the matching process) have no casts.  See #14119.--Note [Matching in the presence of casts (2)]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-There is another wrinkle (#17395).  Suppose (T :: forall k. k -> Type)-and we are matching-   tcMatchTy (T k (a::k))  (T j (b::j))--Then we'll match k :-> j, as expected. But then in unify_tys-we invoke-   unify_tys env (a::k) (b::j) (Refl j)--Although we have unified k and j, it's very important that we put-(Refl j), /not/ (Refl k) as the fourth argument to unify_tys.-If we put (Refl k) we'd end up with the substitution-  a :-> b |> Refl k-which is bogus because one of the template variables, k,-appears in the range of the substitution.  Eek.--Similar care is needed in unify_ty_app.---Note [Polykinded tycon applications]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-Suppose  T :: forall k. Type -> K-and we are unifying-  ty1:  T @Type         Int       :: Type-  ty2:  T @(Type->Type) Int Int   :: Type--These two TyConApps have the same TyCon at the front but they-(legitimately) have different numbers of arguments.  They-are surelyApart, so we can report that without looking any-further (see #15704).--Note [Unifying type applications]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-Unifying type applications is quite subtle, as we found-in #23134 and #22647, when type families are involved.--Suppose-   type family F a :: Type -> Type-   type family G k :: k = r | r -> k--and consider these examples:--* F Int ~ F Char, where F is injective-  Since F is injective, we can reduce this to Int ~ Char,-  therefore SurelyApart.--* F Int ~ F Char, where F is not injective-  Without injectivity, return MaybeApart.--* G Type ~ G (Type -> Type) Int-  Even though G is injective and the arguments to G are different,-  we cannot deduce apartness because the RHS is oversaturated.-  For example, G might be defined as-    G Type = Maybe Int-    G (Type -> Type) = Maybe-  So we return MaybeApart.--* F Int Bool ~ F Int Char       -- SurelyApart (since Bool is apart from Char)-  F Int Bool ~ Maybe a          -- MaybeApart-  F Int Bool ~ a b              -- MaybeApart-  F Int Bool ~ Char -> Bool     -- MaybeApart-  An oversaturated type family can match an application,-  whether it's a TyConApp, AppTy or FunTy. Decompose.--* F Int ~ a b-  We cannot decompose a saturated, or under-saturated-  type family application. We return MaybeApart.--To handle all those conditions, unify_ty goes through-the following checks in sequence, where Fn is a type family-of arity n:--* (C1) Fn x_1 ... x_n ~ Fn y_1 .. y_n-  A saturated application.-  Here we can unify arguments in which Fn is injective.-* (C2) Fn x_1 ... x_n ~ anything, anything ~ Fn x_1 ... x_n-  A saturated type family can match anything - we return MaybeApart.-* (C3) Fn x_1 ... x_m ~ a b, a b ~ Fn x_1 ... x_m where m > n-  An oversaturated type family can be decomposed.-* (C4) Fn x_1 ... x_m ~ anything, anything ~ Fn x_1 ... x_m, where m > n-  If we couldn't decompose in the previous step, we return SurelyApart.--Afterwards, the rest of the code doesn't have to worry about type families.--Note [Unifying type synonyms]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-Consider the task of unifying two 'Type's of the form--  TyConApp tc [] ~ TyConApp tc []--where `tc` is a type synonym. A naive way to perform this comparison these-would first expand the synonym and then compare the resulting expansions.--However, this is obviously wasteful and the RHS of `tc` may be large; it is-much better to rather compare the TyCons directly. Consequently, before-expanding type synonyms in type comparisons we first look for a nullary-TyConApp and simply compare the TyCons if we find one.--Of course, if we find that the TyCons are *not* equal then we still need to-perform the expansion as their RHSs may still be unifiable.  E.g-    type T = S (a->a)-    type S a = [a]-and consider-    T Int ~ S (Int -> Int)--We can't decompose non-nullary synonyms.  E.g.-    type R a = F a    -- Where F is a type family-and consider-    R (a->a) ~ R Int-We can't conclude that  (a->) ~ Int.  (There is a currently-missed opportunity-here; if we knew that R was /injective/, perhaps we could decompose.)--We perform the nullary-type-synonym optimisation in a number of places:-- * GHC.Core.Unify.unify_ty- * GHC.Tc.Solver.Equality.can_eq_nc'- * GHC.Tc.Utils.Unify.uType--This optimisation is especially helpful for the ubiquitous GHC.Types.Type,-since GHC prefers to use the type synonym over @TYPE 'LiftedRep@ applications-whenever possible. See Note [Using synonyms to compress types] in-GHC.Core.Type for details.--c.f. Note [Comparing type synonyms] in GHC.Core.TyCo.Compare--}---------------- unify_ty: the main workhorse -------------type AmIUnifying = Bool   -- True  <=> Unifying-                          -- False <=> Matching--unify_ty :: UMEnv-         -> Type -> Type  -- Types to be unified and a co-         -> CoercionN     -- A coercion between their kinds-                          -- See Note [Kind coercions in Unify]-         -> UM ()--- Precondition: see (Unification Kind Invariant)------ See Note [Specification of unification]--- Respects newtypes, PredTypes--- See Note [Computing equality on types] in GHC.Core.Type-unify_ty _env (TyConApp tc1 []) (TyConApp tc2 []) _kco-  -- See Note [Unifying type synonyms]-  | tc1 == tc2-  = return ()--unify_ty env ty1 ty2 kco-    -- Now handle the cases we can "look through": synonyms and casts.-  | Just ty1' <- coreView ty1 = unify_ty env ty1' ty2 kco-  | Just ty2' <- coreView ty2 = unify_ty env ty1 ty2' kco-  | CastTy ty1' co <- ty1     = if um_unif env-                                then unify_ty env ty1' ty2 (co `mkTransCo` kco)-                                else -- See Note [Matching in the presence of casts (1)]-                                     do { subst <- getSubst env-                                        ; let co' = substCo subst co-                                        ; unify_ty env ty1' ty2 (co' `mkTransCo` kco) }-  | CastTy ty2' co <- ty2     = unify_ty env ty1 ty2' (kco `mkTransCo` mkSymCo co)--unify_ty env (TyVarTy tv1) ty2 kco-  = uVar env tv1 ty2 kco-unify_ty env ty1 (TyVarTy tv2) kco-  | um_unif env  -- If unifying, can swap args-  = uVar (umSwapRn env) tv2 ty1 (mkSymCo kco)--unify_ty env ty1 ty2 _kco--  -- Handle non-oversaturated type families first-  -- See Note [Unifying type applications]-  ---  -- (C1) If we have T x1 ... xn ~ T y1 ... yn, use injectivity information of T-  -- Note that both sides must not be oversaturated-  | Just (tc1, tys1) <- isSatTyFamApp mb_tc_app1-  , Just (tc2, tys2) <- isSatTyFamApp mb_tc_app2-  , tc1 == tc2-  = do { let inj = case tyConInjectivityInfo tc1 of-                          NotInjective -> repeat False-                          Injective bs -> bs--             (inj_tys1, noninj_tys1) = partitionByList inj tys1-             (inj_tys2, noninj_tys2) = partitionByList inj tys2--       ; unify_tys env inj_tys1 inj_tys2-       ; unless (um_inj_tf env) $ -- See (end of) Note [Specification of unification]-         don'tBeSoSure MARTypeFamily $ unify_tys env noninj_tys1 noninj_tys2 }--  | Just _ <- isSatTyFamApp mb_tc_app1  -- (C2) A (not-over-saturated) type-family application-  = maybeApart MARTypeFamily            -- behaves like a type variable; might match--  | Just _ <- isSatTyFamApp mb_tc_app2  -- (C2) A (not-over-saturated) type-family application-                                        -- behaves like a type variable; might unify-                                        -- but doesn't match (as in the TyVarTy case)-  = if um_unif env then maybeApart MARTypeFamily else surelyApart--  -- Handle oversaturated type families.-  ---  -- They can match an application (TyConApp/FunTy/AppTy), this is handled-  -- the same way as in the AppTy case below.-  ---  -- If there is no application, an oversaturated type family can only-  -- match a type variable or a saturated type family,-  -- both of which we handled earlier. So we can say surelyApart.-  | Just (tc1, _) <- mb_tc_app1-  , isTypeFamilyTyCon tc1-  = if | Just (ty1a, ty1b) <- tcSplitAppTyNoView_maybe ty1-       , Just (ty2a, ty2b) <- tcSplitAppTyNoView_maybe ty2-       -> unify_ty_app env ty1a [ty1b] ty2a [ty2b]            -- (C3)-       | otherwise -> surelyApart                             -- (C4)--  | Just (tc2, _) <- mb_tc_app2-  , isTypeFamilyTyCon tc2-  = if | Just (ty1a, ty1b) <- tcSplitAppTyNoView_maybe ty1-       , Just (ty2a, ty2b) <- tcSplitAppTyNoView_maybe ty2-       -> unify_ty_app env ty1a [ty1b] ty2a [ty2b]            -- (C3)-       | otherwise -> surelyApart                             -- (C4)--  -- At this point, neither tc1 nor tc2 can be a type family.-  | Just (tc1, tys1) <- mb_tc_app1-  , Just (tc2, tys2) <- mb_tc_app2-  , tc1 == tc2-  = do { massertPpr (isInjectiveTyCon tc1 Nominal) (ppr tc1)-       ; unify_tc_app tc1 tys1 tys2-       }--  -- TYPE and CONSTRAINT are not Apart-  -- See Note [Type and Constraint are not apart] in GHC.Builtin.Types.Prim-  -- NB: at this point we know that the two TyCons do not match-  | Just (tc1,_) <- mb_tc_app1, let u1 = tyConUnique tc1-  , Just (tc2,_) <- mb_tc_app2, let u2 = tyConUnique tc2-  , (u1 == tYPETyConKey && u2 == cONSTRAINTTyConKey) ||-    (u2 == tYPETyConKey && u1 == cONSTRAINTTyConKey)-  = maybeApart MARTypeVsConstraint-    -- We don't bother to look inside; wrinkle (W3) in GHC.Builtin.Types.Prim-    -- Note [Type and Constraint are not apart]--  -- The arrow types are not Apart-  -- See Note [Type and Constraint are not apart] in GHC.Builtin.Types.Prim-  --     wrinkle (W2)-  -- NB1: at this point we know that the two TyCons do not match-  -- NB2: In the common FunTy/FunTy case you might wonder if we want to go via-  --      splitTyConApp_maybe.  But yes we do: we need to look at those implied-  --      kind argument in order to satisfy (Unification Kind Invariant)-  | FunTy {} <- ty1-  , FunTy {} <- ty2-  = maybeApart MARTypeVsConstraint-    -- We don't bother to look inside; wrinkle (W3) in GHC.Builtin.Types.Prim-    -- Note [Type and Constraint are not apart]--  where-    mb_tc_app1 = splitTyConApp_maybe ty1-    mb_tc_app2 = splitTyConApp_maybe ty2--    unify_tc_app tc tys1 tys2-      | tc == fUNTyCon-      , IgnoreMultiplicities <- um_arr_mult env-      , (_mult1 : no_mult_tys1) <- tys1-      , (_mult2 : no_mult_tys2) <- tys2-      = -- We're comparing function arrow types here (not constraint arrow-        -- types!), and they have at least one argument, which is the arrow's-        -- multiplicity annotation. The flag `um_arr_mult` instructs us to-        -- ignore multiplicities in this very case. This is a little tricky: see-        -- point (3) in Note [Rewrite rules ignore multiplicities in FunTy].-         unify_tys env no_mult_tys1 no_mult_tys2--      | otherwise-      = unify_tys env tys1 tys2--        -- Applications need a bit of care!-        -- They can match FunTy and TyConApp, so use splitAppTy_maybe-        -- NB: we've already dealt with type variables,-        -- so if one type is an App the other one jolly well better be too-unify_ty env (AppTy ty1a ty1b) ty2 _kco-  | Just (ty2a, ty2b) <- tcSplitAppTyNoView_maybe ty2-  = unify_ty_app env ty1a [ty1b] ty2a [ty2b]--unify_ty env ty1 (AppTy ty2a ty2b) _kco-  | Just (ty1a, ty1b) <- tcSplitAppTyNoView_maybe ty1-  = unify_ty_app env ty1a [ty1b] ty2a [ty2b]--unify_ty _ (LitTy x) (LitTy y) _kco | x == y = return ()--unify_ty env (ForAllTy (Bndr tv1 _) ty1) (ForAllTy (Bndr tv2 _) ty2) kco-  = do { unify_ty env (varType tv1) (varType tv2) (mkNomReflCo liftedTypeKind)-       ; let env' = umRnBndr2 env tv1 tv2-       ; unify_ty env' ty1 ty2 kco }---- See Note [Matching coercion variables]-unify_ty env (CoercionTy co1) (CoercionTy co2) kco-  = do { c_subst <- getCvSubstEnv-       ; case co1 of-           CoVarCo cv-             | not (um_unif env)-             , not (cv `elemVarEnv` c_subst)-             , let (_, co_l, co_r) = decomposeFunCo kco-                     -- Because the coercion is used in a type, it should be safe to-                     -- ignore the multiplicity coercion.-                      -- cv :: t1 ~ t2-                      -- co2 :: s1 ~ s2-                      -- co_l :: t1 ~ s1-                      -- co_r :: t2 ~ s2-                   rhs_co = co_l `mkTransCo` co2 `mkTransCo` mkSymCo co_r-             , BindMe <- tvBindFlag env cv (CoercionTy rhs_co)-             -> do { checkRnEnv env (tyCoVarsOfCo co2)-                   ; extendCvEnv cv rhs_co }-           _ -> return () }--unify_ty _ _ _ _ = surelyApart--unify_ty_app :: UMEnv -> Type -> [Type] -> Type -> [Type] -> UM ()-unify_ty_app env ty1 ty1args ty2 ty2args-  | Just (ty1', ty1a) <- splitAppTyNoView_maybe ty1-  , Just (ty2', ty2a) <- splitAppTyNoView_maybe ty2-  = unify_ty_app env ty1' (ty1a : ty1args) ty2' (ty2a : ty2args)--  | otherwise-  = do { let ki1 = typeKind ty1-             ki2 = typeKind ty2-           -- See Note [Kind coercions in Unify]-       ; unify_ty  env ki1 ki2 (mkNomReflCo liftedTypeKind)-       ; unify_ty  env ty1 ty2 (mkNomReflCo ki2)-                 -- Very important: 'ki2' not 'ki1'-                 -- See Note [Matching in the presence of casts (2)]-       ; unify_tys env ty1args ty2args }--unify_tys :: UMEnv -> [Type] -> [Type] -> UM ()--- Precondition: see (Unification Kind Invariant)-unify_tys env orig_xs orig_ys-  = go orig_xs orig_ys-  where-    go []     []     = return ()-    go (x:xs) (y:ys)-      -- See Note [Kind coercions in Unify]-      = do { unify_ty env x y (mkNomReflCo $ typeKind y)-                 -- Very important: 'y' not 'x'-                 -- See Note [Matching in the presence of casts (2)]-           ; go xs ys }-    go _ _ = surelyApart-      -- Possibly different saturations of a polykinded tycon-      -- See Note [Polykinded tycon applications]--isSatTyFamApp :: Maybe (TyCon, [Type]) -> Maybe (TyCon, [Type])--- Return the argument if we have a saturated type family application--- If it is /over/ saturated then we return False.  E.g.---     unify_ty (F a b) (c d)    where F has arity 1--- we definitely want to decompose that type application! (#22647)-isSatTyFamApp tapp@(Just (tc, tys))-  |  isTypeFamilyTyCon tc-  && not (tys `lengthExceeds` tyConArity tc)  -- Not over-saturated-  = tapp-isSatTyFamApp _ = Nothing------------------------------------uVar :: UMEnv-     -> InTyVar         -- Variable to be unified-     -> Type            -- with this Type-     -> Coercion        -- :: kind tv ~N kind ty-     -> UM ()--uVar env tv1 ty kco- = do { -- Apply the ambient renaming-        let tv1' = umRnOccL env tv1--        -- Check to see whether tv1 is refined by the substitution-      ; subst <- getTvSubstEnv-      ; case (lookupVarEnv subst tv1') of-          Just ty' | um_unif env                -- Unifying, so call-                   -> unify_ty env ty' ty kco   -- back into unify-                   | otherwise-                   -> -- Matching, we don't want to just recur here.-                      -- this is because the range of the subst is the target-                      -- type, not the template type. So, just check for-                      -- normal type equality.-                      unless ((ty' `mkCastTy` kco) `tcEqType` ty) $-                        surelyApart-                      -- NB: it's important to use `tcEqType` instead of `eqType` here,-                      -- otherwise we might not reject a substitution-                      -- which unifies `Type` with `Constraint`, e.g.-                      -- a call to tc_unify_tys with arguments-                      ---                      --   tys1 = [k,k]-                      --   tys2 = [Type, Constraint]-                      ---                      -- See test cases: T11715b, T20521.-          Nothing  -> uUnrefined env tv1' ty ty kco } -- No, continue--uUnrefined :: UMEnv-           -> OutTyVar          -- variable to be unified-           -> Type              -- with this Type-           -> Type              -- (version w/ expanded synonyms)-           -> Coercion          -- :: kind tv ~N kind ty-           -> UM ()---- We know that tv1 isn't refined--uUnrefined env tv1' ty2 ty2' kco-  | Just ty2'' <- coreView ty2'-  = uUnrefined env tv1' ty2 ty2'' kco    -- Unwrap synonyms-                -- This is essential, in case we have-                --      type Foo a = a-                -- and then unify a ~ Foo a--  | TyVarTy tv2 <- ty2'-  = do { let tv2' = umRnOccR env tv2-       ; unless (tv1' == tv2' && um_unif env) $ do-           -- If we are unifying a ~ a, just return immediately-           -- Do not extend the substitution-           -- See Note [Self-substitution when matching]--          -- Check to see whether tv2 is refined-       { subst <- getTvSubstEnv-       ; case lookupVarEnv subst tv2 of-         {  Just ty' | um_unif env -> uUnrefined env tv1' ty' ty' kco-         ;  _ ->--    do {   -- So both are unrefined-           -- Bind one or the other, depending on which is bindable-       ; let rhs1 = ty2 `mkCastTy` mkSymCo kco-             rhs2 = ty1 `mkCastTy` kco-             b1  = tvBindFlag env tv1' rhs1-             b2  = tvBindFlag env tv2' rhs2-             ty1 = mkTyVarTy tv1'-       ; case (b1, b2) of-           (BindMe, _) -> bindTv env tv1' rhs1-           (_, BindMe) | um_unif env-                       -> bindTv (umSwapRn env) tv2 rhs2--           _ | tv1' == tv2' -> return ()-             -- How could this happen? If we're only matching and if-             -- we're comparing forall-bound variables.--           _ -> surelyApart-  }}}}--uUnrefined env tv1' ty2 _ kco -- ty2 is not a type variable-  = case tvBindFlag env tv1' rhs of-      Apart  -> surelyApart-      BindMe -> bindTv env tv1' rhs-  where-    rhs = ty2 `mkCastTy` mkSymCo kco--bindTv :: UMEnv -> OutTyVar -> Type -> UM ()--- OK, so we want to extend the substitution with tv := ty--- But first, we must do a couple of checks-bindTv env tv1 ty2-  = do  { let free_tvs2 = tyCoVarsOfType ty2--        -- Make sure tys mentions no local variables-        -- E.g.  (forall a. b) ~ (forall a. [a])-        -- We should not unify b := [a]!-        ; checkRnEnv env free_tvs2--        -- Occurs check, see Note [Fine-grained unification]-        -- Make sure you include 'kco' (which ty2 does) #14846-        ; occurs <- occursCheck env tv1 free_tvs2--        ; if occurs then maybeApart MARInfinite-                    else extendTvEnv tv1 ty2 }--occursCheck :: UMEnv -> TyVar -> VarSet -> UM Bool-occursCheck env tv free_tvs-  | um_unif env-  = do { tsubst <- getTvSubstEnv-       ; return (tv `elemVarSet` niSubstTvSet tsubst free_tvs) }--  | otherwise      -- Matching; no occurs check-  = return False   -- See Note [Self-substitution when matching]--{--%************************************************************************-%*                                                                      *-                Binding decisions-*                                                                      *-************************************************************************--}--data BindFlag-  = BindMe      -- ^ A regular type variable--  | Apart       -- ^ Declare that this type variable is /apart/ from the-                -- type provided. That is, the type variable will never-                -- be instantiated to that type.-                -- See also Note [Binding when looking up instances]-                -- in GHC.Core.InstEnv.-  deriving Eq--- NB: It would be conceivable to have an analogue to MaybeApart here,--- but there is not yet a need.--{--************************************************************************-*                                                                      *-                Unification monad-*                                                                      *-************************************************************************--}--data UMEnv-  = UMEnv { um_unif :: AmIUnifying--          , um_inj_tf :: Bool-            -- Checking for injectivity?-            -- See (end of) Note [Specification of unification]--          , um_arr_mult :: MultiplicityFlag-            -- Whether to unify multiplicity arguments when unifying arrows.-            -- See Note [Rewrite rules ignore multiplicities in FunTy]--          , um_rn_env :: RnEnv2-            -- Renaming InTyVars to OutTyVars; this eliminates-            -- shadowing, and lines up matching foralls on the left-            -- and right--          , um_skols :: TyVarSet-            -- OutTyVars bound by a forall in this unification;-            -- Do not bind these in the substitution!-            -- See the function tvBindFlag--          , um_bind_fun :: BindFun-            -- User-supplied BindFlag function,-            -- for variables not in um_skols-          }--data UMState = UMState-                   { um_tv_env   :: TvSubstEnv-                   , um_cv_env   :: CvSubstEnv }--newtype UM a-  = UM' { unUM :: UMState -> UnifyResultM (UMState, a) }-    -- See Note [The one-shot state monad trick] in GHC.Utils.Monad--pattern UM :: (UMState -> UnifyResultM (UMState, a)) -> UM a--- See Note [The one-shot state monad trick] in GHC.Utils.Monad-pattern UM m <- UM' m-  where-    UM m = UM' (oneShot m)-{-# COMPLETE UM #-}--instance Functor UM where-  fmap f (UM m) = UM (\s -> fmap (\(s', v) -> (s', f v)) (m s))--instance Applicative UM where-      pure a = UM (\s -> pure (s, a))-      (<*>)  = ap--instance Monad UM where-  {-# INLINE (>>=) #-}-  -- See Note [INLINE pragmas and (>>)] in GHC.Utils.Monad-  m >>= k  = UM (\state ->-                  do { (state', v) <- unUM m state-                     ; unUM (k v) state' })--instance MonadFail UM where-    fail _   = UM (\_ -> SurelyApart) -- failed pattern match--initUM :: TvSubstEnv  -- subst to extend-       -> CvSubstEnv-       -> UM a -> UnifyResultM a-initUM subst_env cv_subst_env um-  = case unUM um state of-      Unifiable (_, subst)    -> Unifiable subst-      MaybeApart r (_, subst) -> MaybeApart r subst-      SurelyApart             -> SurelyApart-  where-    state = UMState { um_tv_env = subst_env-                    , um_cv_env = cv_subst_env }--tvBindFlag :: UMEnv -> OutTyVar -> Type -> BindFlag-tvBindFlag env tv rhs-  | tv `elemVarSet` um_skols env = Apart-  | otherwise                    = um_bind_fun env tv rhs--getTvSubstEnv :: UM TvSubstEnv-getTvSubstEnv = UM $ \state -> Unifiable (state, um_tv_env state)--getCvSubstEnv :: UM CvSubstEnv-getCvSubstEnv = UM $ \state -> Unifiable (state, um_cv_env state)--getSubst :: UMEnv -> UM Subst-getSubst env = do { tv_env <- getTvSubstEnv-                  ; cv_env <- getCvSubstEnv-                  ; let in_scope = rnInScopeSet (um_rn_env env)-                  ; return (mkTCvSubst in_scope tv_env cv_env) }--extendTvEnv :: TyVar -> Type -> UM ()-extendTvEnv tv ty = UM $ \state ->-  Unifiable (state { um_tv_env = extendVarEnv (um_tv_env state) tv ty }, ())--extendCvEnv :: CoVar -> Coercion -> UM ()-extendCvEnv cv co = UM $ \state ->-  Unifiable (state { um_cv_env = extendVarEnv (um_cv_env state) cv co }, ())--umRnBndr2 :: UMEnv -> TyCoVar -> TyCoVar -> UMEnv-umRnBndr2 env v1 v2-  = env { um_rn_env = rn_env', um_skols = um_skols env `extendVarSet` v' }-  where-    (rn_env', v') = rnBndr2_var (um_rn_env env) v1 v2--checkRnEnv :: UMEnv -> VarSet -> UM ()-checkRnEnv env varset-  | isEmptyVarSet skol_vars           = return ()-  | varset `disjointVarSet` skol_vars = return ()-  | otherwise                         = surelyApart-  where-    skol_vars = um_skols env-    -- NB: That isEmptyVarSet guard is a critical optimization;-    -- it means we don't have to calculate the free vars of-    -- the type, often saving quite a bit of allocation.---- | Converts any SurelyApart to a MaybeApart-don'tBeSoSure :: MaybeApartReason -> UM () -> UM ()-don'tBeSoSure r um = UM $ \ state ->-  case unUM um state of-    SurelyApart -> MaybeApart r (state, ())-    other       -> other--umRnOccL :: UMEnv -> TyVar -> TyVar-umRnOccL env v = rnOccL (um_rn_env env) v--umRnOccR :: UMEnv -> TyVar -> TyVar-umRnOccR env v = rnOccR (um_rn_env env) v--umSwapRn :: UMEnv -> UMEnv-umSwapRn env = env { um_rn_env = rnSwap (um_rn_env env) }--maybeApart :: MaybeApartReason -> UM ()-maybeApart r = UM (\state -> MaybeApart r (state, ()))--surelyApart :: UM a-surelyApart = UM (\_ -> SurelyApart)--{--%************************************************************************-%*                                                                      *-            Matching a (lifted) type against a coercion-%*                                                                      *-%************************************************************************--This section defines essentially an inverse to liftCoSubst. It is defined-here to avoid a dependency from Coercion on this module.---}--data MatchEnv = ME { me_tmpls :: TyVarSet-                   , me_env   :: RnEnv2 }---- | 'liftCoMatch' is sort of inverse to 'liftCoSubst'.  In particular, if---   @liftCoMatch vars ty co == Just s@, then @liftCoSubst s ty == co@,---   where @==@ there means that the result of 'liftCoSubst' has the same---   type as the original co; but may be different under the hood.---   That is, it matches a type against a coercion of the same---   "shape", and returns a lifting substitution which could have been---   used to produce the given coercion from the given type.---   Note that this function is incomplete -- it might return Nothing---   when there does indeed exist a possible lifting context.------ This function is incomplete in that it doesn't respect the equality--- in `eqType`. That is, it's possible that this will succeed for t1 and--- fail for t2, even when t1 `eqType` t2. That's because it depends on--- there being a very similar structure between the type and the coercion.--- This incompleteness shouldn't be all that surprising, especially because--- it depends on the structure of the coercion, which is a silly thing to do.------ The lifting context produced doesn't have to be exacting in the roles--- of the mappings. This is because any use of the lifting context will--- also require a desired role. Thus, this algorithm prefers mapping to--- nominal coercions where it can do so.-liftCoMatch :: TyCoVarSet -> Type -> Coercion -> Maybe LiftingContext-liftCoMatch tmpls ty co-  = do { cenv1 <- ty_co_match menv emptyVarEnv ki ki_co ki_ki_co ki_ki_co-       ; cenv2 <- ty_co_match menv cenv1       ty co-                              (mkNomReflCo co_lkind) (mkNomReflCo co_rkind)-       ; return (LC (mkEmptySubst in_scope) cenv2) }-  where-    menv     = ME { me_tmpls = tmpls, me_env = mkRnEnv2 in_scope }-    in_scope = mkInScopeSet (tmpls `unionVarSet` tyCoVarsOfCo co)-    -- Like tcMatchTy, assume all the interesting variables-    -- in ty are in tmpls--    ki       = typeKind ty-    ki_co    = promoteCoercion co-    ki_ki_co = mkNomReflCo liftedTypeKind--    Pair co_lkind co_rkind = coercionKind ki_co---- | 'ty_co_match' does all the actual work for 'liftCoMatch'.-ty_co_match :: MatchEnv   -- ^ ambient helpful info-            -> LiftCoEnv  -- ^ incoming subst-            -> Type       -- ^ ty, type to match-            -> Coercion   -- ^ co :: lty ~r rty, coercion to match against-            -> Coercion   -- ^ :: kind(lsubst(ty)) ~N kind(lty)-            -> Coercion   -- ^ :: kind(rsubst(ty)) ~N kind(rty)-            -> Maybe LiftCoEnv-   -- ^ Just env ==> liftCoSubst Nominal env ty == co, modulo roles.-   -- Also: Just env ==> lsubst(ty) == lty and rsubst(ty) == rty,-   -- where lsubst = lcSubstLeft(env) and rsubst = lcSubstRight(env)-ty_co_match menv subst ty co lkco rkco-  | Just ty' <- coreView ty = ty_co_match menv subst ty' co lkco rkco--  -- handle Refl case:-  | tyCoVarsOfType ty `isNotInDomainOf` subst-  , Just (ty', _) <- isReflCo_maybe co-  , ty `eqType` ty'-    -- Why `eqType` and not `tcEqType`? Because this function is only used-    -- during coercion optimisation, after type-checking has finished.-  = Just subst--  where-    isNotInDomainOf :: VarSet -> VarEnv a -> Bool-    isNotInDomainOf set env-      = noneSet (\v -> elemVarEnv v env) set--    noneSet :: (Var -> Bool) -> VarSet -> Bool-    noneSet f = allVarSet (not . f)--ty_co_match menv subst ty co lkco rkco-  | CastTy ty' co' <- ty-     -- See Note [Matching in the presence of casts (1)]-  = let empty_subst  = mkEmptySubst (rnInScopeSet (me_env menv))-        substed_co_l = substCo (liftEnvSubstLeft empty_subst subst)  co'-        substed_co_r = substCo (liftEnvSubstRight empty_subst subst) co'-    in-    ty_co_match menv subst ty' co (substed_co_l `mkTransCo` lkco)-                                  (substed_co_r `mkTransCo` rkco)--  | SymCo co' <- co-  = swapLiftCoEnv <$> ty_co_match menv (swapLiftCoEnv subst) ty co' rkco lkco--  -- Match a type variable against a non-refl coercion-ty_co_match menv subst (TyVarTy tv1) co lkco rkco-  | Just co1' <- lookupVarEnv subst tv1' -- tv1' is already bound to co1-  = if eqCoercionX (nukeRnEnvL rn_env) co1' co-    then Just subst-    else Nothing       -- no match since tv1 matches two different coercions--  | tv1' `elemVarSet` me_tmpls menv           -- tv1' is a template var-  = if any (inRnEnvR rn_env) (tyCoVarsOfCoList co)-    then Nothing      -- occurs check failed-    else Just $ extendVarEnv subst tv1' $-                castCoercionKind co (mkSymCo lkco) (mkSymCo rkco)--  | otherwise-  = Nothing--  where-    rn_env = me_env menv-    tv1' = rnOccL rn_env tv1--  -- just look through SubCo's. We don't really care about roles here.-ty_co_match menv subst ty (SubCo co) lkco rkco-  = ty_co_match menv subst ty co lkco rkco--ty_co_match menv subst (AppTy ty1a ty1b) co _lkco _rkco-  | Just (co2, arg2) <- splitAppCo_maybe co     -- c.f. Unify.match on AppTy-  = ty_co_match_app menv subst ty1a [ty1b] co2 [arg2]-ty_co_match menv subst ty1 (AppCo co2 arg2) _lkco _rkco-  | Just (ty1a, ty1b) <- splitAppTyNoView_maybe ty1-       -- yes, the one from Type, not TcType; this is for coercion optimization-  = ty_co_match_app menv subst ty1a [ty1b] co2 [arg2]--ty_co_match menv subst (TyConApp tc1 tys) (TyConAppCo _ tc2 cos) _lkco _rkco-  = ty_co_match_tc menv subst tc1 tys tc2 cos--ty_co_match menv subst (FunTy { ft_mult = w, ft_arg = ty1, ft_res = ty2 })-            (FunCo { fco_mult = co_w, fco_arg = co1, fco_res = co2 }) _lkco _rkco-  = ty_co_match_args menv subst [w,    rep1,    rep2,    ty1, ty2]-                                [co_w, co1_rep, co2_rep, co1, co2]-  where-     rep1    = getRuntimeRep ty1-     rep2    = getRuntimeRep ty2-     co1_rep = mkRuntimeRepCo co1-     co2_rep = mkRuntimeRepCo co2-    -- NB: we include the RuntimeRep arguments in the matching;-    --     not doing so caused #21205.--ty_co_match menv subst (ForAllTy (Bndr tv1 vis1t) ty1)-                       (ForAllCo tv2 vis1c vis2c kind_co2 co2)-                       lkco rkco-  | isTyVar tv1 && isTyVar tv2-  , vis1t == vis1c && vis1c == vis2c -- Is this necessary?-      -- Is this visibility check necessary?  @rae says: yes, I think the-      -- check is necessary, if we're caring about visibility (and we are).-      -- But ty_co_match is a dark and not important corner.-  = do { subst1 <- ty_co_match menv subst (tyVarKind tv1) kind_co2-                               ki_ki_co ki_ki_co-       ; let rn_env0 = me_env menv-             rn_env1 = rnBndr2 rn_env0 tv1 tv2-             menv'   = menv { me_env = rn_env1 }-       ; ty_co_match menv' subst1 ty1 co2 lkco rkco }-  where-    ki_ki_co = mkNomReflCo liftedTypeKind---- ty_co_match menv subst (ForAllTy (Bndr cv1 _) ty1)---                        (ForAllCo cv2 kind_co2 co2)---                        lkco rkco---   | isCoVar cv1 && isCoVar cv2---   We seems not to have enough information for this case---   1. Given:---        cv1      :: (s1 :: k1) ~r (s2 :: k2)---        kind_co2 :: (s1' ~ s2') ~N (t1 ~ t2)---        eta1      = mkSelCo (SelTyCon 2 role) (downgradeRole r Nominal kind_co2)---                 :: s1' ~ t1---        eta2      = mkSelCo (SelTyCon 3 role) (downgradeRole r Nominal kind_co2)---                 :: s2' ~ t2---      Wanted:---        subst1 <- ty_co_match menv subst  s1 eta1 kco1 kco2---        subst2 <- ty_co_match menv subst1 s2 eta2 kco3 kco4---      Question: How do we get kcoi?---   2. Given:---        lkco :: <*>    -- See Note [Weird typing rule for ForAllTy] in GHC.Core.TyCo.Rep---        rkco :: <*>---      Wanted:---        ty_co_match menv' subst2 ty1 co2 lkco' rkco'---      Question: How do we get lkco' and rkco'?--ty_co_match _ subst (CoercionTy {}) _ _ _-  = Just subst -- don't inspect coercions--ty_co_match menv subst ty (GRefl r t (MCo co)) lkco rkco-  =  ty_co_match menv subst ty (GRefl r t MRefl) lkco (rkco `mkTransCo` mkSymCo co)--ty_co_match menv subst ty co1 lkco rkco-  | Just (CastTy t co, r) <- isReflCo_maybe co1-  -- In @pushRefl@, pushing reflexive coercion inside CastTy will give us-  -- t |> co ~ t ; <t> ; t ~ t |> co-  -- But transitive coercions are not helpful. Therefore we deal-  -- with it here: we do recursion on the smaller reflexive coercion,-  -- while propagating the correct kind coercions.-  = let kco' = mkSymCo co-    in ty_co_match menv subst ty (mkReflCo r t) (lkco `mkTransCo` kco')-                                                (rkco `mkTransCo` kco')--ty_co_match menv subst ty co lkco rkco-  | Just co' <- pushRefl co = ty_co_match menv subst ty co' lkco rkco-  | otherwise               = Nothing--ty_co_match_tc :: MatchEnv -> LiftCoEnv-               -> TyCon -> [Type]-               -> TyCon -> [Coercion]-               -> Maybe LiftCoEnv-ty_co_match_tc menv subst tc1 tys1 tc2 cos2-  = do { guard (tc1 == tc2)-       ; ty_co_match_args menv subst tys1 cos2 }--ty_co_match_app :: MatchEnv -> LiftCoEnv-                -> Type -> [Type] -> Coercion -> [Coercion]-                -> Maybe LiftCoEnv-ty_co_match_app menv subst ty1 ty1args co2 co2args-  | Just (ty1', ty1a) <- splitAppTyNoView_maybe ty1-  , Just (co2', co2a) <- splitAppCo_maybe co2-  = ty_co_match_app menv subst ty1' (ty1a : ty1args) co2' (co2a : co2args)--  | otherwise-  = do { subst1 <- ty_co_match menv subst ki1 ki2 ki_ki_co ki_ki_co-       ; let Pair lkco rkco = mkNomReflCo <$> coercionKind ki2-       ; subst2 <- ty_co_match menv subst1 ty1 co2 lkco rkco-       ; ty_co_match_args menv subst2 ty1args co2args }-  where-    ki1 = typeKind ty1-    ki2 = promoteCoercion co2-    ki_ki_co = mkNomReflCo liftedTypeKind--ty_co_match_args :: MatchEnv -> LiftCoEnv -> [Type] -> [Coercion]-                 -> Maybe LiftCoEnv-ty_co_match_args menv subst (ty:tys) (arg:args)-  = do { let Pair lty rty = coercionKind arg-             lkco = mkNomReflCo (typeKind lty)-             rkco = mkNomReflCo (typeKind rty)-       ; subst' <- ty_co_match menv subst ty arg lkco rkco-       ; ty_co_match_args menv subst' tys args }-ty_co_match_args _    subst []       [] = Just subst-ty_co_match_args _    _     _        _  = Nothing--pushRefl :: Coercion -> Maybe Coercion-pushRefl co =-  case (isReflCo_maybe co) of-    Just (AppTy ty1 ty2, Nominal)-      -> Just (AppCo (mkReflCo Nominal ty1) (mkNomReflCo ty2))-    Just (FunTy af w ty1 ty2, r)-      ->  Just (FunCo r af af (mkReflCo r w) (mkReflCo r ty1) (mkReflCo r ty2))-    Just (TyConApp tc tys, r)-      -> Just (TyConAppCo r tc (zipWith mkReflCo (tyConRoleListX r tc) tys))-    Just (ForAllTy (Bndr tv vis) ty, r)-      -> Just (ForAllCo { fco_tcv = tv, fco_visL = vis, fco_visR = vis-                        , fco_kind = mkNomReflCo (varType tv)-                        , fco_body = mkReflCo r ty })-    _ -> Nothing--{--************************************************************************-*                                                                      *-              Flattening-*                                                                      *-************************************************************************--Note [Flattening type-family applications when matching instances]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-As described in "Closed type families with overlapping equations"-http://research.microsoft.com/en-us/um/people/simonpj/papers/ext-f/axioms-extended.pdf-we need to flatten core types before unifying them, when checking for "surely-apart"-against earlier equations of a closed type family.-Flattening means replacing all top-level uses of type functions with-fresh variables, *taking care to preserve sharing*. That is, the type-(Either (F a b) (F a b)) should flatten to (Either c c), never (Either-c d).--Here is a nice example of why it's all necessary:--  type family F a b where-    F Int Bool = Char-    F a   b    = Double-  type family G a         -- open, no instances--How do we reduce (F (G Float) (G Float))? The first equation clearly doesn't match,-while the second equation does. But, before reducing, we must make sure that the-target can never become (F Int Bool). Well, no matter what G Float becomes, it-certainly won't become *both* Int and Bool, so indeed we're safe reducing-(F (G Float) (G Float)) to Double.--This is necessary not only to get more reductions (which we might be-willing to give up on), but for substitutivity. If we have (F x x), we-can see that (F x x) can reduce to Double. So, it had better be the-case that (F blah blah) can reduce to Double, no matter what (blah)-is!  Flattening as done below ensures this.--We also use this flattening operation to check for class instances.-If we have-  instance C (Maybe b)-  instance {-# OVERLAPPING #-} C (Maybe Bool)-  [W] C (Maybe (F a))-we want to know that the second instance might match later. So we-flatten the (F a) in the target before trying to unify with instances.-(This is done in GHC.Core.InstEnv.lookupInstEnv'.)--The algorithm works by building up a TypeMap TyVar, mapping-type family applications to fresh variables. This mapping must-be threaded through all the function calls, as any entry in-the mapping must be propagated to all future nodes in the tree.--The algorithm also must track the set of in-scope variables, in-order to make fresh variables as it flattens. (We are far from a-source of fresh Uniques.) See Wrinkle 2, below.--There are wrinkles, of course:--1. The flattening algorithm must account for the possibility-   of inner `forall`s. (A `forall` seen here can happen only-   because of impredicativity. However, the flattening operation-   is an algorithm in Core, which is impredicative.)-   Suppose we have (forall b. F b) -> (forall b. F b). Of course,-   those two bs are entirely unrelated, and so we should certainly-   not flatten the two calls F b to the same variable. Instead, they-   must be treated separately. We thus carry a substitution that-   freshens variables; we must apply this substitution (in-   `coreFlattenTyFamApp`) before looking up an application in the environment.-   Note that the range of the substitution contains only TyVars, never anything-   else.--   For the sake of efficiency, we only apply this substitution when absolutely-   necessary. Namely:--   * We do not perform the substitution at all if it is empty.-   * We only need to worry about the arguments of a type family that are within-     the arity of said type family, so we can get away with not applying the-     substitution to any oversaturated type family arguments.-   * Importantly, we do /not/ achieve this substitution by recursively-     flattening the arguments, as this would be wrong. Consider `F (G a)`,-     where F and G are type families. We might decide that `F (G a)` flattens-     to `beta`. Later, the substitution is non-empty (but does not map `a`) and-     so we flatten `G a` to `gamma` and try to flatten `F gamma`. Of course,-     `F gamma` is unknown, and so we flatten it to `delta`, but it really-     should have been `beta`! Argh!--     Moral of the story: instead of flattening the arguments, just substitute-     them directly.--2. There are two different reasons we might add a variable-   to the in-scope set as we work:--     A. We have just invented a new flattening variable.-     B. We have entered a `forall`.--   Annoying here is that in-scope variable source (A) must be-   threaded through the calls. For example, consider (F b -> forall c. F c).-   Suppose that, when flattening F b, we invent a fresh variable c.-   Now, when we encounter (forall c. F c), we need to know c is already in-   scope so that we locally rename c to c'. However, if we don't thread through-   the in-scope set from one argument of (->) to the other, we won't know this-   and might get very confused.--   In contrast, source (B) increases only as we go deeper, as in-scope sets-   normally do. However, even here we must be careful. The TypeMap TyVar that-   contains mappings from type family applications to freshened variables will-   be threaded through both sides of (forall b. F b) -> (forall b. F b). We-   thus must make sure that the two `b`s don't get renamed to the same b1. (If-   they did, then looking up `F b1` would yield the same flatten var for-   each.) So, even though `forall`-bound variables should really be in the-   in-scope set only when they are in scope, we retain these variables even-   outside of their scope. This ensures that, if we encounter a fresh-   `forall`-bound b, we will rename it to b2, not b1. Note that keeping a-   larger in-scope set than strictly necessary is always OK, as in-scope sets-   are only ever used to avoid collisions.--   Sadly, the freshening substitution described in (1) really mustn't bind-   variables outside of their scope: note that its domain is the *unrenamed*-   variables. This means that the substitution gets "pushed down" (like a-   reader monad) while the in-scope set gets threaded (like a state monad).-   Because a Subst contains its own in-scope set, we don't carry a Subst;-   instead, we just carry a TvSubstEnv down, tying it to the InScopeSet-   traveling separately as necessary.--3. Consider `F ty_1 ... ty_n`, where F is a type family with arity k:--     type family F ty_1 ... ty_k :: res_k--   It's tempting to just flatten `F ty_1 ... ty_n` to `alpha`, where alpha is a-   flattening skolem. But we must instead flatten it to-   `alpha ty_(k+1) ... ty_n`—that is, by only flattening up to the arity of the-   type family.--   Why is this better? Consider the following concrete example from #16995:--     type family Param :: Type -> Type--     type family LookupParam (a :: Type) :: Type where-       LookupParam (f Char) = Bool-       LookupParam x        = Int--     foo :: LookupParam (Param ())-     foo = 42--   In order for `foo` to typecheck, `LookupParam (Param ())` must reduce to-   `Int`. But if we flatten `Param ()` to `alpha`, then GHC can't be sure if-   `alpha` is apart from `f Char`, so it won't fall through to the second-   equation. But since the `Param` type family has arity 0, we can instead-   flatten `Param ()` to `alpha ()`, about which GHC knows with confidence is-   apart from `f Char`, permitting the second equation to be reached.--   Not only does this allow more programs to be accepted, it's also important-   for correctness. Not doing this was the root cause of the Core Lint error-   in #16995.--flattenTys is defined here because of module dependencies.--}--data FlattenEnv-  = FlattenEnv { fe_type_map :: TypeMap (TyVar, TyCon, [Type])-                 -- domain: exactly-saturated type family applications-                 -- range: (fresh variable, type family tycon, args)-               , fe_in_scope :: InScopeSet }-                 -- See Note [Flattening type-family applications when matching instances]--emptyFlattenEnv :: InScopeSet -> FlattenEnv-emptyFlattenEnv in_scope-  = FlattenEnv { fe_type_map = emptyTypeMap-               , fe_in_scope = in_scope }--updateInScopeSet :: FlattenEnv -> (InScopeSet -> InScopeSet) -> FlattenEnv-updateInScopeSet env upd = env { fe_in_scope = upd (fe_in_scope env) }--flattenTys :: InScopeSet -> [Type] -> [Type]--- See Note [Flattening type-family applications when matching instances]-flattenTys in_scope tys = fst (flattenTysX in_scope tys)--flattenTysX :: InScopeSet -> [Type] -> ([Type], TyVarEnv (TyCon, [Type]))--- See Note [Flattening type-family applications when matching instances]--- NB: the returned types mention the fresh type variables---     in the domain of the returned env, whose range includes---     the original type family applications. Building a substitution---     from this information and applying it would yield the original---     types -- almost. The problem is that the original type might---     have something like (forall b. F a b); the returned environment---     can't really sensibly refer to that b. So it may include a locally----     bound tyvar in its range. Currently, the only usage of this env't---     checks whether there are any meta-variables in it---     (in GHC.Tc.Solver.Monad.mightEqualLater), so this is all OK.-flattenTysX in_scope tys-  = let (env, result) = coreFlattenTys emptyTvSubstEnv (emptyFlattenEnv in_scope) tys in-    (result, build_env (fe_type_map env))-  where-    build_env :: TypeMap (TyVar, TyCon, [Type]) -> TyVarEnv (TyCon, [Type])-    build_env env_in-      = foldTM (\(tv, tc, tys) env_out -> extendVarEnv env_out tv (tc, tys))-               env_in emptyVarEnv--coreFlattenTys :: TvSubstEnv -> FlattenEnv-               -> [Type] -> (FlattenEnv, [Type])-coreFlattenTys subst = mapAccumL (coreFlattenTy subst)--coreFlattenTy :: TvSubstEnv -> FlattenEnv-              -> Type -> (FlattenEnv, Type)-coreFlattenTy subst = go-  where-    go env ty | Just ty' <- coreView ty = go env ty'--    go env (TyVarTy tv)-      | Just ty <- lookupVarEnv subst tv = (env, ty)-      | otherwise                        = let (env', ki) = go env (tyVarKind tv) in-                                           (env', mkTyVarTy $ setTyVarKind tv ki)-    go env (AppTy ty1 ty2) = let (env1, ty1') = go env  ty1-                                 (env2, ty2') = go env1 ty2 in-                             (env2, AppTy ty1' ty2')-    go env (TyConApp tc tys)-         -- NB: Don't just check if isFamilyTyCon: this catches *data* families,-         -- which are generative and thus can be preserved during flattening-      | not (isGenerativeTyCon tc Nominal)-      = coreFlattenTyFamApp subst env tc tys--      | otherwise-      = let (env', tys') = coreFlattenTys subst env tys in-        (env', mkTyConApp tc tys')--    go env ty@(FunTy { ft_mult = mult, ft_arg = ty1, ft_res = ty2 })-      = let (env1, ty1') = go env  ty1-            (env2, ty2') = go env1 ty2-            (env3, mult') = go env2 mult in-        (env3, ty { ft_mult = mult', ft_arg = ty1', ft_res = ty2' })--    go env (ForAllTy (Bndr tv vis) ty)-      = let (env1, subst', tv') = coreFlattenVarBndr subst env tv-            (env2, ty') = coreFlattenTy subst' env1 ty in-        (env2, ForAllTy (Bndr tv' vis) ty')--    go env ty@(LitTy {}) = (env, ty)--    go env (CastTy ty co)-      = let (env1, ty') = go env ty-            (env2, co') = coreFlattenCo subst env1 co in-        (env2, CastTy ty' co')--    go env (CoercionTy co)-      = let (env', co') = coreFlattenCo subst env co in-        (env', CoercionTy co')----- when flattening, we don't care about the contents of coercions.--- so, just return a fresh variable of the right (flattened) type-coreFlattenCo :: TvSubstEnv -> FlattenEnv-              -> Coercion -> (FlattenEnv, Coercion)-coreFlattenCo subst env co-  = (env2, mkCoVarCo covar)-  where-    (env1, kind') = coreFlattenTy subst env (coercionType co)-    covar         = mkFlattenFreshCoVar (fe_in_scope env1) kind'-    -- Add the covar to the FlattenEnv's in-scope set.-    -- See Note [Flattening type-family applications when matching instances], wrinkle 2A.-    env2          = updateInScopeSet env1 (flip extendInScopeSet covar)--coreFlattenVarBndr :: TvSubstEnv -> FlattenEnv-                   -> TyCoVar -> (FlattenEnv, TvSubstEnv, TyVar)-coreFlattenVarBndr subst env tv-  = (env2, subst', tv')-  where-    -- See Note [Flattening type-family applications when matching instances], wrinkle 2B.-    kind          = varType tv-    (env1, kind') = coreFlattenTy subst env kind-    tv'           = uniqAway (fe_in_scope env1) (setVarType tv kind')-    subst'        = extendVarEnv subst tv (mkTyVarTy tv')-    env2          = updateInScopeSet env1 (flip extendInScopeSet tv')--coreFlattenTyFamApp :: TvSubstEnv -> FlattenEnv-                    -> TyCon         -- type family tycon-                    -> [Type]        -- args, already flattened-                    -> (FlattenEnv, Type)-coreFlattenTyFamApp tv_subst env fam_tc fam_args-  = case lookupTypeMap type_map fam_ty of-      Just (tv, _, _) -> (env', mkAppTys (mkTyVarTy tv) leftover_args')-      Nothing ->-        let tyvar_name = mkFlattenFreshTyName fam_tc-            tv         = uniqAway in_scope $-                         mkTyVar tyvar_name (typeKind fam_ty)--            ty'   = mkAppTys (mkTyVarTy tv) leftover_args'-            env'' = env' { fe_type_map = extendTypeMap type_map fam_ty-                                                       (tv, fam_tc, sat_fam_args)-                         , fe_in_scope = extendInScopeSet in_scope tv }-        in (env'', ty')-  where-    arity = tyConArity fam_tc-    tcv_subst = Subst (fe_in_scope env) emptyIdSubstEnv tv_subst emptyVarEnv-    (sat_fam_args, leftover_args) = assert (arity <= length fam_args) $-                                    splitAt arity fam_args-    -- Apply the substitution before looking up an application in the-    -- environment. See Note [Flattening type-family applications when matching instances],-    -- wrinkle 1.-    -- NB: substTys short-cuts the common case when the substitution is empty.-    sat_fam_args' = substTys tcv_subst sat_fam_args-    (env', leftover_args') = coreFlattenTys tv_subst env leftover_args-    -- `fam_tc` may be over-applied to `fam_args` (see-    -- Note [Flattening type-family applications when matching instances]-    -- wrinkle 3), so we split it into the arguments needed to saturate it-    -- (sat_fam_args') and the rest (leftover_args')-    fam_ty = mkTyConApp fam_tc sat_fam_args'-    FlattenEnv { fe_type_map = type_map-               , fe_in_scope = in_scope } = env'--mkFlattenFreshTyName :: Uniquable a => a -> Name-mkFlattenFreshTyName unq-  = mkSysTvName (getUnique unq) (fsLit "flt")--mkFlattenFreshCoVar :: InScopeSet -> Kind -> CoVar-mkFlattenFreshCoVar in_scope kind-  = let uniq = unsafeGetFreshLocalUnique in_scope-        name = mkSystemVarName uniq (fsLit "flc")-    in mkCoVar name kind-+        tcUnifyTy, tcUnifyTys, tcUnifyFunDeps, tcUnifyDebugger,+        tcUnifyTysFG, tcUnifyTyForInjectivity,+        BindTvFun, BindFamFun, BindFlag(..),+        matchBindTv, alwaysBindTv, alwaysBindFam, dontCareBindFam,+        UnifyResult, UnifyResultM(..), MaybeApartReason(..),+        typesCantMatch, typesAreApart,++        -- Matching a type against a lifted type (coercion)+        liftCoMatch+   ) where++import GHC.Prelude++import GHC.Types.Var+import GHC.Types.Var.Env+import GHC.Types.Var.Set+import GHC.Builtin.Names( tYPETyConKey, cONSTRAINTTyConKey )+import GHC.Core.Type     hiding ( getTvSubstEnv )+import GHC.Core.Coercion hiding ( getCvSubstEnv )+import GHC.Core.Predicate( scopedSort )+import GHC.Core.TyCon+import GHC.Core.Predicate( CanEqLHS(..), canEqLHS_maybe )+import GHC.Core.TyCon.Env+import GHC.Core.TyCo.Rep+import GHC.Core.TyCo.Compare ( eqType, tcEqType, tcEqTyConAppArgs )+import GHC.Core.TyCo.FVs     ( tyCoVarsOfCoList, tyCoFVsOfTypes )+import GHC.Core.TyCo.Subst   ( mkTvSubst )+import GHC.Core.Map.Type+import GHC.Core.Multiplicity++import GHC.Utils.FV( FV, fvVarList )+import GHC.Utils.Misc+import GHC.Utils.Outputable+import GHC.Types.Basic( SwapFlag(..) )+import GHC.Types.Unique.FM+import GHC.Exts( oneShot )+import GHC.Utils.Panic++import GHC.Data.Pair+import GHC.Data.TrieMap+import GHC.Data.Maybe( orElse )++import Control.Monad+import qualified Data.Semigroup as S+import GHC.Builtin.Types.Prim (fUNTyCon)++{- Note [The Core unifier]+~~~~~~~~~~~~~~~~~~~~~~~~~~+This module contains the (pure) unifier two types.  It is subtle in a number+of ways.  Here we summarise, but see Note [Specification of unification].++(CU1) It creates a substition only for "bindable" or "template" type variables.+  These are identified by a `um_bind_tv_fun` function passed down in the `UMEnv`+  environment.++(CU2) We want to match in the presence of foralls;+        e.g     (forall a. t1) ~ (forall b. t2)+   That is what the `um_rn_env :: RnEnv2` field of `UMEnv` is for; it does the+   alpha-renaming that makes it as if `a` and `b` were the same variable.+   Initialising the `RnEnv2`, so that it can generate a fresh binder when+   necessary, entails knowing the free variables of both types.++   Of course, we must be careful not to bind a template type variable to a+   locally bound variable.  E.g.+        (forall a. x) ~ (forall b. b)+   where `x` is the template type variable.  Then we do not want to+   bind `x` to a/b!  See `mentionsForAllBoundTyVarsL/R`.++(CU3) We want to take special care for type families.+  See the big Note [Apartness and type families]++(CU4) Rather than returning just "unifiable" or "not-unifiable" we do "fine-grained"+  unification (hence "fg" or "FG" in this module) returning three possiblities,+  captured in `UnifyResult`:+    - Unifiable subst : certainly unifiable with this type substitution+    - SurelyApart     : cannot be unifiable, regardless of how type familes reduce+    - MaybeApart      : neither of the above+  See Note [Unification result].++  Four reasons for MaybeApart (see `MaybeApartReason`).  The first two are the+  big ones!+    * MARTypeFamily:+         Family reduction might make the two types equal+             Maybe (F Int) ~ Maybe Bool+         See Note [Apartness and type families]+    * MARInfinite (occurs check):+         See Note [Infinitary substitutions]+    * MARTypeVsConstraint:+         See Note [Type and Constraint are not apart] in GHC.Builtin.Types.Prim+    * MARCast (obscure):+         See (KCU2) in Note [Kind coercions in Unify]++(CU5) We need to take care with kinds.  See Note [tcMatchTy vs tcMatchTyKi]++(CU6) The "unifier" can also do /matching/, governed by `um_unif :: AmIUnifying`.+   When matching, the LHS and RHS namespaces are unrelated. In particular, the+   bindable type variable can occur (unrelatedly) in the RHS.  E.g.+        match  (a,Maybe a) ~  ([a], Maybe [a])+   We get the substitution [a :-> [a]], without confusing the+   LHS `a` with the RHS `a`.  The substitition is "one-shot", and should not be+   iterated.++Note [Infinitary substitutions]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+Do the types (x, x) and ([y], y) unify? The answer is seemingly "no" --+no substitution to finite types makes these match. This is the famous+"occurs check".++But, a substitution to *infinite* types can unify these two types:+  [x |-> [[...]]], y |-> [[[...]]] ].++Why do we care? Consider these two type family instances:++  type instance F x x   = Int+  type instance F [y] y = Bool++If we also have++  type instance Looper = [Looper]++then the instances potentially overlap -- they are not "apart". So we must+distinguish failure-to-unify from definitely-apart. The solution is to use+unification over infinite terms. This is possible (see [1] for lots of gory+details), but a full algorithm is a little more powerful than we need. Instead,+we make a conservative approximation and just omit the occurs check.++  [1]: http://research.microsoft.com/en-us/um/people/simonpj/papers/ext-f/axioms-extended.pdf++tcUnifyTys considers an occurs-check problem as the same as general unification+failure.++See also #8162.++It's worth noting that unification in the presence of infinite types is not+complete. This means that, sometimes, a closed type family does not reduce+when it should. See test case indexed-types/should_fail/Overlap15 for an+example.++Note [tcMatchTy vs tcMatchTyKi]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+This module offers two variants of matching: with kinds and without.+The TyKi variant takes two types, of potentially different kinds,+and matches them. Along the way, it necessarily also matches their+kinds. The Ty variant instead assumes that the kinds are already+eqType and so skips matching up the kinds.++How do you choose between them?++1. If you know that the kinds of the two types are eqType, use+   the Ty variant. It is more efficient, as it does less work.++2. If the kinds of variables in the template type might mention type families,+   use the Ty variant (and do other work to make sure the kinds+   work out). These pure unification functions do a straightforward+   syntactic unification and do no complex reasoning about type+   families. Note that the types of the variables in instances can indeed+   mention type families, so instance lookup must use the Ty variant.++   (Nothing goes terribly wrong -- no panics -- if there might be type+   families in kinds in the TyKi variant. You just might get match+   failure even though a reducing a type family would lead to success.)++3. Otherwise, if you're sure that the variable kinds do not mention+   type families and you're not already sure that the kind of the template+   equals the kind of the target, then use the TyKi version.++Note [Unification result]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~+See `UnifyResult` and `UnifyResultM`.  When unifying t1 ~ t2, we return+* Unifiable s, if s is a substitution such that s(t1) is syntactically the+  same as s(t2), modulo type-synonym expansion.+* SurelyApart, if there is no substitution s such that s(t1) = s(t2),+  where "=" includes type-family reductions.+* MaybeApart mar s, when we aren't sure. `mar` is a MaybeApartReason.++Examples+* [a] ~ Maybe b: SurelyApart, because [] and Maybe can't unify++* [(a,Int)] ~ [(Bool,b)]:  Unifiable++* [F Int] ~ [Bool]: MaybeApart MARTypeFamily, because F Int might reduce to Bool+                    (the unifier does not try this)++* a ~ Maybe a: MaybeApart MARInfinite. Not Unifiable clearly, but not SurelyApart+    either; consider+       a := Loop+       where  type family Loop where Loop = Maybe Loop++Wrinkle (UR1): see `combineMAR`+   There is the possibility that two types are MaybeApart for *both* reasons:++   * (a, F Int) ~ (Maybe a, Bool)++   What reason should we use? The *only* consumer of the reason is described+   in Note [Infinitary substitution in lookup] in GHC.Core.InstEnv. The goal+   there is identify which instances might match a target later (but don't+   match now) -- except that we want to ignore the possibility of infinitary+   substitutions. So let's examine a concrete scenario:++     class C a b c+     instance C a (Maybe a) Bool+     -- other instances, including one that will actually match+     [W] C b b (F Int)++   Do we want the instance as a future possibility? No. The only way that+   instance can match is in the presence of an infinite type (infinitely nested+   Maybes). We thus say that `MARInfinite` takes precedence, so that InstEnv treats+   this case as an infinitary substitution case; the fact that a type family is+   involved is only incidental. We thus define `combineMAR` to prefer+   `MARInfinite`.++Note [Apartness and type families]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+Consider this:++  type family F a b where+    F Int Bool = Char+    F a   b    = Double+  type family G a         -- open, no instances++How do we reduce (F (G Float) (G Float))? The first equation clearly doesn't+match immediately while the second equation does. But, before reducing, we must+make sure that the target can never become (F Int Bool). Well, no matter what G+Float becomes, it certainly won't become *both* Int and Bool, so indeed we're+safe reducing (F (G Float) (G Float)) to Double.++So we must say that the argument list+     (G Float) (G Float)   is SurelyApart from   Int Bool++This is necessary not only to get more reductions (which we might be willing to+give up on), but for /substitutivity/. If we have (F x x), we can see that (F x x)+can reduce to Double. So, it had better be the case that (F blah blah) can+reduce to Double, no matter what (blah) is!++To achieve this, `go` in `uVarOrFam` does this;++* We maintain /two/ substitutions, not just one:+     * um_tv_env: the regular substitution, mapping TyVar :-> Type+     * um_fam_env: maps (TyCon,[Type]) :-> Type, where the LHS is a type-fam application+  In effect, these constitute one substitution mapping+     CanEqLHS :-> Types++* When we attempt to unify (G Float) ~ Int, we return MaybeApart..+  but we /also/ add a "family substitution" [G Float :-> Int],+  to `um_fam_env`. See the `BindMe` case of `go` in `uVarOrFam`.++* When we later encounter (G Float) ~ Bool, we apply the family substitution,+  very much as we apply the conventional [tyvar :-> type] substitution+  when we encounter a type variable.  See the `lookupFamEnv` in `go` in+  `uVarOrFam`.++  So (G Float ~ Bool) becomes (Int ~ Bool) which is SurelyApart.  Bingo.+++Wrinkles++(ATF0) Once we encounter a type-family application, we only ever return+             MaybeApart   or   SurelyApart+  but never `Unifiable`.  Accordingly, we only return a TyCoVar substitution+  from `tcUnifyTys` and friends; we don't return a type-family substitution as+  well.  (We could imagine doing so, though.)++(ATF1) Exactly the same mechanism is used in class-instance checking.+    If we have+        instance C (Maybe b)+        instance {-# OVERLAPPING #-} C (Maybe Bool)+        [W] C (Maybe (F a))+    we want to know that the second instance might match later, when we know more about `a`.+    The function `GHC.Core.InstEnv.instEnvMatchesAndUnifiers` uses `tcUnifyTysFG` to+    account for type families in the type being matched.++(ATF2) A very similar check is made in `GHC.Tc.Utils.Unify.mightEqualLater`, which+  again uses `tcUnifyTysFG` to account for the possibility of type families.  See+  Note [What might equal later?] in GHC.Tc.Utils.Unify, esp example (10).++(ATF3) What about foralls?   For example, supppose we are unifying+           (forall a. F a) -> (forall a. F a)+   against some other type. Those two (F a) types are unrelated, bound by+   different foralls; we cannot extend the um_fam_env with a binding [F a :-> blah]++   So to keep things simple, the entire family-substitution machinery is used+   only if there are no enclosing foralls (see the `under_forall` check in+   `uSatFamApp`).  That's fine, because the apartness business is used only for+   reducing type-family applications, and class instances, and their arguments+   can't have foralls anyway.++   The bottom line is that we won't discover that+       (forall a. (a, F Int, F Int))+   is surely apart from+       (forall a. (a, Int, Bool))+   but that doesn't matter.  Fixing this would be possible, but would require+   quite a bit of head-scratching.++(ATF4) The family substitution only has /saturated/ family applications in+   its domain. Consider the following concrete example from #16995:++     type family Param :: Type -> Type   -- arity 0++     type family LookupParam (a :: Type) :: Type where+       LookupParam (f Char) = Bool+       LookupParam x        = Int++     foo :: LookupParam (Param ())+     foo = 42++   In order for `foo` to typecheck, `LookupParam (Param ())` must reduce to+   `Int`.  So    (f Char) ~ (Param ())   must be SurelyApart.  Remember, since+   `Param` is a nullary type family, it is over-saturated in (Param ()).+   This unification will only be SurelyApart if we decompose the outer AppTy+   separately, to then give (() ~ Char).++   Not only does this allow more programs to be accepted, it's also important+   for correctness. Not doing this was the root cause of the Core Lint error+   in #16995.++(ATF5) Consider+          instance (Generic1 f, Ord (Rep1 f a))+                => Ord (Generically1 f a) where ...+              -- The "..." gives rise to [W] Ord (Generically1 f a)+   where Rep1 is a type family.++   We must use the instance decl (recursively) to simplify the [W] constraint;+   we do /not/ want to worry that the `[G] Ord (Rep1 f a)` might be an+   alternative path.  So `noMatchableGivenDicts` must return False;+   so `mightMatchLater` must return False; so when um_bind_fam_fun returns+   `DontBindMe`, the unifier must return `SurelyApart`, not `MaybeApart`.  See+   `go` in `uVarOrFam`++   This looks a bit sketchy, because they aren't SurelyApart, but see+   Note [What might equal later?] in GHC.Tc.Utils.Unify, esp "Red Herring".++   If we are under a forall, we return `MaybeApart`; that seems more conservative,+   and class constraints are on tau-types so it doesn't matter.++(ATF6) When /matching/ can we ever have a type-family application on the LHS, in+   the template?  You might think not, because type-class-instance and+   type-family-instance heads can't include type families.  E.g.+            instance C (F a) where ...  -- Illegal++   But you'd be wrong: even when matching, we can see type families in the LHS template:+   * In `checkValidClass`, in `check_dm` we check that the default method has the+      right type, using matching, both ways.  And that type may have type-family+      applications in it. Examples in test CoOpt_Singletons and T26457.++   * In the specialiser: see the call to `tcMatchTy` in+     `GHC.Core.Opt.Specialise.beats_or_same`++   * With -fpolymorphic-specialisation, we might get a specialiation rule like+         RULE forall a (d :: Eq (Maybe (F a))) .+                 f @(Maybe (F a)) d = ...+     See #25965.++   * A user-written RULE could conceivably have a type-family application+     in the template.  It might not be a good rule, but I don't think we currently+     check for this.++    In all these cases we are only interested in finding a substitution /for+    type variables/ that makes the match work.  So we simply want to recurse into+    the arguments of the type family.  E.g.+       Template:   forall a.  Maybe (F a)+       Target:     Maybe (F Int)+    We want to succeed with substitution [a :-> Int].  See (ATF9).++    Conclusion: where we enter via `tcMatchTy`, `tcMatchTys`, `tc_match_tys`,+    etc, we always end up in `tc_match_tys_x`.  There we invoke the unifier+    but we do not distinguish between `SurelyApart` and `MaybeApart`. So in+    these cases we can set `um_bind_fam_fun` to `neverBindFam`.++(ATF7) There is one other, very special case of matching where we /do/ want to+   bind type families in `um_fam_env`, namely in GHC.Tc.Solver.Equality, the call+   to `tcUnifyTyForInjectivity False` in `improve_injective_wanted_top`.+   Consider+   of a match. Consider+      type family G6 a = r | r -> a+      type instance G6 [a]  = [G a]+      type instance G6 Bool = Int+   and suppose we have a Wanted constraint+      [W] G6 alpha ~ [Int]+   According to Section 5.2 of "Injective type families for Haskell", we /match/+   the RHS each of type instance with [Int].  So we try+        Template: [G a]    Target: [Int]+   and we want to succeed with MaybeApart, so that we can generate the improvement+   constraint+        [W] alpha ~ [beta]+   where beta is fresh.  We do this by binding [G a :-> Int]++(ATF8) The treatment of type families is governed by+         um_bind_fam_fun :: BindFamFun+  in UMEnv, where+         type BindFamFun = TyCon -> [Type] -> Type -> BindFlag+  There are some simple BindFamFun functions provided:+     alwaysBindFam    do the clever stuff above+     neverBindFam     treat type families as SurelyApart+     dontCareBindFam  type families shouldn't exist at all+  This function only affects the difference between the results MaybeApart and+  SurelyApart; it never does not affect whether or not we return Unifiable.++(ATF9) Decomposition.  Consider unifying+          F a  ~  F Int+  when `um_bind_fam_fun` says DontBindMe.  There is a unifying substitition [a :-> Int],+  and we want to find it, returning Unifiable. Why?+    - Remember, this is the Core unifier -- we are not doing type inference+    - When we have two equal types, like  F a ~ F a, it is ridiculous to say that they+      are MaybeApart.  Example: the two-way tcMatchTy in `checkValidClass` and #26457.++  (ATF9-1) But consider unifying+          F Int ~ F Bool+    Although Int and Bool are SurelyApart, we must return MaybeApart for the outer+    unification.  Hence the use of `don'tBeSoSure` in `go_fam_fam`; it leaves Unifiable+    alone, but weakens `SurelyApart` to `MaybeApart`.++  (ATF9-2) We want this decomposition to occur even under a forall (this was #26457).+    E.g.    (forall a. F Int) -> Int  ~   (forall a. F Int) ~ Int+++(ATF10) Injectivity.  Consider (AFT9) where F is known to be injective.  Then if we+  are unifying+          F Int ~ F Bool+  we /can/ say SurelyApart.  See the inj/noninj stuff in `go_fam_fam`.++(ATF11) Consider unifying+          [F Int, F Int, F Bool]  ~  [F Bool, Char, Double]+  We find (F Int ~ F Bool), so we can decompose.  But we /also/ want to remember+  the substitution [F Int :-> F Bool].  Then from (F Int ~ Char) we get the+  substitution [F Bool :-> Char].  And that flat-out contradicts (F Bool ~ Double)+  so we should get SurelyApart.++  Key point: when decomposing (F tys1 ~ F tys2), we should /also/ extend the+  type-family substitution.++  (ATF11-1) All this cleverness only matters when unifying, not when matching++(ATF12) There is a horrid exception for the injectivity check. See (UR1) in+  in Note [Specification of unification].++(ATF13) We have to be careful about the occurs check.+  See Note [The occurs check in the Core unifier]++SIDE NOTE.  The paper "Closed type families with overlapping equations"+http://research.microsoft.com/en-us/um/people/simonpj/papers/ext-f/axioms-extended.pdf+tries to achieve the same effect with a standard yes/no unifier, by "flattening"+the types (replacing each type-family application with a fresh type variable)+and then unifying.  But that does not work well. Consider (#25657)++    type MyEq :: k -> k -> Bool+    type family MyEq a b where+       MyEq a a = 'True+       MyEq _ _ = 'False++    type Var :: forall {k}. Tag -> k+    type family Var tag = a | a -> tag++Then, because Var is injective, we want+     MyEq (Var A) (Var B) --> False+     MyEq (Var A) (Var A) --> True++But if we flattten the types (Var A) and (Var B) we'll just get fresh type variables,+and all is lost.  But with the current algorithm we have that+    a a   ~    (Var A) (Var B)+is SurelyApart, so the first equation definitely doesn't match and we can try the+second, which does.  END OF SIDE NOTE.++Note [Shortcomings of the apartness test]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+Note [Apartness and type families] is very clever.++But it still has shortcomings (#26358).  Consider unifying+    [F a, F Int, Int]  ~  [Bool, Char, a]+Working left to right you might think we would build the mapping+  F a   :-> Bool+  F Int :-> Char+Now we discover that `a` unifies with `Int`. So really these two lists are Apart+because F Int can't be both Bool and Char.++Just the same applies when adding a type-family binding to um_fam_env:+  [F (G Float), F Int, G Float] ~ [Bool, Char, Iont]+Again these are Apart, because (G Float = Int),+and (F Int) can't be both Bool and Char++But achieving this is very tricky! Perhaps whenever we unify a type variable,+or a type family, we should run it over the domain and (maybe range) of the+type-family mapping too?  Sigh.++For now we make no such attempt.+* The um_fam_env has only /un-substituted/ types.+* We look up only /un-substituted/ types in um_fam_env++This may make us say MaybeApart when we could say SurelyApart, but it has no+effect on the correctness of unification: if we return Unifiable, it really is+Unifiable.++This is all quite subtle. suppose we have:+    um_tv_env:   c :-> b+    um_fam_env   F b :-> a+and we are trying to add a :-> F c. We will call lookupFamEnv on (F, [c]), which will+fail because b and c are not equal. So we go ahead and add a :-> F c as a new tyvar eq,+getting:+    um_tv_env:   a :-> F c, c :-> b+    um_fam_env   F b :-> a++Does that loop, like this:+   a --> F c --> F b --> a?+No, because we do not substitute (F c) to (F b) and then look up in um_fam_env;+we look up only un-substituted types.+-}++{- *********************************************************************+*                                                                      *+                Binding decisions+*                                                                      *+********************************************************************* -}++data BindFlag+  = BindMe      -- ^ A bindable type variable++  | DontBindMe  -- ^ Do not bind this type variable is /apart/+                -- See also Note [Super skolems: binding when looking up instances]+                -- in GHC.Core.InstEnv.+  deriving Eq++-- | Some unification functions are parameterised by a 'BindTvFun', which+-- says whether or not to allow a certain unification to take place.+-- A 'BindTvFun' takes the 'TyVar' involved along with the 'Type' it will+-- potentially be bound to.+--+-- It is possible for the variable to actually be a coercion variable+-- (Note [Matching coercion variables]), but only when one-way matching.+-- In this case, the 'Type' will be a 'CoercionTy'.+type BindTvFun = TyCoVar -> Type -> BindFlag++-- | BindFamFun is similiar to BindTvFun, but deals with a saturated+-- type-family application.  See Note [Apartness and type families].+type BindFamFun = TyCon -> [Type] -> Type -> BindFlag++-- | Allow binding only for any variable in the set. Variables may+-- be bound to any type.+-- Used when doing simple matching; e.g. can we find a substitution+--+-- @+-- S = [a :-> t1, b :-> t2] such that+--     S( Maybe (a, b->Int )  =   Maybe (Bool, Char -> Int)+-- @+matchBindTv :: TyCoVarSet -> BindTvFun+matchBindTv tvs tv _ty+  | tv `elemVarSet` tvs = BindMe+  | otherwise           = DontBindMe++-- | Allow the binding of any variable to any type+alwaysBindTv :: BindTvFun+alwaysBindTv _tv _ty = BindMe++-- | Allow the binding of a type-family application to any type+alwaysBindFam :: BindFamFun+-- See (ATF8) in Note [Apartness and type families]+alwaysBindFam _tc _args _rhs = BindMe++dontCareBindFam :: HasCallStack => BindFamFun+-- See (ATF8) in Note [Apartness and type families]+dontCareBindFam tc args rhs+  = pprPanic "dontCareBindFam" $+    vcat [ ppr tc <+> ppr args, text "rhs" <+> ppr rhs ]++-- | Don't allow the binding of a type-family application at all+neverBindFam :: BindFamFun+-- See (ATF8) in Note [Apartness and type families]+neverBindFam _tc _args _rhs = DontBindMe+++{- *********************************************************************+*                                                                      *+                Various wrappers for matching+*                                                                      *+********************************************************************* -}++-- | @tcMatchTy t1 t2@ produces a substitution (over fvs(t1))+-- @s@ such that @s(t1)@ equals @t2@.+-- The returned substitution might bind coercion variables,+-- if the variable is an argument to a GADT constructor.+--+-- Precondition: typeKind ty1 `eqType` typeKind ty2+--+-- We don't pass in a set of "template variables" to be bound+-- by the match, because tcMatchTy (and similar functions) are+-- always used on top-level types, so we can bind any of the+-- free variables of the LHS.+-- See also Note [tcMatchTy vs tcMatchTyKi]+tcMatchTy :: HasDebugCallStack => Type -> Type -> Maybe Subst+tcMatchTy ty1 ty2 = tcMatchTys [ty1] [ty2]++tcMatchTyX_BM :: HasDebugCallStack+              => BindTvFun -> Subst+              -> Type -> Type -> Maybe Subst+tcMatchTyX_BM bind_tv subst ty1 ty2+  = tc_match_tys_x bind_tv False subst [ty1] [ty2]++-- | Like 'tcMatchTy', but allows the kinds of the types to differ,+-- and thus matches them as well.+-- See also Note [tcMatchTy vs tcMatchTyKi]+tcMatchTyKi :: HasDebugCallStack => Type -> Type -> Maybe Subst+tcMatchTyKi ty1 ty2+  = tc_match_tys alwaysBindTv True [ty1] [ty2]++-- | This is similar to 'tcMatchTy', but extends a substitution+-- See also Note [tcMatchTy vs tcMatchTyKi]+tcMatchTyX :: HasDebugCallStack+           => Subst               -- ^ Substitution to extend+           -> Type                -- ^ Template+           -> Type                -- ^ Target+           -> Maybe Subst+tcMatchTyX subst ty1 ty2+  = tc_match_tys_x alwaysBindTv False subst [ty1] [ty2]++-- | Like 'tcMatchTy' but over a list of types.+-- See also Note [tcMatchTy vs tcMatchTyKi]+tcMatchTys :: HasDebugCallStack+           => [Type]         -- ^ Template+           -> [Type]         -- ^ Target+           -> Maybe Subst    -- ^ One-shot; in principle the template+                             -- variables could be free in the target+                             -- See (CU6) in Note [The Core unifier]+tcMatchTys tys1 tys2+  = tc_match_tys alwaysBindTv False tys1 tys2++-- | Like 'tcMatchTyKi' but over a list of types.+-- See also Note [tcMatchTy vs tcMatchTyKi]+tcMatchTyKis :: HasDebugCallStack+             => [Type]         -- ^ Template+             -> [Type]         -- ^ Target+             -> Maybe Subst    -- ^ One-shot substitution+                               -- See (CU6) in Note [The Core unifier]+tcMatchTyKis tys1 tys2+  = tc_match_tys alwaysBindTv True tys1 tys2++-- | Like 'tcMatchTys', but extending a substitution+-- See also Note [tcMatchTy vs tcMatchTyKi]+tcMatchTysX :: HasDebugCallStack+            => Subst          -- ^ Substitution to extend+            -> [Type]         -- ^ Template+            -> [Type]         -- ^ Target+            -> Maybe Subst    -- ^ One-shot substitution+tcMatchTysX subst tys1 tys2+  = tc_match_tys_x alwaysBindTv False subst tys1 tys2++-- | Like 'tcMatchTyKis', but extending a substitution+-- See also Note [tcMatchTy vs tcMatchTyKi]+tcMatchTyKisX :: HasDebugCallStack+              => Subst        -- ^ Substitution to extend+              -> [Type]       -- ^ Template+              -> [Type]       -- ^ Target+              -> Maybe Subst  -- ^ One-shot substitution+tcMatchTyKisX subst tys1 tys2+  = tc_match_tys_x alwaysBindTv True subst tys1 tys2++-- | Same as tc_match_tys_x, but starts with an empty substitution+tc_match_tys :: HasDebugCallStack+             => BindTvFun+             -> Bool          -- ^ match kinds?+             -> [Type]+             -> [Type]+             -> Maybe Subst+tc_match_tys bind_me match_kis tys1 tys2+  = tc_match_tys_x bind_me match_kis (mkEmptySubst in_scope) tys1 tys2+  where+    in_scope = mkInScopeSet (tyCoVarsOfTypes tys1 `unionVarSet` tyCoVarsOfTypes tys2)++-- | Worker for 'tcMatchTysX' and 'tcMatchTyKisX'+tc_match_tys_x :: HasDebugCallStack+               => BindTvFun+               -> Bool          -- ^ match kinds?+               -> Subst+               -> [Type]+               -> [Type]+               -> Maybe Subst+tc_match_tys_x bind_tv match_kis (Subst in_scope id_env tv_env cv_env) tys1 tys2+  = case tc_unify_tys neverBindFam  -- (ATF7) in Note [Apartness and type families]+                      bind_tv+                      False  -- Matching, not unifying+                      False  -- Not an injectivity check+                      match_kis+                      RespectMultiplicities+                      (mkRnEnv2 in_scope) tv_env cv_env tys1 tys2 of+      Unifiable (tv_env', cv_env')+        -> Just $ Subst in_scope id_env tv_env' cv_env'+      _ -> Nothing++-- | This one is called from the expression matcher,+-- which already has a MatchEnv in hand+ruleMatchTyKiX+  :: TyCoVarSet          -- ^ template variables+  -> RnEnv2+  -> TvSubstEnv          -- ^ type substitution to extend+  -> Type                -- ^ Template+  -> Type                -- ^ Target+  -> Maybe TvSubstEnv+ruleMatchTyKiX tmpl_tvs rn_env tenv tmpl target+-- See Note [Kind coercions in Unify]+  = case tc_unify_tys neverBindFam (matchBindTv tmpl_tvs)+      -- neverBindFam: a type family probably shouldn't appear+      -- on the LHS of a RULE, although we don't currently prevent it.+      -- But even if it did, (ATF8) in Note [Apartness and type families]+      -- says it doesn't matter becuase here we only care about Unifiable.+      -- So neverBindFam is efficient, and sufficient.+                      False    -- Matching, not unifying+                      False    -- No doing an injectivity check+                      True     -- Match the kinds+                      IgnoreMultiplicities+                        -- See Note [Rewrite rules ignore multiplicities in FunTy]+                      rn_env tenv emptyCvSubstEnv [tmpl] [target] of+      Unifiable (tenv', _) -> Just tenv'+      _                    -> Nothing++{-+************************************************************************+*                                                                      *+                GADTs+*                                                                      *+************************************************************************++Note [Pruning dead case alternatives]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+Consider        data T a where+                   T1 :: T Int+                   T2 :: T a++                newtype X = MkX Int+                newtype Y = MkY Char++                type family F a+                type instance F Bool = Int++Now consider    case x of { T1 -> e1; T2 -> e2 }++The question before the house is this: if I know something about the type+of x, can I prune away the T1 alternative?++Suppose x::T Char.  It's impossible to construct a (T Char) using T1,+        Answer = YES we can prune the T1 branch (clearly)++Suppose x::T (F a), where 'a' is in scope.  Then 'a' might be instantiated+to 'Bool', in which case x::T Int, so+        ANSWER = NO (clearly)++We see here that we want precisely the apartness check implemented within+tcUnifyTysFG. So that's what we do! Two types cannot match if they are surely+apart. Note that since we are simply dropping dead code, a conservative test+suffices.+-}++-- | Given a list of pairs of types, are any two members of a pair surely+-- apart, even after arbitrary type function evaluation and substitution?+typesCantMatch :: [(Type,Type)] -> Bool+-- See Note [Pruning dead case alternatives]+typesCantMatch prs = any (uncurry typesAreApart) prs++typesAreApart :: Type -> Type -> Bool+typesAreApart t1 t2 = case tcUnifyTysFG alwaysBindFam alwaysBindTv [t1] [t2] of+                        SurelyApart -> True+                        _           -> False+{-+************************************************************************+*                                                                      *+             Various wrappers for unification+*                                                                      *+********************************************************************* -}++-- | Simple unification of two types; all type variables are bindable+-- Precondition: the kinds are already equal+tcUnifyTy :: Type -> Type       -- All tyvars are bindable+          -> Maybe Subst+                       -- A regular one-shot (idempotent) substitution+tcUnifyTy t1 t2 = tcUnifyTys alwaysBindTv [t1] [t2]++tcUnifyDebugger :: Type -> Type -> Maybe Subst+tcUnifyDebugger t1 t2+  = case tc_unify_tys_fg+             True            -- Unify kinds+             neverBindFam    -- Does not affect Unifiable, so pick max efficient+                             -- See (ATF8) in Note [Apartness and type families]+             alwaysBindTv+             [t1] [t2] of+      Unifiable subst -> Just subst+      _               -> Nothing++-- | Like 'tcUnifyTys' but also unifies the kinds+tcUnifyFunDeps :: TyCoVarSet+               -> [Type] -> [Type]+               -> Maybe Subst+tcUnifyFunDeps qtvs tys1 tys2+  = case tc_unify_tys_fg+             True               -- Unify kinds+             dontCareBindFam    -- Class-instance heads never mention type families+             (matchBindTv qtvs)+             tys1 tys2 of+      Unifiable subst -> Just subst+      _               -> Nothing++-- | Unify or match a type-family RHS with a type (possibly another type-family RHS)+-- Precondition: kinds are the same+tcUnifyTyForInjectivity+    :: AmIUnifying  -- ^ True <=> do two-way unification;+                    --   False <=> do one-way matching.+                    --   See end of sec 5.2 from the paper+    -> InScopeSet     -- Should include the free tyvars of both Type args+    -> Type -> Type   -- Types to unify+    -> Maybe Subst+-- This algorithm is an implementation of the "Algorithm U" presented in+-- the paper "Injective type families for Haskell", Figures 2 and 3.+-- The code is incorporated with the standard unifier for convenience, but+-- its operation should match the specification in the paper.+tcUnifyTyForInjectivity unif in_scope t1 t2+  = case tc_unify_tys alwaysBindFam alwaysBindTv+                       unif   -- Am I unifying?+                       True   -- Do injectivity checks+                       False  -- Don't check outermost kinds+                       RespectMultiplicities+                       rn_env emptyTvSubstEnv emptyCvSubstEnv+                       [t1] [t2] of+      Unifiable          (tv_subst, _cv_subst) -> Just $ maybe_fix tv_subst+      MaybeApart _reason (tv_subst, _cv_subst) -> Just $ maybe_fix tv_subst+                 -- We want to *succeed* in questionable cases.+                 -- This is a pre-unification algorithm.+      SurelyApart      -> Nothing+  where+    rn_env   = mkRnEnv2 in_scope++    maybe_fix | unif      = niFixSubst in_scope+              | otherwise = mkTvSubst in_scope -- when matching, don't confuse+                                               -- domain with range++-----------------+tcUnifyTys :: BindTvFun+           -> [Type] -> [Type]+           -> Maybe Subst+                                -- ^ A regular one-shot (idempotent) substitution+                                -- that unifies the erased types. See comments+                                -- for 'tcUnifyTysFG'++-- The two types may have common type variables, and indeed do so in the+-- second call to tcUnifyTys in GHC.Tc.Instance.FunDeps.checkClsFD+tcUnifyTys bind_fn tys1 tys2+  = case tcUnifyTysFG neverBindFam bind_fn tys1 tys2 of+      Unifiable result -> Just result+      _                -> Nothing++-- | (tcUnifyTysFG bind_fam bind_tv tys1 tys2) does "fine-grain" unification+-- of tys1 and tys2, under the control of `bind_fam` and `bind_tv`.+-- This version requires that the kinds of the types are the same,+-- if you unify left-to-right.+-- See Note [The Core unifier]+tcUnifyTysFG :: BindFamFun -> BindTvFun+             -> [Type] -> [Type]+             -> UnifyResult+tcUnifyTysFG bind_fam bind_tv tys1 tys2+  = tc_unify_tys_fg False bind_fam bind_tv tys1 tys2++tc_unify_tys_fg :: Bool+                -> BindFamFun -> BindTvFun+                -> [Type] -> [Type]+                -> UnifyResult+tc_unify_tys_fg match_kis bind_fam bind_tv tys1 tys2+  = do { (tv_env, _) <- tc_unify_tys bind_fam bind_tv+                                  True       -- Unifying+                                  False      -- Not doing an injectivity check+                                  match_kis  -- Match outer kinds+                                  RespectMultiplicities rn_env+                                  emptyTvSubstEnv emptyCvSubstEnv+                                  tys1 tys2+       ; return $ niFixSubst in_scope tv_env }+  where+    in_scope = mkInScopeSet $ tyCoVarsOfTypes tys1 `unionVarSet` tyCoVarsOfTypes tys2+    rn_env   = mkRnEnv2 in_scope++-- | This function is actually the one to call the unifier -- a little+-- too general for outside clients, though.+tc_unify_tys :: BindFamFun -> BindTvFun+             -> AmIUnifying -- ^ True <=> unify; False <=> match+             -> Bool        -- ^ True <=> doing an injectivity check+             -> Bool        -- ^ True <=> treat the kinds as well+             -> MultiplicityFlag -- ^ see Note [Rewrite rules ignore multiplicities in FunTy] in GHC.Core.Unify+             -> RnEnv2+             -> TvSubstEnv  -- ^ substitution to extend+             -> CvSubstEnv+             -> [Type] -> [Type]+             -> UnifyResultM (TvSubstEnv, CvSubstEnv)+-- NB: It's tempting to ASSERT here that, if we're not matching kinds, then+-- the kinds of the types should be the same. However, this doesn't work,+-- as the types may be a dependent telescope, where later types have kinds+-- that mention variables occurring earlier in the list of types. Here's an+-- example (from typecheck/should_fail/T12709):+--   template: [rep :: RuntimeRep,       a :: TYPE rep]+--   target:   [LiftedRep :: RuntimeRep, Int :: TYPE LiftedRep]+-- We can see that matching the first pair will make the kinds of the second+-- pair equal. Yet, we still don't need a separate pass to unify the kinds+-- of these types, so it's appropriate to use the Ty variant of unification.+-- See also Note [tcMatchTy vs tcMatchTyKi].+tc_unify_tys bind_fam bind_tv unif inj_check match_kis match_mults rn_env tv_env cv_env tys1 tys2+  = initUM tv_env cv_env $+    do { when match_kis $+         unify_tys env kis1 kis2+       ; unify_tys env tys1 tys2 }+  where+    env = UMEnv { um_bind_tv_fun  = bind_tv+                , um_bind_fam_fun = bind_fam+                , um_foralls      = emptyVarSet+                , um_unif         = unif+                , um_inj_tf       = inj_check+                , um_arr_mult     = match_mults+                , um_rn_env       = rn_env }++    kis1 = map typeKind tys1+    kis2 = map typeKind tys2+++{- *********************************************************************+*                                                                      *+                UnifyResult, MaybeApart etc+*                                                                      *+********************************************************************* -}++{- Note [Rewrite rules ignore multiplicities in FunTy]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+Consider the following (higher-order) rule:++m :: Bool -> Bool -> Bool+{-# RULES "m" forall f. m (f True) = f #-}++let x = m ((,) @Bool @Bool True True)++The rewrite rule expects an `f :: Bool -> Bool`, but `(,) @Bool @Bool True ::+Bool %1 -> Bool` is linear (see Note [Data constructors are linear by default]+in GHC.Core.Multiplicity) Should the rule match? Yes! According to the+principles laid out in Note [Linting linearity] in GHC.Core.Lint, optimisation+shouldn't be constrained by linearity.++However, when matching the template variable `f` to `(,) True`, we do check that+their types unify (see Note [Matching variable types] in GHC.Core.Rules). So+when unifying types for the sake of rule-matching, the unification algorithm+must be able to ignore multiplicities altogether.++How is this done?+  (1) The `um_arr_mult` field of `UMEnv` recordsw when we are doing rule-matching,+      and hence want to ignore multiplicities.+  (2) The field is set to True in by `ruleMatchTyKiX`.+  (3) It is consulted when matching `FunTy` in `unify_ty`.++Wrinkle in (3). In `unify_tc_app`, in `unify_ty`, `FunTy` is handled as if it+was a regular type constructor. In this case, and when the types being unified+are *function* arrows, but not constraint arrows, then the first argument is a+multiplicity.++We select this situation by comparing the type constructor with fUNTyCon. In+this case, and this case only, we can safely drop the first argument (using the+tail function) and unify the rest.++Note [The substitution in MaybeApart]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+The constructor MaybeApart carries data with it, typically a TvSubstEnv. Why?+Because consider unifying these:++(a, a, Int) ~ (b, [b], Bool)++If we go left-to-right, we start with [a |-> b]. Then, on the middle terms, we+apply the subst we have so far and discover that we need [b |-> [b]]. Because+this fails the occurs check, we say that the types are MaybeApart (see above+Note [Infinitary substitutions]). But, we can't stop there! Because if we+continue, we discover that Int is SurelyApart from Bool, and therefore the+types are apart. This has practical consequences for the ability for closed+type family applications to reduce. See test case+indexed-types/should_compile/Overlap14.+-}++-- This type does double-duty. It is used in the UM (unifier monad) and to+-- return the final result. See Note [Unification result]+type UnifyResult = UnifyResultM Subst++-- | See Note [Unification result]+data UnifyResultM a = Unifiable a        -- the subst that unifies the types+                    | MaybeApart MaybeApartReason+                                 a       -- the subst has as much as we know+                                         -- it must be part of a most general unifier+                                         -- See Note [The substitution in MaybeApart]+                    | SurelyApart+                    deriving Functor++-- | Why are two types 'MaybeApart'? 'MARInfinite' takes precedence:+-- This is used (only) in Note [Infinitary substitution in lookup] in GHC.Core.InstEnv+-- As of Feb 2022, we never differentiate between MARTypeFamily and MARTypeVsConstraint;+-- it's really only MARInfinite that's interesting here.+data MaybeApartReason+  = MARTypeFamily   -- ^ matching e.g. F Int ~? Bool++  | MARInfinite     -- ^ matching e.g. a ~? Maybe a++  | MARTypeVsConstraint  -- ^ matching Type ~? Constraint or the arrow types+    -- See Note [Type and Constraint are not apart] in GHC.Builtin.Types.Prim++  | MARCast         -- ^ Very obscure.+    -- See (KCU2) in Note [Kind coercions in Unify]+++combineMAR :: MaybeApartReason -> MaybeApartReason -> MaybeApartReason+-- See (UR1) in Note [Unification result] for why MARInfinite wins+combineMAR MARInfinite         _ = MARInfinite   -- MARInfinite wins+combineMAR MARTypeFamily       r = r             -- Otherwise it doesn't really matter+combineMAR MARTypeVsConstraint r = r+combineMAR MARCast             r = r++instance Outputable MaybeApartReason where+  ppr MARTypeFamily       = text "MARTypeFamily"+  ppr MARInfinite         = text "MARInfinite"+  ppr MARTypeVsConstraint = text "MARTypeVsConstraint"+  ppr MARCast             = text "MARCast"++instance Semigroup MaybeApartReason where+  (<>) = combineMAR++instance Applicative UnifyResultM where+  pure  = Unifiable+  (<*>) = ap++instance Monad UnifyResultM where+  SurelyApart  >>= _ = SurelyApart+  MaybeApart r1 x >>= f = case f x of+                            Unifiable y     -> MaybeApart r1 y+                            MaybeApart r2 y -> MaybeApart (r1 S.<> r2) y+                            SurelyApart     -> SurelyApart+  Unifiable x  >>= f = f x++instance Outputable a => Outputable (UnifyResultM a) where+  ppr SurelyApart      = text "SurelyApart"+  ppr (Unifiable x)    = text "Unifiable" <+> ppr x+  ppr (MaybeApart r x) = text "MaybeApart" <+> ppr r <+> ppr x++{-+************************************************************************+*                                                                      *+                Non-idempotent substitution+*                                                                      *+************************************************************************++Note [Non-idempotent substitution]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+During unification we use a TvSubstEnv/CvSubstEnv pair that is+  (a) non-idempotent+  (b) loop-free; ie repeatedly applying it yields a fixed point++Note [Finding the substitution fixpoint]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+Finding the fixpoint of a non-idempotent substitution arising from a+unification is much trickier than it looks, because of kinds.  Consider+   T k (H k (f:k)) ~ T * (g:*)+If we unify, we get the substitution+   [ k -> *+   , g -> H k (f:k) ]+To make it idempotent we don't want to get just+   [ k -> *+   , g -> H * (f:k) ]+We also want to substitute inside f's kind, to get+   [ k -> *+   , g -> H k (f:*) ]+If we don't do this, we may apply the substitution to something,+and get an ill-formed type, i.e. one where typeKind will fail.+This happened, for example, in #9106.++It gets worse.  In #14164 we wanted to take the fixpoint of+this substitution+   [ xs_asV :-> F a_aY6 (z_aY7 :: a_aY6)+                        (rest_aWF :: G a_aY6 (z_aY7 :: a_aY6))+   , a_aY6  :-> a_aXQ ]++We have to apply the substitution for a_aY6 two levels deep inside+the invocation of F!  We don't have a function that recursively+applies substitutions inside the kinds of variable occurrences (and+probably rightly so).++So, we work as follows:++ 1. Start with the current substitution (which we are+    trying to fixpoint+       [ xs :-> F a (z :: a) (rest :: G a (z :: a))+       , a  :-> b ]++ 2. Take all the free vars of the range of the substitution:+       {a, z, rest, b}+    NB: the free variable finder closes over+    the kinds of variable occurrences++ 3. If none are in the domain of the substitution, stop.+    We have found a fixpoint.++ 4. Remove the variables that are bound by the substitution, leaving+       {z, rest, b}++ 5. Do a topo-sort to put them in dependency order:+       [ b :: *, z :: a, rest :: G a z ]++ 6. Apply the substitution left-to-right to the kinds of these+    tyvars, extending it each time with a new binding, so we+    finish up with+       [ xs   :-> ..as before..+       , a    :-> b+       , b    :-> b    :: *+       , z    :-> z    :: b+       , rest :-> rest :: G b (z :: b) ]+    Note that rest now has the right kind++ 7. Apply this extended substitution (once) to the range of+    the /original/ substitution.  (Note that we do the+    extended substitution would go on forever if you tried+    to find its fixpoint, because it maps z to z.)++ 8. And go back to step 1++In Step 6 we use the free vars from Step 2 as the initial+in-scope set, because all of those variables appear in the+range of the substitution, so they must all be in the in-scope+set.  But NB that the type substitution engine does not look up+variables in the in-scope set; it is used only to ensure no+shadowing.+-}++niFixSubst :: InScopeSet -> TvSubstEnv -> Subst+-- Find the idempotent fixed point of the non-idempotent substitution+-- This is surprisingly tricky:+--   see Note [Finding the substitution fixpoint]+-- ToDo: use laziness instead of iteration?+niFixSubst in_scope tenv+  | not_fixpoint = niFixSubst in_scope (mapVarEnv (substTy subst) tenv)+  | otherwise    = subst+  where+    range_fvs :: FV+    range_fvs = tyCoFVsOfTypes (nonDetEltsUFM tenv)+          -- It's OK to use nonDetEltsUFM here because the+          -- order of range_fvs, range_tvs is immaterial++    range_tvs :: [TyVar]+    range_tvs = fvVarList range_fvs++    not_fixpoint  = any in_domain range_tvs+    in_domain tv  = tv `elemVarEnv` tenv++    free_tvs = scopedSort (filterOut in_domain range_tvs)++    -- See Note [Finding the substitution fixpoint], Step 6+    subst = foldl' add_free_tv+                  (mkTvSubst in_scope tenv)+                  free_tvs++    add_free_tv :: Subst -> TyVar -> Subst+    add_free_tv subst tv+      = extendTvSubst subst tv (mkTyVarTy tv')+     where+        tv' = updateTyVarKind (substTy subst) tv++{-+************************************************************************+*                                                                      *+                unify_ty: the main workhorse+*                                                                      *+************************************************************************++Note [Specification of unification]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+The pure unifier, unify_ty, defined in this module, tries to work out+a substitution to make two types say True to eqType. NB: eqType is+itself not purely syntactic; it accounts for CastTys;+see Note [Non-trivial definitional equality] in GHC.Core.TyCo.Rep++Unlike the "impure unifiers" in the typechecker (the eager unifier in+GHC.Tc.Utils.Unify, and the constraint solver itself in GHC.Tc.Solver.Equality),+the pure unifier does /not/ work up to ~.++The algorithm implemented here is rather delicate, and we depend on it+to uphold certain properties. This is a summary of these required+properties.++Notation:+ θ,φ  substitutions+ ξ    type-function-free types+ τ,σ  other types+ τ♭   type τ, flattened++ ≡    eqType++(U1) Soundness.+     If (unify τ₁ τ₂) = Unifiable θ, then θ(τ₁) ≡ θ(τ₂).+     θ is a most general unifier for τ₁ and τ₂.++(U2) Completeness.+     If (unify ξ₁ ξ₂) = SurelyApart,+     then there exists no substitution θ such that θ(ξ₁) ≡ θ(ξ₂).++These two properties are stated as Property 11 in the "Closed Type Families"+paper (POPL'14). Below, this paper is called [CTF].++(U3) Apartness under substitution.+     If (unify ξ τ♭) = SurelyApart, then (unify ξ θ(τ)♭) = SurelyApart,+     for any θ. (Property 12 from [CTF])++(U4) Apart types do not unify.+     If (unify ξ τ♭) = SurelyApart, then there exists no θ+     such that θ(ξ) = θ(τ). (Property 13 from [CTF])++THEOREM. Completeness w.r.t ~+    If (unify τ₁♭ τ₂♭) = SurelyApart,+    then there exists no proof that (τ₁ ~ τ₂).++PROOF. See appendix of [CTF].+++The unification algorithm is used for type family injectivity, as described+in the "Injective Type Families" paper (Haskell'15), called [ITF]. When run+in this mode, it has the following properties.++(I1) If (unify σ τ) = SurelyApart, then σ and τ are not unifiable, even+     after arbitrary type family reductions.++(I2) If (unify σ τ) = MaybeApart θ, and if some+     φ exists such that φ(σ) ~ φ(τ), then φ extends θ.+++Furthermore, the RULES matching algorithm requires this property,+but only when using this algorithm for matching:++(M1) If (match σ τ) succeeds with θ, then all matchable tyvars+     in σ are bound in θ.++     Property M1 means that we must extend the substitution with,+     say (a ↦ a) when appropriate during matching.+     See also Note [Self-substitution when unifying or matching].++(M2) Completeness of matching.+     If θ(σ) = τ, then (match σ τ) = Unifiable φ,+     where θ is an extension of φ.++Wrinkle (SI1): um_inj_tf:+    Sadly, property M2 and I2 conflict. Consider++    type family F1 a b where+      F1 Int    Bool   = Char+      F1 Double String = Char++    Consider now two matching problems:++    P1. match (F1 a Bool) (F1 Int Bool)+    P2. match (F1 a Bool) (F1 Double String)++    In case P1, we must find (a ↦ Int) to satisfy M2.  In case P2, we must /not/+    find (a ↦ Double), in order to satisfy I2. (Note that the correct mapping for+    I2 is (a ↦ Int). There is no way to discover this, but we mustn't map a to+    anything else!)++    We thus must parameterize the algorithm over whether it's being used+    for an injectivity check (refrain from looking at non-injective arguments+    to type families) or not (do indeed look at those arguments).  This is+    implemented  by the um_inj_tf field of UMEnv.++    (It's all a question of whether or not to include equation (7) from Fig. 2+    of [ITF].)++    This extra parameter is a bit fiddly, perhaps, but seemingly less so than+    having two separate, almost-identical algorithms.++Note [Self-substitution when unifying or matching]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+What happens when we are unifying or matching two identical type variables?+     a ~ a++* When /unifying/, just succeed, without binding [a :-> a] in the substitution,+  else we'd get an infinite substitution.  We need to make this check before+  we do the occurs check, of course.++* When /matching/, and `a` is a bindable variable from the template, we /do/+  want to extend the substitution.  Remember, a successful match should map all+  the template variables (except ones that disappear when expanding synonyms),++  But when `a` is /not/ a bindable variable (perhaps it is a globally-in-scope+  skolem) we want to treat it like a constant `Int ~ Int` and succeed.++  Notice: no occurs check!  It's fine to match (a ~ Maybe a), because the+  template vars of the template come from a different name space to the free+  vars of the target.++  Note that this arrangement was provoked by a real failure, where the same+  unique ended up in the template as in the target. (It was a rule firing when+  compiling Data.List.NonEmpty.)++* What about matching a /non-bindable/ variable?  For example:+      template-vars   : {a}+      matching problem: (forall b. b -> a) ~ (forall c. c -> Int)+  We want to emerge with the substitution [a :-> Int]+  But on the way we will encounter (b ~ b), when we match the bits before the+  arrow under the forall, having renamed `c` to `b`.  This match should just+  succeed, just like (Int ~ Int), without extending the substitution.++  It's important to do this for /non-bindable/ variables, not just for+  forall-bound ones.  In an associated type+         instance C (Maybe a) where {  type F (Maybe a) = Int }+  `checkConsistentFamInst` matches (Maybe a) from the header against (Maybe a)+  from the type-family instance, with `a` marked as non-bindable.+++Note [Matching coercion variables]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+Consider this:++   type family F a++   data G a where+     MkG :: F a ~ Bool => G a++   type family Foo (x :: G a) :: F a+   type instance Foo MkG = False++We would like that to be accepted. For that to work, we need to introduce+a coercion variable on the left and then use it on the right. Accordingly,+at use sites of Foo, we need to be able to use matching to figure out the+value for the coercion. (See the desugared version:++   axFoo :: [a :: *, c :: F a ~ Bool]. Foo (MkG c) = False |> (sym c)++) We never want this action to happen during *unification* though, when+all bets are off.++Note [Kind coercions in Unify]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+We wish to match/unify while ignoring casts. But, we can't just ignore+them completely, or we'll end up with ill-kinded substitutions. For example,+say we're matching `a` with `ty |> co`. If we just drop the cast, we'll+return [a |-> ty], but `a` and `ty` might have different kinds. We can't+just match/unify their kinds, either, because this might gratuitously+fail. After all, `co` is the witness that the kinds are the same -- they+may look nothing alike.++So, we pass a kind coercion `kco` to the main `unify_ty`. This coercion witnesses+the equality between the substed kind of the left-hand type and the substed+kind of the right-hand type. Note that we do not unify kinds at the leaves+(as we did previously).++Hence: (UKINV) Unification Kind Invariant+* In the call+     unify_ty ty1 ty2 kco+  it must be that+     subst(kco) :: subst(kind(ty1)) ~N subst(kind(ty2))+  where `subst` is the ambient substitution in the UM monad+* In the call+     unify_tys tys1 tys2+  (which has no kco), after we unify any prefix of tys1,tys2, the kinds of the+  head of the remaining tys1,tys2 are identical after substitution.  This+  implies, for example, that the kinds of the head of tys1,tys2 are identical+  after substitution.++Preserving (UKINV) takes a bit of work, governed by the `match_kis` flag in+`tc_unify_tys`:++* When we're working with type applications (either TyConApp or AppTy) we+  need to worry about establishing (UKINV), as the kinds of the function+  & arguments aren't (necessarily) included in the kind of the result.+  When unifying two TyConApps, this is easy, because the two TyCons are+  the same. Their kinds are thus the same. As long as we unify left-to-right,+  we'll be sure to unify types' kinds before the types themselves. (For example,+  think about Proxy :: forall k. k -> *. Unifying the first args matches up+  the kinds of the second args.)++* For AppTy, we must unify the kinds of the functions, but once these are+  unified, we can continue unifying arguments without worrying further about+  kinds.++* The interface to this module includes both "...Ty" functions and+  "...TyKi" functions. The former assume that (UKINV) is already+  established, either because the kinds are the same or because the+  list of types being passed in are the well-typed arguments to some+  type constructor (see two paragraphs above). The latter take a separate+  pre-pass over the kinds to establish (UKINV). Sometimes, it's important+  not to take the second pass, as it caused #12442.++Wrinkles++(KCU1) We ensure that the `kco` argument never mentions variables in the+  domain of either RnEnvL or RnEnvR.  Why?++  * `kco` is used only to build the final well-kinded substitution+         a :-> ty |> kco+    The range of the substitution never mentions forall-bound variables,+    so `kco` cannot either.++  * `kco` mixes up types from both left and right arguments of+    `unify_ty`, which have different renamings in the RnEnv2.++  The easiest thing is to insist that `kco` does not need renaming with+  the RnEnv2; it mentions no forall-bound variables.++  To achieve this we do a `mentionsForAllBoundTyVars` test in the+  `CastTy` cases of `unify_ty`.++(KCU2) Suppose we are unifying+            (forall a. x |> (...F a b...) ~ (forall a. y)+  We can't bind y :-> x |> (...F a b...), becuase of that free `a`.++  But if we later learn that b=Int, and F a Int = Bool,+  that free `a` might disappear, so we could unify with+      y :-> x |> (...Bool...)++  Conclusion: if there is a free forall-bound variable in a cast,+  return MaybeApart, with a MaybeApartReason of MARCast.++(KCU3) We thought, at one point, that this was all unnecessary: why should+    casts be in types in the first place? But they are sometimes. In+    dependent/should_compile/KindEqualities2, we see, for example the+    constraint Num (Int |> (blah ; sym blah)).  We naturally want to find+    a dictionary for that constraint, which requires dealing with+    coercions in this manner.++Note [Matching in the presence of casts (1)]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+When matching, it is crucial that no variables from the template+end up in the range of the matching substitution (obviously!).+When unifying, that's not a constraint; instead we take the fixpoint+of the substitution at the end.++So what should we do with this, when matching?+   unify_ty (tmpl |> co) tgt kco++Previously, wrongly, we pushed 'co' in the (horrid) accumulating+'kco' argument like this:+   unify_ty (tmpl |> co) tgt kco+     = unify_ty tmpl tgt (kco ; co)++But that is obviously wrong because 'co' (from the template) ends+up in 'kco', which in turn ends up in the range of the substitution.++This all came up in #13910.  Because we match tycon arguments+left-to-right, the ambient substitution will already have a matching+substitution for any kinds; so there is an easy fix: just apply+the substitution-so-far to the coercion from the LHS.++Note that++* When matching, the first arg of unify_ty is always the template;+  we never swap round.++* The above argument is distressingly indirect. We seek a+  better way.++* One better way is to ensure that type patterns (the template+  in the matching process) have no casts.  See #14119.++Note [Matching in the presence of casts (2)]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+There is another wrinkle (#17395).  Suppose (T :: forall k. k -> Type)+and we are matching+   tcMatchTy (T k (a::k))  (T j (b::j))++Then we'll match k :-> j, as expected. But then in unify_tys+we invoke+   unify_tys env (a::k) (b::j) (Refl j)++Although we have unified k and j, it's very important that we put+(Refl j), /not/ (Refl k) as the fourth argument to unify_tys.+If we put (Refl k) we'd end up with the substitution+  a :-> b |> Refl k+which is bogus because one of the template variables, k,+appears in the range of the substitution.  Eek.++Similar care is needed in unify_ty_app.+++Note [Polykinded tycon applications]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+Suppose  T :: forall k. Type -> K+and we are unifying+  ty1:  T @Type         Int       :: Type+  ty2:  T @(Type->Type) Int Int   :: Type++These two TyConApps have the same TyCon at the front but they+(legitimately) have different numbers of arguments.  They+are surelyApart, so we can report that without looking any+further (see #15704).++Note [Unifying type applications]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+Unifying type applications is quite subtle, as we found+in #23134 and #22647, when type families are involved.++Suppose+   type family F a :: Type -> Type+   type family G k :: k = r | r -> k++and consider these examples:++* F Int ~ F Char, where F is injective+  Since F is injective, we can reduce this to Int ~ Char,+  therefore SurelyApart.++* F Int ~ F Char, where F is not injective+  Without injectivity, return MaybeApart.++* G Type ~ G (Type -> Type) Int+  Even though G is injective and the arguments to G are different,+  we cannot deduce apartness because the RHS is oversaturated.+  For example, G might be defined as+    G Type = Maybe Int+    G (Type -> Type) = Maybe+  So we return MaybeApart.++* F Int Bool ~ F Int Char       -- SurelyApart (since Bool is apart from Char)+  F Int Bool ~ Maybe a          -- MaybeApart+  F Int Bool ~ a b              -- MaybeApart+  F Int Bool ~ Char -> Bool     -- MaybeApart+  An oversaturated type family can match an application,+  whether it's a TyConApp, AppTy or FunTy. Decompose.++* F Int ~ a b+  We cannot decompose a saturated, or under-saturated+  type family application. We return MaybeApart.++To handle all those conditions, unify_ty goes through+the following checks in sequence, where Fn is a type family+of arity n:++* (C1) Fn x_1 ... x_n ~ Fn y_1 .. y_n+  A saturated application.+  Here we can unify arguments in which Fn is injective.+* (C2) Fn x_1 ... x_n ~ anything, anything ~ Fn x_1 ... x_n+  A saturated type family can match anything - we return MaybeApart.+* (C3) Fn x_1 ... x_m ~ a b, a b ~ Fn x_1 ... x_m where m > n+  An oversaturated type family can be decomposed.+* (C4) Fn x_1 ... x_m ~ anything, anything ~ Fn x_1 ... x_m, where m > n+  If we couldn't decompose in the previous step, we return SurelyApart.++Afterwards, the rest of the code doesn't have to worry about type families.++Note [Unifying type synonyms]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+Consider the task of unifying two 'Type's of the form++  TyConApp tc [] ~ TyConApp tc []++where `tc` is a type synonym. A naive way to perform this comparison these+would first expand the synonym and then compare the resulting expansions.++However, this is obviously wasteful and the RHS of `tc` may be large; it is+much better to rather compare the TyCons directly. Consequently, before+expanding type synonyms in type comparisons we first look for a nullary+TyConApp and simply compare the TyCons if we find one.++Of course, if we find that the TyCons are *not* equal then we still need to+perform the expansion as their RHSs may still be unifiable.  E.g+    type T = S (a->a)+    type S a = [a]+and consider+    T Int ~ S (Int -> Int)++We can't decompose non-nullary synonyms.  E.g.+    type R a = F a    -- Where F is a type family+and consider+    R (a->a) ~ R Int+We can't conclude that  (a->) ~ Int.  (There is a currently-missed opportunity+here; if we knew that R was /injective/, perhaps we could decompose.)++We perform the nullary-type-synonym optimisation in a number of places:++ * GHC.Core.Unify.unify_ty+ * GHC.Tc.Solver.Equality.can_eq_nc'+ * GHC.Tc.Utils.Unify.uType++This optimisation is especially helpful for the ubiquitous GHC.Types.Type,+since GHC prefers to use the type synonym over @TYPE 'LiftedRep@ applications+whenever possible. See Note [Using synonyms to compress types] in+GHC.Core.Type for details.++c.f. Note [Comparing type synonyms] in GHC.Core.TyCo.Compare+-}++-------------- unify_ty: the main workhorse -----------++type AmIUnifying = Bool   -- True  <=> Unifying+                          -- False <=> Matching++type InType      = Type       -- Before applying the RnEnv2+type OutCoercion = Coercion   -- After applying the RnEnv2+++unify_ty :: UMEnv+         -> InType -> InType  -- Types to be unified+         -> OutCoercion       -- A nominal coercion between their kinds+                              -- OutCoercion: the RnEnv has already been applied+                              -- When matching, the coercion is in "target space",+                              --   not "template space"+                              -- See Note [Kind coercions in Unify]+         -> UM ()+-- Precondition: see (Unification Kind Invariant)+--+-- See Note [Specification of unification]+-- Respects newtypes, PredTypes+-- See Note [Computing equality on types] in GHC.Core.Type+unify_ty _env (TyConApp tc1 []) (TyConApp tc2 []) _kco+  -- See Note [Unifying type synonyms]+  | tc1 == tc2+  = return ()++unify_ty env ty1 ty2 kco+    -- Now handle the cases we can "look through": synonyms and casts.+  | Just ty1' <- coreView ty1 = unify_ty env ty1' ty2 kco+  | Just ty2' <- coreView ty2 = unify_ty env ty1 ty2' kco++unify_ty env (CastTy ty1 co1) ty2 kco+  | mentionsForAllBoundTyVarsL env (tyCoVarsOfCo co1)+    -- See (KCU1) in Note [Kind coercions in Unify]+  = maybeApart MARCast  -- See (KCU2)++  | um_unif env+  = unify_ty env ty1 ty2 (co1 `mkTransCo` kco)++  | otherwise -- We are matching, not unifying+  = do { subst <- getSubst env+       ; let co' = substCo subst co1+         -- We match left-to-right, so the free template vars of the+         -- coercion should already have been matched.+         -- See Note [Matching in the presence of casts (1)]+         -- NB: co1 does not mention forall-bound vars, so no need to rename+       ; unify_ty env ty1 ty2 (co' `mkTransCo` kco) }++unify_ty env ty1 (CastTy ty2 co2) kco+  | mentionsForAllBoundTyVarsR env (tyCoVarsOfCo co2)+    -- See (KCU1) in Note [Kind coercions in Unify]+  = maybeApart MARCast  -- See (KCU2)+  | otherwise+  = unify_ty env ty1 ty2 (kco `mkTransCo` mkSymCo co2)+    -- NB: co2 does not mention forall-bound variables++-- Applications need a bit of care!+-- They can match FunTy and TyConApp, so use splitAppTy_maybe+unify_ty env (AppTy ty1a ty1b) ty2 _kco+  | Just (ty2a, ty2b) <- tcSplitAppTyNoView_maybe ty2+  = unify_ty_app env ty1a [ty1b] ty2a [ty2b]++unify_ty env ty1 (AppTy ty2a ty2b) _kco+  | Just (ty1a, ty1b) <- tcSplitAppTyNoView_maybe ty1+  = unify_ty_app env ty1a [ty1b] ty2a [ty2b]++unify_ty _ (LitTy x) (LitTy y) _kco | x == y = return ()++unify_ty env (ForAllTy (Bndr tv1 _) ty1) (ForAllTy (Bndr tv2 _) ty2) kco+  -- ToDo: See Note [Unifying coercion-foralls]+  = do { unify_ty env (varType tv1) (varType tv2) (mkNomReflCo liftedTypeKind)+       ; let env' = umRnBndr2 env tv1 tv2+       ; unify_ty env' ty1 ty2 kco }++-- See Note [Matching coercion variables]+unify_ty env (CoercionTy co1) (CoercionTy co2) kco+  = do { c_subst <- getCvSubstEnv+       ; case co1 of+           CoVarCo cv+             | not (um_unif env)+             , not (cv `elemVarEnv` c_subst)   -- Not forall-bound+             , let (_mult_co, co_l, co_r) = decomposeFunCo kco+                     -- Because the coercion is used in a type, it should be safe to+                     -- ignore the multiplicity coercion, _mult_co+                      -- cv :: t1 ~ t2+                      -- co2 :: s1 ~ s2+                      -- co_l :: t1 ~ s1+                      -- co_r :: t2 ~ s2+                   rhs_co = co_l `mkTransCo` co2 `mkTransCo` mkSymCo co_r+             , BindMe <- um_bind_tv_fun env cv (CoercionTy rhs_co)+             -> if mentionsForAllBoundTyVarsR env (tyCoVarsOfCo co2)+                then surelyApart+                else extendCvEnv cv rhs_co++           _ -> return () }++unify_ty env (TyVarTy tv1) ty2 kco+  = uVarOrFam env (TyVarLHS tv1) ty2 kco++unify_ty env ty1 (TyVarTy tv2) kco+  | um_unif env  -- If unifying, can swap args; but not when matching+  = uVarOrFam (umSwapRn env) (TyVarLHS tv2) ty1 (mkSymCo kco)++-- Deal with TyConApps+unify_ty env ty1 ty2 kco+  -- Handle non-oversaturated type families first+  -- See Note [Unifying type applications]+  | Just (tc,tys) <- mb_sat_fam_app1+  = uVarOrFam env (TyFamLHS tc tys) ty2 kco++  | um_unif env+  , Just (tc,tys) <- mb_sat_fam_app2+  = uVarOrFam (umSwapRn env) (TyFamLHS tc tys) ty1 (mkSymCo kco)++  -- Handle oversaturated type families. Suppose we have+  --     (F a b) ~ (c d)    where F has arity 1+  -- We definitely want to decompose that type application! (#22647)+  --+  -- If there is no application, an oversaturated type family can only+  -- match a type variable or a saturated type family,+  -- both of which we handled earlier. So we can say surelyApart.+  | Just (tc1, _) <- mb_tc_app1+  , isTypeFamilyTyCon tc1+  = if | Just (ty1a, ty1b) <- tcSplitAppTyNoView_maybe ty1+       , Just (ty2a, ty2b) <- tcSplitAppTyNoView_maybe ty2+       -> unify_ty_app env ty1a [ty1b] ty2a [ty2b]            -- (C3)+       | otherwise -> surelyApart                             -- (C4)++  | Just (tc2, _) <- mb_tc_app2+  , isTypeFamilyTyCon tc2+  = if | Just (ty1a, ty1b) <- tcSplitAppTyNoView_maybe ty1+       , Just (ty2a, ty2b) <- tcSplitAppTyNoView_maybe ty2+       -> unify_ty_app env ty1a [ty1b] ty2a [ty2b]            -- (C3)+       | otherwise -> surelyApart                             -- (C4)++  -- At this point, neither tc1 nor tc2 can be a type family.+  | Just (tc1, tys1) <- mb_tc_app1+  , Just (tc2, tys2) <- mb_tc_app2+  , tc1 == tc2+  = do { massertPpr (isInjectiveTyCon tc1 Nominal) (ppr tc1)+       ; unify_tc_app env tc1 tys1 tys2+       }++  -- TYPE and CONSTRAINT are not Apart+  -- See Note [Type and Constraint are not apart] in GHC.Builtin.Types.Prim+  -- NB: at this point we know that the two TyCons do not match+  | Just (tc1,_) <- mb_tc_app1, let u1 = tyConUnique tc1+  , Just (tc2,_) <- mb_tc_app2, let u2 = tyConUnique tc2+  , (u1 == tYPETyConKey && u2 == cONSTRAINTTyConKey) ||+    (u2 == tYPETyConKey && u1 == cONSTRAINTTyConKey)+  = maybeApart MARTypeVsConstraint+    -- We don't bother to look inside; wrinkle (W3) in GHC.Builtin.Types.Prim+    -- Note [Type and Constraint are not apart]++  -- The arrow types are not Apart+  -- See Note [Type and Constraint are not apart] in GHC.Builtin.Types.Prim+  --     wrinkle (W2)+  -- NB1: at this point we know that the two TyCons do not match+  -- NB2: In the common FunTy/FunTy case you might wonder if we want to go via+  --      splitTyConApp_maybe.  But yes we do: we need to look at those implied+  --      kind argument in order to satisfy (Unification Kind Invariant)+  | FunTy {} <- ty1+  , FunTy {} <- ty2+  = maybeApart MARTypeVsConstraint+    -- We don't bother to look inside; wrinkle (W3) in GHC.Builtin.Types.Prim+    -- Note [Type and Constraint are not apart]++  where+    mb_tc_app1 = splitTyConApp_maybe ty1+    mb_tc_app2 = splitTyConApp_maybe ty2+    mb_sat_fam_app1 = isSatTyFamApp ty1+    mb_sat_fam_app2 = isSatTyFamApp ty2++unify_ty _ _ _ _ = surelyApart++-----------------------------+unify_tc_app :: UMEnv -> TyCon -> [Type] -> [Type] -> UM ()+-- Mainly just unifies the argument types;+-- but with a special case for fUNTyCon+unify_tc_app env tc tys1 tys2+  | tc == fUNTyCon+  , IgnoreMultiplicities <- um_arr_mult env+  , (_mult1 : no_mult_tys1) <- tys1+  , (_mult2 : no_mult_tys2) <- tys2+  = -- We're comparing function arrow types here (not constraint arrow+    -- types!), and they have at least one argument, which is the arrow's+    -- multiplicity annotation. The flag `um_arr_mult` instructs us to+    -- ignore multiplicities in this very case. This is a little tricky: see+    -- point (3) in Note [Rewrite rules ignore multiplicities in FunTy].+     unify_tys env no_mult_tys1 no_mult_tys2++  | otherwise+  = unify_tys env tys1 tys2++-----------------------------+unify_ty_app :: UMEnv -> Type -> [Type] -> Type -> [Type] -> UM ()+-- Deal with (t1 t1args) ~ (t2 t2args)+-- where   length t1args = length t2args+unify_ty_app env ty1 ty1args ty2 ty2args+  | Just (ty1', ty1a) <- splitAppTyNoView_maybe ty1+  , Just (ty2', ty2a) <- splitAppTyNoView_maybe ty2+  = unify_ty_app env ty1' (ty1a : ty1args) ty2' (ty2a : ty2args)++  | otherwise+  = do { let ki1 = typeKind ty1+             ki2 = typeKind ty2+           -- See Note [Kind coercions in Unify]+       ; unify_ty  env ki1 ki2 (mkNomReflCo liftedTypeKind)+       ; unify_ty  env ty1 ty2 (mkNomReflCo ki2)+                 -- Very important: 'ki2' not 'ki1'+                 -- See Note [Matching in the presence of casts (2)]+       ; unify_tys env ty1args ty2args }++-----------------------------+unify_tys :: UMEnv -> [Type] -> [Type] -> UM ()+-- Precondition: see (Unification Kind Invariant)+unify_tys env orig_xs orig_ys+  = go orig_xs orig_ys+  where+    go []     []     = return ()+    go (x:xs) (y:ys)+      -- See Note [Kind coercions in Unify]+      = do { unify_ty env x y (mkNomReflCo $ typeKind y)+                 -- Very important: 'y' not 'x'+                 -- See Note [Matching in the presence of casts (2)]+           ; go xs ys }+    go _ _ = surelyApart+      -- Possibly different saturations of a polykinded tycon+      -- See Note [Polykinded tycon applications]++---------------------------------+uVarOrFam :: UMEnv -> CanEqLHS -> InType -> OutCoercion -> UM ()+-- Invariants: (a) If ty1 is a TyFamLHS, then ty2 is NOT a TyVarTy+--             (b) both args have had coreView already applied+-- Why saturated?  See (ATF4) in Note [Apartness and type families]+uVarOrFam env ty1 ty2 kco+  = do { substs <- getSubstEnvs+--       ; pprTrace "uVarOrFam" (vcat+--           [ text "ty1" <+> ppr ty1+--           , text "ty2" <+> ppr ty2+--           , text "tv_env" <+> ppr (um_tv_env substs)+--           , text "fam_env" <+> ppr (um_fam_env substs) ]) $+       ; go NotSwapped substs ty1 ty2 kco }+  where+    foralld_tvs  = um_foralls env+    under_forall = not (isEmptyVarSet foralld_tvs)++    -- `go` takes two bites at the cherry; if the first one fails+    -- it swaps the arguments and tries again; and then it fails.+    -- The SwapFlag argument tells `go` whether it is on the first+    -- bite (NotSwapped) or the second (IsSwapped).+    -- E.g.    a ~ F p q+    --         Starts with: go a (F p q)+    --         if `a` not bindable, swap to: go (F p q) a++    -----------------------------+    -- LHS is a type variable+    -- The sequence of tests is very similar to go_tv+    go :: SwapFlag -> UMState -> CanEqLHS -> InType -> OutCoercion -> UM ()+    go swapped substs lhs@(TyVarLHS tv1) ty2 kco+      | Just ty1' <- lookupVarEnv (um_tv_env substs) tv1'+      = -- We already have a substitution for tv1+        if | um_unif env                          -> unify_ty env ty1' ty2 kco+           | (ty1' `mkCastTy` kco) `tcEqType` ty2 -> return ()+           | otherwise                            -> surelyApart+           -- Unifying: recurse into unify_ty+           -- Matching: we /don't/ want to just recurse here, because the range of+           --    the subst is the target type, not the template type. So, just check+           --    for normal type equality.+           -- NB: it's important to use `tcEqType` instead of `eqType` here,+           -- otherwise we might not reject a substitution+           -- which unifies `Type` with `Constraint`, e.g.+           -- a call to tc_unify_tys with arguments+           --+           --   tys1 = [k,k]+           --   tys2 = [Type, Constraint]+           --+           -- See test cases: T11715b, T20521.++      -- If we are matching or unifying a ~ a, take care+      -- See Note [Self-substitution when unifying or matching]+      | TyVarTy tv2 <- ty2+      , let tv2' = umRnOccR env tv2+      , tv1' == tv2'+      = if | um_unif env     -> return ()+           | tv1_is_bindable -> extendTvEnv tv1' ty2+           | otherwise       -> return ()++      | tv1_is_bindable+      , not (mentionsForAllBoundTyVarsR env ty2_fvs)+            -- ty2_fvs: kco does not mention forall-bound vars+      , not occurs_check+      = -- No occurs check, nor skolem-escape; just bind the tv+        -- We don't need to rename `rhs` because it mentions no forall-bound vars+        extendTvEnv tv1' rhs     -- Bind tv1:=rhs and continue++      -- When unifying, try swapping:+      -- e.g.   a    ~ F p q       with `a` not bindable: we might succeed with go_fam+      -- e.g.   a    ~ beta        with `a` not bindable: we might be able to bind `beta`+      -- e.g.   beta ~ F beta Int  occurs check; but MaybeApart after swapping+      | um_unif env+      , NotSwapped <- swapped  -- If we have swapped already, don't do so again+      , Just lhs2 <- canEqLHS_maybe ty2+      = go IsSwapped substs lhs2 (mkTyVarTy tv1) (mkSymCo kco)++      | occurs_check = maybeApart MARInfinite   -- Occurs check+      | otherwise    = surelyApart++      where+        tv1'            = umRnOccL env tv1+        ty2_fvs         = tyCoVarsOfType ty2+        rhs             = ty2 `mkCastTy` mkSymCo kco+        tv1_is_bindable | not (tv1' `elemVarSet` foralld_tvs)+                          -- tv1' is not forall-bound, but tv1 can still differ+                          -- from tv1; see Note [Cloning the template binders]+                          -- in GHC.Core.Rules.  So give tv1' to um_bind_tv_fun.+                        , BindMe <- um_bind_tv_fun env tv1' rhs+                        = True+                        | otherwise+                        = False++        occurs_check = um_unif env && uOccursCheck substs foralld_tvs lhs rhs+          -- Occurs check, only when unifying+          -- see Note [Infinitary substitutions]+          -- Make sure you include `kco` in rhs #14846++    -----------------------------+    -- LHS is a saturated type-family application+    -- Invariant: ty2 is not a TyVarTy+    go swapped substs lhs@(TyFamLHS tc1 tys1) ty2 kco+      -- Check if we have an existing substitution for the LHS; if so, recurse+      -- But not under a forall; see (ATF3) in Note [Apartness and type families]+      -- Hence the RnEnv2 is empty+      | not under_forall+      , Just ty1' <- lookupFamEnv (um_fam_env substs) tc1 tys1+      = if | um_unif env                          -> unify_ty env ty1' ty2 kco+           -- Below here we are matching+           -- The return () case deals with:+           --    Template:   (F a)..(F a)+           --    Target:     (F b)..(F b)+           -- This should match! With [a :-> b]+           | (ty1' `mkCastTy` kco) `tcEqType` ty2 -> return ()+           | otherwise                            -> maybeApart MARTypeFamily++      -- Check for equality  F tys1 ~ F tys2+      -- Very important that this can happen under a forall, so that we+      -- successfully match  (forall a. F a) ~ (forall b. F b)  See (ATF9-2)+      | Just (tc2, tys2) <- isSatTyFamApp ty2+      , tc1 == tc2+      = go_fam_fam substs tc1 tys1 tys2 kco++      -- If we are under a forall, just give up+      -- see (ATF3) and (ATF5) in Note [Apartness and type families]+      | under_forall+      = maybeApart MARTypeFamily++      -- Now check if we can bind the (F tys) to the RHS+      -- Again, not under a forall; see (ATF3)+      -- This can happen even when matching: see (ATF7)+      | BindMe <- um_bind_fam_fun env tc1 tys1 rhs+      = if uOccursCheck substs emptyVarSet lhs rhs+        then maybeApart MARInfinite+        else do { extendFamEnv tc1 tys1 rhs+                     -- We don't substitute tys1 before extending+                     -- See Note [Shortcomings of the apartness test]+                ; maybeApart MARTypeFamily }++      -- Swap in case of (F a b) ~ (G c d e)+      -- Maybe um_bind_fam_fun is False of (F a b) but true of (G c d e)+      -- NB: a type family can appear on the template when matching+      --     see (ATF6) in Note [Apartness and type families]+      -- (Only worth doing this if we are not under a forall.)+      | um_unif env+      , NotSwapped <- swapped+      , Just lhs2 <- canEqLHS_maybe ty2+      = go IsSwapped substs lhs2 (mkTyConApp tc1 tys1) (mkSymCo kco)++      | otherwise   -- See (ATF5) in Note [Apartness and type families]+      = surelyApart++      where+        rhs = ty2 `mkCastTy` mkSymCo kco++    -----------------------------+    -- go_fam_fam: LHS and RHS are both saturated type-family applications,+    --             for the same type-family F+    go_fam_fam substs tc tys1 tys2 kco+       -- Decompose (F tys1 ~ F tys2): (ATF9)+       -- Use injectivity information of F: (ATF10)+       -- But first bind the type-fam if poss: (ATF11)+      = do { bind_fam_if_poss                 -- (ATF11)+           ; unify_tys env inj_tys1 inj_tys2  -- (ATF10)+           ; unless (um_inj_tf env) $         -- (ATF12)+             don'tBeSoSure MARTypeFamily $    -- (ATF9-1)+             unify_tys env noninj_tys1 noninj_tys2 }+     where+       inj = case tyConInjectivityInfo tc of+                NotInjective -> repeat False+                Injective bs -> bs++       (inj_tys1, noninj_tys1) = partitionByList inj tys1+       (inj_tys2, noninj_tys2) = partitionByList inj tys2++       bind_fam_if_poss+         | not (um_unif env)  -- Not when matching (ATF11-1)+         = return ()+         | under_forall       -- Not under a forall (ATF3)+         = return ()+         | BindMe <- um_bind_fam_fun env tc tys1 rhs1+         = unless (uOccursCheck substs emptyVarSet (TyFamLHS tc tys1) rhs1) $+           extendFamEnv tc tys1 rhs1+         -- At this point um_unif=True, so we can unify either way+         | BindMe <- um_bind_fam_fun env tc tys2 rhs2+         = unless (uOccursCheck substs emptyVarSet (TyFamLHS tc tys2) rhs2) $+           extendFamEnv tc tys2 rhs2+         | otherwise+         = return ()++       rhs1 = mkTyConApp tc tys2 `mkCastTy` mkSymCo kco+       rhs2 = mkTyConApp tc tys1 `mkCastTy` kco+++uOccursCheck :: UMState+             -> TyVarSet -- Bound by enclosing foralls; see (OCU1)+             -> CanEqLHS -> Type   -- Can we unify (lhs := ty)?+             -> Bool+-- See Note [The occurs check in the Core unifier] and (ATF13)+uOccursCheck (UMState { um_tv_env = tv_env, um_fam_env = fam_env }) bvs lhs ty+  = go bvs ty+  where+    go :: TyCoVarSet   -- Bound by enclosing foralls; see (OCU1)+       -> Type -> Bool+    go bvs ty | Just ty' <- coreView ty = go bvs ty'+    go bvs (TyVarTy tv) | Just ty' <- lookupVarEnv tv_env tv+                        = go bvs ty'+                        | TyVarLHS tv' <- lhs, tv==tv'+                        = True+                        | otherwise+                        = go bvs (tyVarKind tv)+    go bvs (AppTy ty1 ty2)           = go bvs ty1 || go bvs ty2+    go _   (LitTy {})                = False+    go bvs (FunTy _ w arg res)       = go bvs w || go bvs arg || go bvs res+    go bvs (TyConApp tc tys)         = go_tc bvs tc tys++    go bvs (ForAllTy (Bndr tv _) ty)+      = go bvs (tyVarKind tv) ||+        (case lhs of+           TyVarLHS tv' | tv==tv'   -> False  -- Shadowing+                        | otherwise -> go (bvs `extendVarSet` tv) ty+           TyFamLHS {} -> False)  -- Lookups don't happen under a forall++    go bvs (CastTy ty  _co) = go bvs ty  -- ToDo: should we worry about `co`?+    go _   (CoercionTy _co) = False      -- ToDo: should we worry about `co`?++    go_tc bvs tc tys+      | isEmptyVarSet bvs   -- Never look up in um_fam_env under a forall (ATF3)+      , isTypeFamilyTyCon tc+      , Just ty' <- lookupFamEnv fam_env tc (take arity tys)+             -- NB: we look up /un-substituted/ types;+             -- See Note [Shortcomings of the apartness test]+      = go bvs ty' || any (go bvs) (drop arity tys)++      | TyFamLHS tc' tys' <- lhs+      , tc == tc'+      , tys `lengthAtLeast` arity  -- Saturated, or over-saturated+      , tcEqTyConAppArgs tys tys'+      = True++      | otherwise+      = any (go bvs) tys+      where+        arity = tyConArity tc++{- Note [The occurs check in the Core unifier]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+The unifier applies both substitutions (um_tv_env and um_fam_env) as it goes,+so we'll get an infinite loop if we have, for example+    um_tv_env:   a :-> F b      -- (1)+    um_fam_env   F b :-> a      -- (2)++So (uOccursCheck substs lhs ty) returns True iff extending `substs` with `lhs :-> ty`+could lead to a loop. That is, could there by a type `s` such that+  applySubsts( (substs + lhs:->ty), s ) is infinite++It's vital that we do both at once: we might have (1) already and add (2);+or we might have (2) already and add (1).++A very similar task is done by GHC.Tc.Utils.Unify.checkTyEqRhs.++(OCU1) We keep track of the forall-bound variables because the um_fam_env is inactive+  under a forall; indeed it is /unsound/ to consult it because we may have a binding+  (F a :-> Int), and then unify (forall a. ...(F a)...) with something.  We don't+  want to map that (F a) to Int!++(OCU2) Performance. Consider unifying+         [a, b] ~ [big-ty, (a,a,a)]+  We'll unify a:=big-ty.  Then we'll attempt b:=(a,a,a), but must do an occurs check.+  So we'll walk over big-ty, looking for `b`.  And then again, and again, once for+  each occurrence of `a`.  A similar thing happens for+         [a, (b,b,b)] ~ [big-ty, (a,a,a)]+  albeit a bit less obviously.++  Potentially we could use a cache to record checks we have already done;+  but I have not attempted that yet.  Precisely similar remarks would apply+  to GHC.Tc.Utils.Unify.checkTyEqRhs++Note [Unifying coercion-foralls]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+Suppose we try to unify (forall cv. t1) ~ (forall cv. t2).+See Note [ForAllTy] in GHC.Core.TyCo.Rep.++The problem with coercion variables is that coercion abstraction is not erased:+the `kco` shouldn't propagate from outside the ForAllTy to inside. Instead, I think+the correct new `kco` for the recursive call is `mkNomReflCo liftedTypeKind` (but I'm+a little worried it might be Constraint sometimes).++This potential problem has been there a long time, and I'm going to let+sleeping dogs lie for now.+-}++{-+************************************************************************+*                                                                      *+                Unification monad+*                                                                      *+************************************************************************+-}++data UMEnv+  = UMEnv { um_unif :: AmIUnifying++          , um_inj_tf :: Bool+            -- Checking for injectivity?+            -- See (SI1) in Note [Specification of unification]++          , um_arr_mult :: MultiplicityFlag+            -- Whether to unify multiplicity arguments when unifying arrows.+            -- See Note [Rewrite rules ignore multiplicities in FunTy]++          , um_rn_env :: RnEnv2+            -- Renaming InTyVars to OutTyVars; this eliminates shadowing, and+            -- lines up matching foralls on the left and right+            -- See (CU2) in Note [The Core unifier]++          , um_foralls :: TyVarSet+            -- OutTyVars bound by a forall in this unification;+            -- Do not bind these in the substitution!+            -- See the function tvBindFlag++          , um_bind_tv_fun :: BindTvFun+            -- User-supplied BindFlag function, for variables not in um_foralls+            -- See (CU1) in Note [The Core unifier]++          , um_bind_fam_fun :: BindFamFun+            -- Similar to um_bind_tv_fun, but for type-family applications+            -- See (ATF8) in Note [Apartness and type families]+          }++type FamSubstEnv = TyConEnv (ListMap TypeMap Type)+  -- Map a TyCon and a list of types to a type+  -- Domain of FamSubstEnv is exactly-saturated type-family+  -- applications (F t1...tn)++lookupFamEnv :: FamSubstEnv -> TyCon -> [Type] -> Maybe Type+lookupFamEnv env tc tys+  = do { tys_map <- lookupTyConEnv env tc+       ; lookupTM tys tys_map }++data UMState = UMState+                   { um_tv_env   :: TvSubstEnv+                   , um_cv_env   :: CvSubstEnv+                   , um_fam_env  :: FamSubstEnv }+  -- um_tv_env, um_cv_env, um_fam_env are all "global" substitutions;+  -- that is, neither their domains nor their ranges mention any variables+  -- in um_foralls; i.e. variables bound by foralls inside the types being unified++  -- When /matching/ um_fam_env is usually empty; but not quite always.+  -- See (ATF7) of Note [Apartness and type families]++newtype UM a+  = UM' { unUM :: UMState -> UnifyResultM (UMState, a) }+    -- See Note [The one-shot state monad trick] in GHC.Utils.Monad++pattern UM :: (UMState -> UnifyResultM (UMState, a)) -> UM a+-- See Note [The one-shot state monad trick] in GHC.Utils.Monad+pattern UM m <- UM' m+  where+    UM m = UM' (oneShot m)+{-# COMPLETE UM #-}++instance Functor UM where+  fmap f (UM m) = UM (\s -> fmap (\(s', v) -> (s', f v)) (m s))++instance Applicative UM where+      pure a = UM (\s -> pure (s, a))+      (<*>)  = ap++instance Monad UM where+  {-# INLINE (>>=) #-}+  -- See Note [INLINE pragmas and (>>)] in GHC.Utils.Monad+  m >>= k  = UM (\state ->+                  do { (state', v) <- unUM m state+                     ; unUM (k v) state' })++instance MonadFail UM where+    fail _   = UM (\_ -> SurelyApart) -- failed pattern match++initUM :: TvSubstEnv  -- subst to extend+       -> CvSubstEnv+       -> UM ()+       -> UnifyResultM (TvSubstEnv, CvSubstEnv)+initUM subst_env cv_subst_env um+  = case unUM um state of+      Unifiable (state, _)    -> Unifiable (get state)+      MaybeApart r (state, _) -> MaybeApart r (get state)+      SurelyApart             -> SurelyApart+  where+    state = UMState { um_tv_env = subst_env+                    , um_cv_env = cv_subst_env+                    , um_fam_env = emptyTyConEnv }+    get (UMState { um_tv_env = tv_env, um_cv_env = cv_env }) = (tv_env, cv_env)++getTvSubstEnv :: UM TvSubstEnv+getTvSubstEnv = UM $ \state -> Unifiable (state, um_tv_env state)++getCvSubstEnv :: UM CvSubstEnv+getCvSubstEnv = UM $ \state -> Unifiable (state, um_cv_env state)++getSubstEnvs :: UM UMState+getSubstEnvs = UM $ \state -> Unifiable (state, state)++getSubst :: UMEnv -> UM Subst+getSubst env = do { tv_env <- getTvSubstEnv+                  ; cv_env <- getCvSubstEnv+                  ; let in_scope = rnInScopeSet (um_rn_env env)+                  ; return (mkTCvSubst in_scope tv_env cv_env) }++extendTvEnv :: TyVar -> Type -> UM ()+extendTvEnv tv ty = UM $ \state ->+  Unifiable (state { um_tv_env = extendVarEnv (um_tv_env state) tv ty }, ())++extendCvEnv :: CoVar -> Coercion -> UM ()+extendCvEnv cv co = UM $ \state ->+  Unifiable (state { um_cv_env = extendVarEnv (um_cv_env state) cv co }, ())++extendFamEnv :: TyCon -> [Type] -> Type -> UM ()+extendFamEnv tc tys ty = UM $ \state ->+  Unifiable (state { um_fam_env = extend (um_fam_env state) tc }, ())+  where+    extend :: FamSubstEnv -> TyCon -> FamSubstEnv+    extend = alterTyConEnv alter_tm++    alter_tm :: Maybe (ListMap TypeMap Type) -> Maybe (ListMap TypeMap Type)+    alter_tm m_elt = Just (alterTM tys (\_ -> Just ty) (m_elt `orElse` emptyTM))++umRnBndr2 :: UMEnv -> TyCoVar -> TyCoVar -> UMEnv+umRnBndr2 env v1 v2+  = env { um_rn_env = rn_env', um_foralls = um_foralls env `extendVarSet` v' }+  where+    (rn_env', v') = rnBndr2_var (um_rn_env env) v1 v2++mentionsForAllBoundTyVarsL, mentionsForAllBoundTyVarsR :: UMEnv -> VarSet -> Bool+-- See (CU2) in Note [The Core unifier]+mentionsForAllBoundTyVarsL = mentions_forall_bound_tvs inRnEnvL+mentionsForAllBoundTyVarsR = mentions_forall_bound_tvs inRnEnvR++mentions_forall_bound_tvs :: (RnEnv2 -> TyVar -> Bool) -> UMEnv -> VarSet -> Bool+mentions_forall_bound_tvs in_rn_env env varset+  | isEmptyVarSet (um_foralls env)               = False+  | anyVarSet (in_rn_env (um_rn_env env)) varset = True+  | otherwise                                    = False+    -- NB: That isEmptyVarSet guard is a critical optimization;+    -- it means we don't have to calculate the free vars of+    -- the type, often saving quite a bit of allocation.++-- | Converts any SurelyApart to a MaybeApart+don'tBeSoSure :: MaybeApartReason -> UM () -> UM ()+don'tBeSoSure r um = UM $ \ state ->+  case unUM um state of+    SurelyApart -> MaybeApart r (state, ())+    other       -> other++umRnOccL :: UMEnv -> TyVar -> TyVar+umRnOccL env v = rnOccL (um_rn_env env) v++umRnOccR :: UMEnv -> TyVar -> TyVar+umRnOccR env v = rnOccR (um_rn_env env) v++umSwapRn :: UMEnv -> UMEnv+umSwapRn env = env { um_rn_env = rnSwap (um_rn_env env) }++maybeApart :: MaybeApartReason -> UM ()+maybeApart r = UM (\state -> MaybeApart r (state, ()))++surelyApart :: UM a+surelyApart = UM (\_ -> SurelyApart)++{-+%************************************************************************+%*                                                                      *+            Matching a (lifted) type against a coercion+%*                                                                      *+%************************************************************************++This section defines essentially an inverse to liftCoSubst. It is defined+here to avoid a dependency from Coercion on this module.++-}++data MatchEnv = ME { me_tmpls :: TyVarSet+                   , me_env   :: RnEnv2 }++-- | 'liftCoMatch' is sort of inverse to 'liftCoSubst'.  In particular, if+--   @liftCoMatch vars ty co == Just s@, then @liftCoSubst s ty == co@,+--   where @==@ there means that the result of 'liftCoSubst' has the same+--   type as the original co; but may be different under the hood.+--   That is, it matches a type against a coercion of the same+--   "shape", and returns a lifting substitution which could have been+--   used to produce the given coercion from the given type.+--   Note that this function is incomplete -- it might return Nothing+--   when there does indeed exist a possible lifting context.+--+-- This function is incomplete in that it doesn't respect the equality+-- in `eqType`. That is, it's possible that this will succeed for t1 and+-- fail for t2, even when t1 `eqType` t2. That's because it depends on+-- there being a very similar structure between the type and the coercion.+-- This incompleteness shouldn't be all that surprising, especially because+-- it depends on the structure of the coercion, which is a silly thing to do.+--+-- The lifting context produced doesn't have to be exacting in the roles+-- of the mappings. This is because any use of the lifting context will+-- also require a desired role. Thus, this algorithm prefers mapping to+-- nominal coercions where it can do so.+liftCoMatch :: TyCoVarSet -> Type -> Coercion -> Maybe LiftingContext+liftCoMatch tmpls ty co+  = do { cenv1 <- ty_co_match menv emptyVarEnv ki ki_co ki_ki_co ki_ki_co+       ; cenv2 <- ty_co_match menv cenv1       ty co+                              (mkNomReflCo co_lkind) (mkNomReflCo co_rkind)+       ; return (LC (mkEmptySubst in_scope) cenv2) }+  where+    menv     = ME { me_tmpls = tmpls, me_env = mkRnEnv2 in_scope }+    in_scope = mkInScopeSet (tmpls `unionVarSet` tyCoVarsOfCo co)+    -- Like tcMatchTy, assume all the interesting variables+    -- in ty are in tmpls++    ki       = typeKind ty+    ki_co    = promoteCoercion co+    ki_ki_co = mkNomReflCo liftedTypeKind++    Pair co_lkind co_rkind = coercionKind ki_co++-- | 'ty_co_match' does all the actual work for 'liftCoMatch'.+ty_co_match :: MatchEnv   -- ^ ambient helpful info+            -> LiftCoEnv  -- ^ incoming subst+            -> Type       -- ^ ty, type to match+            -> Coercion   -- ^ co :: lty ~r rty, coercion to match against+            -> Coercion   -- ^ :: kind(lsubst(ty)) ~N kind(lty)+            -> Coercion   -- ^ :: kind(rsubst(ty)) ~N kind(rty)+            -> Maybe LiftCoEnv+   -- ^ Just env ==> liftCoSubst Nominal env ty == co, modulo roles.+   -- Also: Just env ==> lsubst(ty) == lty and rsubst(ty) == rty,+   -- where lsubst = lcSubstLeft(env) and rsubst = lcSubstRight(env)+ty_co_match menv subst ty co lkco rkco+  | Just ty' <- coreView ty = ty_co_match menv subst ty' co lkco rkco++  -- handle Refl case:+  | tyCoVarsOfType ty `isNotInDomainOf` subst+  , Just (ty', _) <- isReflCo_maybe co+  , ty `eqType` ty'+    -- Why `eqType` and not `tcEqType`? Because this function is only used+    -- during coercion optimisation, after type-checking has finished.+  = Just subst++  where+    isNotInDomainOf :: VarSet -> VarEnv a -> Bool+    isNotInDomainOf set env+      = noneSet (\v -> elemVarEnv v env) set++    noneSet :: (Var -> Bool) -> VarSet -> Bool+    noneSet f = allVarSet (not . f)++ty_co_match menv subst ty co lkco rkco+  | CastTy ty' co' <- ty+     -- See Note [Matching in the presence of casts (1)]+  = let empty_subst  = mkEmptySubst (rnInScopeSet (me_env menv))+        substed_co_l = substCo (liftEnvSubstLeft empty_subst subst)  co'+        substed_co_r = substCo (liftEnvSubstRight empty_subst subst) co'+    in+    ty_co_match menv subst ty' co (substed_co_l `mkTransCo` lkco)+                                  (substed_co_r `mkTransCo` rkco)+