-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Types used in register allocation API -- -- Types used in register allocation API @package reg-alloc-types @version 0.1.0.0 module RegAlloc.Types -- | Each "virtual variable" has details associated with it that affect the -- allocation procedure. data VarInfo VarInfo :: Either PhysReg VarId -> VarKind -> Bool -> VarInfo -- | Identify the variable, or if it is an explicit register reference. [varId] :: VarInfo -> Either PhysReg VarId -- | The kind of a variable determines the scope of its lifetime, and when -- it is spilled or loaded to or from stack. For example, output -- variables are not needed in a basic block until the first point of -- use, while the lifetime of input variables extends until their final -- use. [varKind] :: VarInfo -> VarKind -- | If true, the variable's value must be loaded into a register at this -- use position. [regRequired] :: VarInfo -> Bool type VarId = Int data VarKind Input :: VarKind InputOutput :: VarKind Temp :: VarKind Output :: VarKind -- | Every operation may reference multiple variables and/or specific -- physical registers. If a physical register is referenced, then that -- register is considered unavailable for allocation over its range of -- use. -- -- Certain operations have special significance as to how basic blocks -- are organized and lifetime of allocations. Thus, if an operation -- begins or ends a loop, or represents a method call, this should be -- indicated using the OpKind field. Indication of calls is -- necessary for saving and restoring all registers around a call, while -- indication of loops is optional, as it merely avoids reloading spilled -- variables inside loop bodies. data OpInfo m op1 op2 OpInfo :: (op1 -> OpKind) -> (op1 -> [VarInfo]) -> (PhysReg -> VarId -> PhysReg -> m [op2]) -> (PhysReg -> VarId -> m [op2]) -> (VarId -> PhysReg -> m [op2]) -> (op1 -> [((VarId, VarKind), PhysReg)] -> m [op2]) -> (op1 -> String) -> OpInfo m op1 op2 -- | Return the kind of operator prior to allocation. [opKind] :: OpInfo m op1 op2 -> op1 -> OpKind -- | Return all variable references for the operation. [opRefs] :: OpInfo m op1 op2 -> op1 -> [VarInfo] -- | Create move instruction(s) from one register to another, relating to -- the given variable. [moveOp] :: OpInfo m op1 op2 -> PhysReg -> VarId -> PhysReg -> m [op2] -- | Create a spill instruction from the given restriction, to a stack slot -- for the given variable. [saveOp] :: OpInfo m op1 op2 -> PhysReg -> VarId -> m [op2] -- | Create a load instruction from the stack slot for the given variable, -- to the given register. [restoreOp] :: OpInfo m op1 op2 -> VarId -> PhysReg -> m [op2] -- | Given an operation, and a set of register allocations for each -- variable used by the operation (differentiated by type of use), apply -- the allocations to create one or more post-allocation operations. [applyAllocs] :: OpInfo m op1 op2 -> op1 -> [((VarId, VarKind), PhysReg)] -> m [op2] -- | Render the given pre-allocation operation as a string. [showOp1] :: OpInfo m op1 op2 -> op1 -> String data OpKind IsNormal :: OpKind IsCall :: OpKind IsBranch :: OpKind -- | From the point of view of this library, a basic block is nothing more -- than an ordered sequence of operations. data BlockInfo m blk1 blk2 op1 op2 BlockInfo :: (blk1 -> Int) -> (blk1 -> [Int]) -> (blk1 -> blk1 -> m (blk1, blk1)) -> (blk1 -> ([op1], [op1], [op1])) -> (blk1 -> [op2] -> [op2] -> [op2] -> blk2) -> BlockInfo m blk1 blk2 op1 op2 -- | Identify the block with a unique number. The nature and ordering of -- the number is not significant, only its uniqueness. [blockId] :: BlockInfo m blk1 blk2 op1 op2 -> blk1 -> Int -- | The immediate successors of a block. [blockSuccessors] :: BlockInfo m blk1 blk2 op1 op2 -> blk1 -> [Int] -- | Given two blocks, insert a new block between them to break up a -- "critical edge" (where the first block has multiple destinations due -- to a conditional branch, for example, while the second block has -- multiple originations due to branches from other blocks). The result -- is the new pair of blocks at that boundary. Typically, only one of the -- two will be a newly created block. [splitCriticalEdge] :: BlockInfo m blk1 blk2 op1 op2 -> blk1 -> blk1 -> m (blk1, blk1) -- | Return the entry, body, and exit operation of a block. Typically, the -- entry operation is a "label", and the exit operation is a branch, jump -- or return. [blockOps] :: BlockInfo m blk1 blk2 op1 op2 -> blk1 -> ([op1], [op1], [op1]) -- | Replace the set of operations for a block with a set of allocated -- operations. [setBlockOps] :: BlockInfo m blk1 blk2 op1 op2 -> blk1 -> [op2] -> [op2] -> [op2] -> blk2 type PhysReg = Int data UseVerifier VerifyDisabled :: UseVerifier VerifyEnabled :: UseVerifier VerifyEnabledStrict :: UseVerifier instance GHC.Show.Show RegAlloc.Types.UseVerifier instance GHC.Classes.Eq RegAlloc.Types.UseVerifier instance GHC.Base.Functor m => GHC.Base.Functor (RegAlloc.Types.OpInfo m op1) instance GHC.Show.Show RegAlloc.Types.VarInfo instance GHC.Classes.Eq RegAlloc.Types.VarInfo instance GHC.Show.Show RegAlloc.Types.OpKind instance GHC.Classes.Eq RegAlloc.Types.OpKind instance GHC.Show.Show RegAlloc.Types.VarKind instance GHC.Classes.Eq RegAlloc.Types.VarKind