diff options
author | Simon Marlow <marlowsd@gmail.com> | 2012-10-14 13:03:32 +0100 |
---|---|---|
committer | Simon Marlow <marlowsd@gmail.com> | 2012-10-19 12:03:16 +0100 |
commit | 6fbd46b0bb3ee56160b8216cb2a3bb718ccb41c2 (patch) | |
tree | 8e8c569d0989f89c66a6ccd0d59a466266130649 /compiler/codeGen/CgStackery.lhs | |
parent | 53810006bbcd3fc9b58893858f95c3432cb33f0e (diff) | |
download | haskell-6fbd46b0bb3ee56160b8216cb2a3bb718ccb41c2.tar.gz |
Remove the old codegen
Except for CgUtils.fixStgRegisters that is used in the NCG and LLVM
backends, and should probably be moved somewhere else.
Diffstat (limited to 'compiler/codeGen/CgStackery.lhs')
-rw-r--r-- | compiler/codeGen/CgStackery.lhs | 371 |
1 files changed, 0 insertions, 371 deletions
diff --git a/compiler/codeGen/CgStackery.lhs b/compiler/codeGen/CgStackery.lhs deleted file mode 100644 index 2f7bdfc083..0000000000 --- a/compiler/codeGen/CgStackery.lhs +++ /dev/null @@ -1,371 +0,0 @@ -% -% (c) The University of Glasgow 2006 -% (c) The GRASP/AQUA Project, Glasgow University, 1992-1998 -% -\section[CgStackery]{Stack management functions} - -Stack-twiddling operations, which are pretty low-down and grimy. -(This is the module that knows all about stack layouts, etc.) - -\begin{code} -{-# OPTIONS -fno-warn-tabs #-} --- The above warning supression flag is a temporary kludge. --- While working on this module you are encouraged to remove it and --- detab the module (please do the detabbing in a separate patch). See --- http://hackage.haskell.org/trac/ghc/wiki/Commentary/CodingStyle#TabsvsSpaces --- for details - -module CgStackery ( - spRel, getVirtSp, getRealSp, setRealSp, - setRealAndVirtualSp, getSpRelOffset, - - allocPrimStack, allocStackTop, deAllocStackTop, - adjustStackHW, getFinalStackHW, - setStackFrame, getStackFrame, - mkVirtStkOffsets, mkStkAmodes, - freeStackSlots, - pushUpdateFrame, pushBHUpdateFrame, emitPushUpdateFrame, - ) where - -#include "HsVersions.h" - -import CgMonad -import CgUtils -import CgProf -import ClosureInfo( CgRep(..), cgRepSizeW ) -import SMRep -import OldCmm -import OldCmmUtils -import CLabel -import DynFlags -import Util -import OrdList -import Outputable - -import Control.Monad -import Data.List -\end{code} - -%************************************************************************ -%* * -\subsection[CgUsages-stackery]{Monad things for fiddling with stack usage} -%* * -%************************************************************************ - -spRel is a little function that abstracts the stack direction. Note that most -of the code generator is dependent on the stack direction anyway, so -changing this on its own spells certain doom. ToDo: remove? - - THIS IS DIRECTION SENSITIVE! - -Stack grows down, positive virtual offsets correspond to negative -additions to the stack pointer. - -\begin{code} -spRel :: VirtualSpOffset -- virtual offset of Sp - -> VirtualSpOffset -- virtual offset of The Thing - -> WordOff -- integer offset -spRel sp off = sp - off -\end{code} - -@setRealAndVirtualSp@ sets into the environment the offsets of the -current position of the real and virtual stack pointers in the current -stack frame. The high-water mark is set too. It generates no code. -It is used to initialise things at the beginning of a closure body. - -\begin{code} -setRealAndVirtualSp :: VirtualSpOffset -- New real Sp - -> Code - -setRealAndVirtualSp new_sp - = do { stk_usg <- getStkUsage - ; setStkUsage (stk_usg {virtSp = new_sp, - realSp = new_sp, - hwSp = new_sp}) } - -getVirtSp :: FCode VirtualSpOffset -getVirtSp - = do { stk_usg <- getStkUsage - ; return (virtSp stk_usg) } - -getRealSp :: FCode VirtualSpOffset -getRealSp - = do { stk_usg <- getStkUsage - ; return (realSp stk_usg) } - -setRealSp :: VirtualSpOffset -> Code -setRealSp new_real_sp - = do { stk_usg <- getStkUsage - ; setStkUsage (stk_usg {realSp = new_real_sp}) } - -getSpRelOffset :: VirtualSpOffset -> FCode CmmExpr -getSpRelOffset virtual_offset - = do dflags <- getDynFlags - real_sp <- getRealSp - return (cmmRegOffW dflags spReg (spRel real_sp virtual_offset)) -\end{code} - - -%************************************************************************ -%* * -\subsection[CgStackery-layout]{Laying out a stack frame} -%* * -%************************************************************************ - -'mkVirtStkOffsets' is given a list of arguments. The first argument -gets the /largest/ virtual stack offset (remember, virtual offsets -increase towards the top of stack). - -\begin{code} -mkVirtStkOffsets - :: DynFlags - -> VirtualSpOffset -- Offset of the last allocated thing - -> [(CgRep,a)] -- things to make offsets for - -> (VirtualSpOffset, -- OUTPUTS: Topmost allocated word - [(a, VirtualSpOffset)]) -- things with offsets (voids filtered out) - -mkVirtStkOffsets dflags init_Sp_offset things - = loop init_Sp_offset [] (reverse things) - where - loop offset offs [] = (offset,offs) - loop offset offs ((VoidArg,_):things) = loop offset offs things - -- ignore Void arguments - loop offset offs ((rep,t):things) - = loop thing_slot ((t,thing_slot):offs) things - where - thing_slot = offset + cgRepSizeW dflags rep - -- offset of thing is offset+size, because we're - -- growing the stack *downwards* as the offsets increase. - --- | 'mkStkAmodes' is a higher-level version of --- 'mkVirtStkOffsets'. It starts from the tail-call locations. --- It returns a single list of addressing modes for the stack --- locations, and therefore is in the monad. It /doesn't/ adjust the --- high water mark. - -mkStkAmodes - :: VirtualSpOffset -- Tail call positions - -> [(CgRep,CmmExpr)] -- things to make offsets for - -> FCode (VirtualSpOffset, -- OUTPUTS: Topmost allocated word - CmmStmts) -- Assignments to appropriate stk slots - -mkStkAmodes tail_Sp things - = do dflags <- getDynFlags - rSp <- getRealSp - let (last_Sp_offset, offsets) = mkVirtStkOffsets dflags tail_Sp things - abs_cs = [ CmmStore (cmmRegOffW dflags spReg (spRel rSp offset)) amode - | (amode, offset) <- offsets - ] - returnFC (last_Sp_offset, toOL abs_cs) -\end{code} - -%************************************************************************ -%* * -\subsection[CgStackery-monadery]{Inside-monad functions for stack manipulation} -%* * -%************************************************************************ - -Allocate a virtual offset for something. - -\begin{code} -allocPrimStack :: CgRep -> FCode VirtualSpOffset -allocPrimStack rep = do dflags <- getDynFlags - allocPrimStack' dflags rep - -allocPrimStack' :: DynFlags -> CgRep -> FCode VirtualSpOffset -allocPrimStack' dflags rep - = do { stk_usg <- getStkUsage - ; let free_stk = freeStk stk_usg - ; case find_block free_stk of - Nothing -> do - { let push_virt_sp = virtSp stk_usg + size - ; setStkUsage (stk_usg { virtSp = push_virt_sp, - hwSp = hwSp stk_usg `max` push_virt_sp }) - -- Adjust high water mark - ; return push_virt_sp } - Just slot -> do - { setStkUsage (stk_usg { freeStk = delete_block free_stk slot }) - ; return slot } - } - where - size :: WordOff - size = cgRepSizeW dflags rep - - -- Find_block looks for a contiguous chunk of free slots - -- returning the offset of its topmost word - find_block :: [VirtualSpOffset] -> Maybe VirtualSpOffset - find_block [] = Nothing - find_block (slot:slots) - | take size (slot:slots) == [slot..top_slot] - = Just top_slot - | otherwise - = find_block slots - where -- The stack grows downwards, with increasing virtual offsets. - -- Therefore, the address of a multi-word object is the *highest* - -- virtual offset it occupies (top_slot below). - top_slot = slot+size-1 - - delete_block free_stk slot = [ s | s <- free_stk, - (s<=slot-size) || (s>slot) ] - -- Retain slots which are not in the range - -- slot-size+1..slot -\end{code} - -Allocate a chunk ON TOP OF the stack. - -\begin{code} -allocStackTop :: WordOff -> FCode () -allocStackTop size - = do { stk_usg <- getStkUsage - ; let push_virt_sp = virtSp stk_usg + size - ; setStkUsage (stk_usg { virtSp = push_virt_sp, - hwSp = hwSp stk_usg `max` push_virt_sp }) } -\end{code} - -Pop some words from the current top of stack. This is used for -de-allocating the return address in a case alternative. - -\begin{code} -deAllocStackTop :: WordOff -> FCode () -deAllocStackTop size - = do { stk_usg <- getStkUsage - ; let pop_virt_sp = virtSp stk_usg - size - ; setStkUsage (stk_usg { virtSp = pop_virt_sp }) } -\end{code} - -\begin{code} -adjustStackHW :: VirtualSpOffset -> Code -adjustStackHW offset - = do { stk_usg <- getStkUsage - ; setStkUsage (stk_usg { hwSp = hwSp stk_usg `max` offset }) } -\end{code} - -A knot-tying beast. - -\begin{code} -getFinalStackHW :: (VirtualSpOffset -> Code) -> Code -getFinalStackHW fcode - = do { fixC_ (\hw_sp -> do - { fcode hw_sp - ; stk_usg <- getStkUsage - ; return (hwSp stk_usg) }) - ; return () } -\end{code} - -\begin{code} -setStackFrame :: VirtualSpOffset -> Code -setStackFrame offset - = do { stk_usg <- getStkUsage - ; setStkUsage (stk_usg { frameSp = offset }) } - -getStackFrame :: FCode VirtualSpOffset -getStackFrame - = do { stk_usg <- getStkUsage - ; return (frameSp stk_usg) } -\end{code} - - -%******************************************************** -%* * -%* Setting up update frames * -%* * -%******************************************************** - -@pushUpdateFrame@ $updatee$ pushes a general update frame which -points to $updatee$ as the thing to be updated. It is only used -when a thunk has just been entered, so the (real) stack pointers -are guaranteed to be nicely aligned with the top of stack. -@pushUpdateFrame@ adjusts the virtual and tail stack pointers -to reflect the frame pushed. - -\begin{code} -pushUpdateFrame :: CmmExpr -> Code -> Code -pushUpdateFrame updatee code - = pushSpecUpdateFrame mkUpdInfoLabel updatee code - -pushBHUpdateFrame :: CmmExpr -> Code -> Code -pushBHUpdateFrame updatee code - = pushSpecUpdateFrame mkBHUpdInfoLabel updatee code - -pushSpecUpdateFrame :: CLabel -> CmmExpr -> Code -> Code -pushSpecUpdateFrame lbl updatee code - = do { - when debugIsOn $ do - { EndOfBlockInfo _ sequel <- getEndOfBlockInfo ; - ; MASSERT(case sequel of { OnStack -> True; _ -> False}) } - ; dflags <- getDynFlags - ; allocStackTop (fixedHdrSize dflags + - sIZEOF_StgUpdateFrame_NoHdr dflags `quot` wORD_SIZE dflags) - ; vsp <- getVirtSp - ; setStackFrame vsp - ; frame_addr <- getSpRelOffset vsp - -- The location of the lowest-address - -- word of the update frame itself - - -- NB. we used to set the Sequel to 'UpdateCode' so - -- that we could jump directly to the update code if - -- we know that the next frame on the stack is an - -- update frame. However, the RTS can sometimes - -- change an update frame into something else (see - -- e.g. Note [upd-black-hole] in rts/sm/Scav.c), so we - -- no longer make this assumption. - ; setEndOfBlockInfo (EndOfBlockInfo vsp OnStack) $ - do { emitSpecPushUpdateFrame lbl frame_addr updatee - ; code } - } - -emitPushUpdateFrame :: CmmExpr -> CmmExpr -> Code -emitPushUpdateFrame = emitSpecPushUpdateFrame mkUpdInfoLabel - -emitSpecPushUpdateFrame :: CLabel -> CmmExpr -> CmmExpr -> Code -emitSpecPushUpdateFrame lbl frame_addr updatee = do - dflags <- getDynFlags - stmtsC [ -- Set the info word - CmmStore frame_addr (mkLblExpr lbl) - , -- And the updatee - CmmStore (cmmOffsetB dflags frame_addr (off_updatee dflags)) updatee ] - initUpdFrameProf frame_addr - -off_updatee :: DynFlags -> ByteOff -off_updatee dflags - = fixedHdrSize dflags * wORD_SIZE dflags + oFFSET_StgUpdateFrame_updatee dflags -\end{code} - - -%************************************************************************ -%* * -\subsection[CgStackery-free]{Free stack slots} -%* * -%************************************************************************ - -Explicitly free some stack space. - -\begin{code} -freeStackSlots :: [VirtualSpOffset] -> Code -freeStackSlots extra_free - = do { stk_usg <- getStkUsage - ; let all_free = addFreeSlots (freeStk stk_usg) (sort extra_free) - ; let (new_vsp, new_free) = trim (virtSp stk_usg) all_free - ; setStkUsage (stk_usg { virtSp = new_vsp, freeStk = new_free }) } - -addFreeSlots :: [VirtualSpOffset] -> [VirtualSpOffset] -> [VirtualSpOffset] --- Merge the two, assuming both are in increasing order -addFreeSlots cs [] = cs -addFreeSlots [] ns = ns -addFreeSlots (c:cs) (n:ns) - | c < n = c : addFreeSlots cs (n:ns) - | otherwise = n : addFreeSlots (c:cs) ns - -trim :: VirtualSpOffset -> [VirtualSpOffset] -> (VirtualSpOffset, [VirtualSpOffset]) --- Try to trim back the virtual stack pointer, where there is a --- continuous bunch of free slots at the end of the free list -trim vsp [] = (vsp, []) -trim vsp (slot:slots) - = case trim vsp slots of - (vsp', []) - | vsp' < slot -> pprTrace "trim: strange" (ppr vsp <+> ppr (slot:slots)) - (vsp', []) - | vsp' == slot -> (vsp'-1, []) - | otherwise -> (vsp', [slot]) - (vsp', slots') -> (vsp', slot:slots') -\end{code} |