Safe Haskell | None |
---|---|
Language | Haskell2010 |
- allocate :: forall m blk1 blk2 op1 op2. (Functor m, Applicative m, Monad m) => Int -> BlockInfo m blk1 blk2 op1 op2 -> OpInfo m op1 op2 -> UseVerifier -> [blk1] -> m (String, Either [String] [blk2])
- data UseVerifier
- data BlockInfo m blk1 blk2 op1 op2 = BlockInfo {
- blockId :: blk1 -> Int
- blockSuccessors :: blk1 -> [Int]
- splitCriticalEdge :: blk1 -> blk1 -> m (blk1, blk1)
- blockOps :: blk1 -> ([op1], [op1], [op1])
- setBlockOps :: blk1 -> [op2] -> [op2] -> [op2] -> blk2
- data OpInfo m op1 op2 = OpInfo {}
- data OpKind
- data VarInfo = VarInfo {}
- data VarKind
- = Input
- | InputOutput
- | Temp
- | Output
- type VarId = Int
- type PhysReg = Int
Main entry point
:: (Functor m, Applicative m, Monad m) | |
=> Int | Maximum number of registers to use |
-> BlockInfo m blk1 blk2 op1 op2 | Characterization of blocks |
-> OpInfo m op1 op2 | Characterization of operations |
-> UseVerifier | Whether to use the runtime verifier |
-> [blk1] | A topologically sorted list of blocks |
-> m (String, Either [String] [blk2]) | Status dump and allocated blocks, or error w/ context |
Transform a list of basic blocks, containing variable references, into an equivalent list where each reference has been associated with a register allocation. Artificial save and restore instructions may be inserted into those blocks to indicate spilling and reloading of variables.
In order to call this function, the caller must provide records that functionally characterize these blocks and their operations according to an abstract API. This is done so that any program graph conforming to the API may be used, and no particular representation is required.
A tuple is return where the first value is a textual dump that describes the complete allocation state. If this value is never forced, that data is not collected.
The second value is the resulting list of allocated blocks. If allocation
is found to be impossible -- for example if there are not enough registers
-- a Left
value is returned, with a list of strings describing the error
and its possible context. This is usually when the textual dump should be
provided, if one's user has selected verbose error output, for example.
Blocks
data BlockInfo m blk1 blk2 op1 op2 Source #
From the point of view of this library, a basic block is nothing more than an ordered sequence of operations.
BlockInfo | |
|
Operations
data OpInfo m op1 op2 Source #
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.
OpInfo | |
|
Variables
Each "virtual variable" has details associated with it that affect the allocation procedure.
VarInfo | |
|