-- Cmm representations using Hoopl's Graph CmmNode e x.{-# LANGUAGE GADTs #-}moduleCmm(-- * Cmm top-level datatypesCmmProgram ,CmmGroup ,GenCmmGroup ,CmmDecl ,GenCmmDecl (..),CmmGraph ,GenCmmGraph (..),CmmBlock ,RawCmmDecl ,RawCmmGroup ,Section (..),SectionType (..),CmmStatics (..),CmmStatic (..),isSecConstant ,-- ** Blocks containing listsGenBasicBlock (..),blockId ,ListGraph (..),pprBBlock ,-- * Info TablesCmmTopInfo (..),CmmStackInfo (..),CmmInfoTable (..),topInfoTable ,ClosureTypeInfo (..),ProfilingInfo (..),ConstrDescription ,-- * Statements, expressions and typesmoduleCmmNode ,moduleCmmExpr ,)whereimportGhcPrelude importId importCostCentre importCLabel importBlockId importCmmNode importSMRep importCmmExpr importHoopl.Block importHoopl.Collections importHoopl.Graph importHoopl.Label importOutputable importData.Word(Word8)------------------------------------------------------------------------------- Cmm, GenCmm------------------------------------------------------------------------------- A CmmProgram is a list of CmmGroups-- A CmmGroup is a list of top-level declarations-- When object-splitting is on, each group is compiled into a separate-- .o file. So typically we put closely related stuff in a CmmGroup.-- Section-splitting follows suit and makes one .text subsection for each-- CmmGroup.typeCmmProgram =[CmmGroup ]typeGenCmmGroup d h g =[GenCmmDecl d h g ]typeCmmGroup =GenCmmGroup CmmStatics CmmTopInfo CmmGraph typeRawCmmGroup =GenCmmGroup CmmStatics (LabelMap CmmStatics )CmmGraph ------------------------------------------------------------------------------- CmmDecl, GenCmmDecl------------------------------------------------------------------------------- GenCmmDecl is abstracted over-- 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).dataGenCmmDecl d h g =CmmProc -- A procedureh -- Extra header such as the info tableCLabel -- Entry label[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-- information for CmmProcs.g -- Control-flow graph for the procedure's code|CmmData -- Static dataSection d typeCmmDecl =GenCmmDecl CmmStatics CmmTopInfo CmmGraph typeRawCmmDecl =GenCmmDecl CmmStatics (LabelMap CmmStatics )CmmGraph ------------------------------------------------------------------------------- Graphs-----------------------------------------------------------------------------typeCmmGraph =GenCmmGraph CmmNode dataGenCmmGraph n =CmmGraph {g_entry ::BlockId ,g_graph ::Graph n C C }typeCmmBlock =Block CmmNode C C ------------------------------------------------------------------------------- Info Tables-----------------------------------------------------------------------------dataCmmTopInfo =TopInfo {info_tbls ::LabelMap CmmInfoTable ,stack_info ::CmmStackInfo }topInfoTable::GenCmmDecl a CmmTopInfo (GenCmmGraph n )->MaybeCmmInfoTable topInfoTable (CmmProc infos __g )=mapLookup (g_entryg )(info_tblsinfos )topInfoTable_=NothingdataCmmStackInfo =StackInfo {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.updfr_space ::MaybeByteOff ,-- XXX: this never contains anything useful, but it should.-- See comment in CmmLayoutStack.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.}-- | Info table as a haskell data typedataCmmInfoTable =CmmInfoTable {cit_lbl ::CLabel ,-- Info table labelcit_rep ::SMRep ,cit_prof ::ProfilingInfo ,cit_srt ::MaybeCLabel ,-- empty, or a closure addresscit_clo ::Maybe(Id ,CostCentreStack )-- Just (id,ccs) <=> build a static closure later-- Nothing <=> don't build a static closure---- Static closures for FUNs and THUNKs are *not* generated by-- the code generator, because we might want to add SRT-- entries to them later (for FUNs at least; THUNKs are-- treated the same for consistency). See Note [SRTs] in-- CmmBuildInfoTables, in particular the [FUN] optimisation.---- This is strictly speaking not a part of the info table that-- will be finally generated, but it's the only convenient-- place to convey this information from the code generator to-- where we build the static closures in-- CmmBuildInfoTables.doSRTs.}dataProfilingInfo =NoProfilingInfo |ProfilingInfo [Word8][Word8]-- closure_type, closure_desc------------------------------------------------------------------------------- Static Data-----------------------------------------------------------------------------dataSectionType =Text |Data |ReadOnlyData |RelocatableReadOnlyData |UninitialisedData |ReadOnlyData16 -- .rodata.cst16 on x86_64, 16-byte aligned|CString |OtherSection Stringderiving(Show)-- | Should a data in this section be considered constantisSecConstant::Section ->BoolisSecConstant (Section t _)=caset ofText ->TrueReadOnlyData ->TrueRelocatableReadOnlyData ->TrueReadOnlyData16 ->TrueCString ->TrueData ->FalseUninitialisedData ->False(OtherSection _)->FalsedataSection =Section SectionType CLabel dataCmmStatic =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.dataCmmStatics =Statics CLabel -- Label of statics[CmmStatic ]-- The static data itself-- ------------------------------------------------------------------------------- Basic blocks consisting of lists-- These are used by the LLVM and NCG backends, when populating Cmm-- with lists of instructions.dataGenBasicBlock i =BasicBlock BlockId [i ]-- | The branch block id is that of the first block in-- the branch, which is that branch's entry pointblockId::GenBasicBlock i ->BlockId blockId (BasicBlock blk_id _)=blk_id newtypeListGraph i =ListGraph [GenBasicBlock i ]instanceOutputable instr =>Outputable (ListGraph instr )whereppr (ListGraph blocks )=vcat (mapppr blocks )instanceOutputable instr =>Outputable (GenBasicBlock instr )whereppr =pprBBlock pprBBlock::Outputable stmt =>GenBasicBlock stmt ->SDoc pprBBlock (BasicBlock ident stmts )=hang (ppr ident <> colon )4(vcat (mapppr stmts ))

AltStyle によって変換されたページ (->オリジナル) /