Cmm.hs 7.09 KB
Newer Older
1
-- Cmm representations using Hoopl's Graph CmmNode e x.
2
{-# LANGUAGE CPP, GADTs #-}
Simon Marlow's avatar
Simon Marlow committed
3

4 5
module Cmm (
     -- * Cmm top-level datatypes
Simon Peyton Jones's avatar
Simon Peyton Jones committed
6 7
     CmmProgram, CmmGroup, GenCmmGroup,
     CmmDecl, GenCmmDecl(..),
8 9
     CmmGraph, GenCmmGraph(..),
     CmmBlock,
10
     RawCmmDecl, RawCmmGroup,
11
     Section(..), SectionType(..), CmmStatics(..), CmmStatic(..),
12

13 14 15 16
     -- ** Blocks containing lists
     GenBasicBlock(..), blockId,
     ListGraph(..), pprBBlock,

17 18
     -- * Cmm graphs
     CmmReplGraph, GenCmmReplGraph, CmmFwdRewrite, CmmBwdRewrite,
19

20
     -- * Info Tables
21
     CmmTopInfo(..), CmmStackInfo(..), CmmInfoTable(..), topInfoTable,
22
     ClosureTypeInfo(..),
23
     C_SRT(..), needsSRT,
24
     ProfilingInfo(..), ConstrDescription,
25 26 27 28 29 30 31

     -- * Statements, expressions and types
     module CmmNode,
     module CmmExpr,
  ) where

import CLabel
32
import BlockId
33
import CmmNode
34
import SMRep
35
import CmmExpr
36
import UniqSupply
37
import Compiler.Hoopl
38
import Outputable
39 40

import Data.Word        ( Word8 )
41 42

#include "HsVersions.h"
43

44 45 46 47
-----------------------------------------------------------------------------
--  Cmm, GenCmm
-----------------------------------------------------------------------------

48 49
-- A CmmProgram is a list of CmmGroups
-- A CmmGroup is a list of top-level declarations
50

51
-- When object-splitting is on, each group is compiled into a separate
Simon Peyton Jones's avatar
Simon Peyton Jones committed
52
-- .o file. So typically we put closely related stuff in a CmmGroup.
53 54
-- Section-splitting follows suit and makes one .text subsection for each
-- CmmGroup.
Simon Peyton Jones's avatar
Simon Peyton Jones committed
55 56 57 58 59

type CmmProgram = [CmmGroup]

type GenCmmGroup d h g = [GenCmmDecl d h g]
type CmmGroup = GenCmmGroup CmmStatics CmmTopInfo CmmGraph
60
type RawCmmGroup = GenCmmGroup CmmStatics (LabelMap CmmStatics) CmmGraph
Simon Peyton Jones's avatar
Simon Peyton Jones committed
61 62 63 64 65 66

-----------------------------------------------------------------------------
--  CmmDecl, GenCmmDecl
-----------------------------------------------------------------------------

-- GenCmmDecl is abstracted over
67 68 69 70 71 72 73 74 75 76
--   d, the type of static data elements in CmmData
--   h, the static info preceding the code of a CmmProc
--   g, the control-flow graph of a CmmProc
--
-- We expect there to be two main instances of this type:
--   (a) C--, i.e. populated with various C-- constructs
--   (b) Native code, populated with data/instructions

-- | A top-level chunk, abstracted over the type of the contents of
-- the basic blocks (Cmm or instructions are the likely instantiations).
Simon Peyton Jones's avatar
Simon Peyton Jones committed
77
data GenCmmDecl d h g
78 79 80
  = CmmProc     -- A procedure
     h                 -- Extra header such as the info table
     CLabel            -- Entry label
81 82 83 84
     [GlobalReg]       -- Registers live on entry. Note that the set of live
                       -- registers will be correct in generated C-- code, but
                       -- not in hand-written C-- code. However,
                       -- splitAtProcPoints calculates correct liveness
Simon Marlow's avatar
Simon Marlow committed
85
                       -- information for CmmProcs.
86 87 88 89 90 91
     g                 -- Control-flow graph for the procedure's code

  | CmmData     -- Static data
        Section
        d

Simon Peyton Jones's avatar
Simon Peyton Jones committed
92
type CmmDecl = GenCmmDecl CmmStatics CmmTopInfo CmmGraph
93

94 95 96
type RawCmmDecl
   = GenCmmDecl
        CmmStatics
97
        (LabelMap CmmStatics)
98 99
        CmmGraph

100 101 102
-----------------------------------------------------------------------------
--     Graphs
-----------------------------------------------------------------------------
103

104 105
type CmmGraph = GenCmmGraph CmmNode
data GenCmmGraph n = CmmGraph { g_entry :: BlockId, g_graph :: Graph n C C }
106 107
type CmmBlock = Block CmmNode C C

108
type CmmReplGraph e x = GenCmmReplGraph CmmNode e x
109 110 111
type GenCmmReplGraph n e x = UniqSM (Maybe (Graph n e x))
type CmmFwdRewrite f = FwdRewrite UniqSM CmmNode f
type CmmBwdRewrite f = BwdRewrite UniqSM CmmNode f
112

113 114 115 116
-----------------------------------------------------------------------------
--     Info Tables
-----------------------------------------------------------------------------

117
data CmmTopInfo   = TopInfo { info_tbls  :: LabelMap CmmInfoTable
Simon Marlow's avatar
Simon Marlow committed
118
                            , stack_info :: CmmStackInfo }
119

120
topInfoTable :: GenCmmDecl a CmmTopInfo (GenCmmGraph n) -> Maybe CmmInfoTable
121 122
topInfoTable (CmmProc infos _ _ g) = mapLookup (g_entry g) (info_tbls infos)
topInfoTable _                     = Nothing
123

124 125
data CmmStackInfo
   = StackInfo {
Simon Marlow's avatar
Simon Marlow committed
126 127 128 129
       arg_space :: ByteOff,
               -- number of bytes of arguments on the stack on entry to the
               -- the proc.  This is filled in by StgCmm.codeGen, and used
               -- by the stack allocator later.
130
       updfr_space :: Maybe ByteOff,
131 132
               -- XXX: this never contains anything useful, but it should.
               -- See comment in CmmLayoutStack.
133 134 135 136 137
       do_layout :: Bool
               -- Do automatic stack layout for this proc.  This is
               -- True for all code generated by the code generator,
               -- but is occasionally False for hand-written Cmm where
               -- we want to do the stack manipulation manually.
138
  }
139 140 141 142 143 144 145 146 147 148 149 150 151 152

-- | Info table as a haskell data type
data CmmInfoTable
  = CmmInfoTable {
      cit_lbl  :: CLabel, -- Info table label
      cit_rep  :: SMRep,
      cit_prof :: ProfilingInfo,
      cit_srt  :: C_SRT
    }

data ProfilingInfo
  = NoProfilingInfo
  | ProfilingInfo [Word8] [Word8] -- closure_type, closure_desc

153
-- C_SRT is what StgSyn.SRT gets translated to...
154 155 156
-- we add a label for the table, and expect only the 'offset/length' form

data C_SRT = NoC_SRT
157
           | C_SRT !CLabel !WordOff !StgHalfWord {-bitmap or escape-}
158 159 160 161 162 163 164 165 166 167
           deriving (Eq)

needsSRT :: C_SRT -> Bool
needsSRT NoC_SRT       = False
needsSRT (C_SRT _ _ _) = True

-----------------------------------------------------------------------------
--              Static Data
-----------------------------------------------------------------------------

168
data SectionType
169 170 171 172 173 174
  = Text
  | Data
  | ReadOnlyData
  | RelocatableReadOnlyData
  | UninitialisedData
  | ReadOnlyData16      -- .rodata.cst16 on x86_64, 16-byte aligned
175
  | CString
176
  | OtherSection String
177 178 179
  deriving (Show)

data Section = Section SectionType CLabel
180 181 182 183 184 185 186 187 188 189 190 191 192 193

data CmmStatic
  = CmmStaticLit CmmLit
        -- a literal value, size given by cmmLitRep of the literal.
  | CmmUninitialised Int
        -- uninitialised data, N bytes long
  | CmmString [Word8]
        -- string of 8-bit values only, not zero terminated.

data CmmStatics
   = Statics
       CLabel      -- Label of statics
       [CmmStatic] -- The static data itself

194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218
-- -----------------------------------------------------------------------------
-- Basic blocks consisting of lists

-- These are used by the LLVM and NCG backends, when populating Cmm
-- with lists of instructions.

data GenBasicBlock i = BasicBlock BlockId [i]

-- | The branch block id is that of the first block in
-- the branch, which is that branch's entry point
blockId :: GenBasicBlock i -> BlockId
blockId (BasicBlock blk_id _ ) = blk_id

newtype ListGraph i = ListGraph [GenBasicBlock i]

instance Outputable instr => Outputable (ListGraph instr) where
    ppr (ListGraph blocks) = vcat (map ppr blocks)

instance Outputable instr => Outputable (GenBasicBlock instr) where
    ppr = pprBBlock

pprBBlock :: Outputable stmt => GenBasicBlock stmt -> SDoc
pprBBlock (BasicBlock ident stmts) =
    hang (ppr ident <> colon) 4 (vcat (map ppr stmts))