~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\r
\r
Things to do:\r
+ - Consider module names\r
+\r
- Top-level SRT threading is a bit ugly\r
\r
- Add type/newtype for CmmModule = [CmmGroup] -- A module\r
regardless of SplitObjs. Question: can we *always* generate M.o if there\r
is just one element in the list (rather than M/M1.o, M/M2.o etc)\r
\r
+ One SRT per group.\r
+\r
+ - See "CAFs" below; we want to totally refactor the way SRTs are calculated\r
+\r
- Change \r
type CmmZ = GenCmm CmmStatic CmmInfo (CmmStackInfo, CmmGraph)\r
to\r
type SubArea = (Area, ByteOff, ByteWidth) \r
ByteOff should not be defined in SMRep -- that is too high up the hierarchy\r
\r
+ - SMRep should not be imported by any module in cmm/! Make it so.\r
+ -- ByteOff etc ==> CmmExpr\r
+ -- rET_SMALL etc ==> CmmInfo\r
+ Check that there are no other imports from codeGen in cmm/\r
+\r
- Think about a non-flattened representation?\r
\r
- LastCall: \r
points that are not successors of a call, we think) can be treated\r
uniformly: zero-size Area, and use inSP.\r
\r
-Dead files\r
-~~~~~~~~~~\r
-CmmProcPoint (Michael Adams)\r
-CmmCPS (ditto)\r
+\r
+ - Currently AsmCodeGen top level calls AsmCodeGen.cmmToCmm, which is a small\r
+ C-- optimiser. It has quite a lot of boilerplate folding code in AsmCodeGen\r
+ (cmmBlockConFold, cmmStmtConFold, cmmExprConFold), before calling out to\r
+ CmmOpt. ToDo: see what optimisations are being done; and do them before\r
+ AsmCodeGen.\r
+\r
+ - Modularise the CPS pipeline; instead of ...; A;B;C; ...\r
+ use ..; ABC; ....\r
+\r
+ - Most of HscMain.tryNewCodeGen does not belong in HscMain. Instead\r
+ if new_cg then\r
+ StgCmm.codeGen\r
+ processCmm [including generating "raw" cmm]\r
+ else\r
+ CodeGen.codeGen\r
+ cmmToRawCmm\r
+\r
+\r
+ - If we stick CAF and stack liveness info on a LastCall node (not LastRet/Jump)\r
+ then all CAF and stack liveness stuff be completed before we split\r
+ into separate C procedures.\r
+\r
+ Short term:\r
+ compute and attach liveness into to LastCall\r
+ right at end, split, cvt to old rep\r
+ [must split before cvt, because old rep is not expressive enough]\r
+\r
+ Longer term: \r
+ when old rep disappears, \r
+ move the whole splitting game into the C back end *only*\r
+ (guided by the procpoint set)\r
+\r
+ \r
+----------------------------------------------------\r
+ Modules in cmm/\r
+----------------------------------------------------\r
+\r
+-------- Dead stuff ------------\r
+CmmProcPoint Dead: Michael Adams\r
+CmmCPS Dead: Michael Adams\r
+CmmCPSGen.hs Dead: Michael Adams\r
+CmmBrokenBlock.hs Dead: Michael Adams\r
+CmmLive.hs Dead: Michael Adams\r
+CmmProcPoint.hs Dead: Michael Adams\r
+Dataflow.hs Dead: Michael Adams\r
+StackColor.hs Norman?\r
+StackPlacements.hs Norman?\r
+\r
HscMain.optionallyConvertAndOrCPS\r
testCmmConversion\r
DynFlags: -fconvert-to-zipper-and-back, -frun-cps, -frun-cpsz\r
\r
-Proc-points\r
-~~~~~~~~~~~~\r
-Consider this program, which has a diamond control flow, \r
-with a call on one branch\r
- fn(p,x) {\r
- h()\r
- if b then { ... f(x) ...; q=5; goto J }\r
- else { ...; q=7; goto J }\r
- J: ..p...q...\r
- }\r
-then the join point J is a "proc-point". So, is 'p' passed to J\r
-as a parameter? Or, if 'p' was saved on the stack anyway, perhaps\r
-to keep it alive across the call to h(), maybe 'p' gets communicated\r
-to J that way. This is an awkward choice. (We think that we currently\r
-never pass variables to join points via arguments.)\r
+-------- Moribund stuff ------------\r
+CmmCvt.hs Conversion between old and new Cmm reps\r
+CmmOpt.hs Hopefully-redundant optimiser\r
+CmmZipUtil.hs Only one function; move elsewhere\r
\r
-Furthermore, there is *no way* to pass q to J in a register (other\r
-than a paramter register).\r
+-------- Stuff to keep ------------\r
+CmmCPSZ.hs Driver for new pipeline\r
\r
-What we want is to do register allocation across the whole caboodle.\r
-Then we could drop all the code that deals with the above awkward\r
-decisions about spilling variables across proc-points.\r
+CmmLiveZ.hs Liveness analysis, dead code elim\r
+CmmProcPointZ.hs Identifying and splitting out proc-points\r
\r
-Note that J doesn't need an info table.\r
+CmmSpillReload.hs Save and restore across calls\r
\r
-What we really want is for each Block to have an optional info table.\r
-To do that, we need to be polymorphic over first nodes.\r
+CmmCommonBlockElimZ.hs Common block elim\r
+CmmContFlowOpt.hs Other optimisations (branch-chain, merging)\r
+\r
+CmmBuildInfoTables.hs New info-table \r
+CmmStackLayout.hs and stack layout \r
+CmmCallConv.hs\r
+CmmInfo.hs Defn of InfoTables, and conversion to exact layout\r
+\r
+---------- Cmm data types --------------\r
+ZipCfgCmmRep.hs Cmm instantiations of dataflow graph framework\r
+MkZipCfgCmm.hs Cmm instantiations of dataflow graph framework\r
+\r
+Cmm.hs Key module; a mix of old and new stuff\r
+ so needs tidying up in due course\r
+CmmExpr.hs\r
+CmmUtils.hs\r
+CmmLint.hs\r
+\r
+PprC.hs Pretty print Cmm in C syntax\r
+PprCmm.hs Pretty printer for Cmm\r
+PprCmmZ.hs Additional stuff for zipper rep\r
+\r
+CLabel.hs CLabel\r
+\r
+---------- Dataflow modules --------------\r
+ Goal: separate library; for now, separate directory\r
+\r
+MkZipCfg.hs\r
+ZipCfg.hs\r
+ZipCfgExtras.hs\r
+ZipDataflow.hs\r
+CmmTx.hs Transactions\r
+OptimizationFuel.hs Fuel\r
+BlockId.hs BlockId, BlockEnv, BlockSet\r
+DFMonad.hs \r
\r
-Figuring out proc-points\r
-~~~~~~~~~~~~~~~~~~~~~~~~\r
-Proc-points are identified by\r
-CmmProcPointZ.minimalProcPointSet/extendPPSet Although there isn't\r
-that much code, JD thinks that it could be done much more nicely using\r
-a dominator analysis, using the Dataflow Engine.\r
\r
----------------------------------------------------\r
Top-level structure\r
\r
* CmmProcPointZ.minimalProcPointSet\r
identify proc-points\r
+ no change to graph\r
\r
* CmmProcPointZ.addProcPointProtocols\r
something to do with the MA optimisation\r
probably entirely unnecessary\r
\r
-\r
* Spill and reload:\r
- CmmSpillReload.dualLivenessWithInsertion\r
insert spills/reloads across \r
\r
- CmmStackLayout.layout\r
Lay out the stack, returning an AreaMap\r
- type AreaMap = FiniteMap Area ByteOff\r
+ type AreaMap = FiniteMap Area ByteOff\r
-- Byte offset of the oldest byte of the Area, \r
-- relative to the oldest byte of the Old Area\r
\r
* Split into separate procedures\r
- CmmProcPointZ.procPointAnalysis\r
Given set of proc points, which blocks are reachable from each\r
+ Claim: too few proc-points => code duplication, but program still works??\r
\r
- CmmProcPointZ.splitAtProcPoints\r
Using this info, split into separate procedures\r
\r
+ - CmmBuildInfoTables.setInfoTableStackMap\r
+ Attach stack maps to each info table\r
+\r
+\r
+----------------------------------------------------\r
+ Proc-points\r
+----------------------------------------------------\r
+\r
+Consider this program, which has a diamond control flow, \r
+with a call on one branch\r
+ fn(p,x) {\r
+ h()\r
+ if b then { ... f(x) ...; q=5; goto J }\r
+ else { ...; q=7; goto J }\r
+ J: ..p...q...\r
+ }\r
+then the join point J is a "proc-point". So, is 'p' passed to J\r
+as a parameter? Or, if 'p' was saved on the stack anyway, perhaps\r
+to keep it alive across the call to h(), maybe 'p' gets communicated\r
+to J that way. This is an awkward choice. (We think that we currently\r
+never pass variables to join points via arguments.)\r
+\r
+Furthermore, there is *no way* to pass q to J in a register (other\r
+than a paramter register).\r
+\r
+What we want is to do register allocation across the whole caboodle.\r
+Then we could drop all the code that deals with the above awkward\r
+decisions about spilling variables across proc-points.\r
+\r
+Note that J doesn't need an info table.\r
+\r
+What we really want is for each LastCall (not LastJump/Ret) \r
+to have an info table. Note that ProcPoints that are not successors\r
+of calls don't need an info table.\r
+\r
+Figuring out proc-points\r
+~~~~~~~~~~~~~~~~~~~~~~~~\r
+Proc-points are identified by\r
+CmmProcPointZ.minimalProcPointSet/extendPPSet Although there isn't\r
+that much code, JD thinks that it could be done much more nicely using\r
+a dominator analysis, using the Dataflow Engine.\r
+\r
----------------------------------------------------\r
CAFs\r
----------------------------------------------------\r
If f is live, then so is g. f's SRT must include g's closure.\r
\r
* The CLabel for the entry-point/closure reveals whether g is \r
- a CAF (or refers to CAFs). See the IdLabell constructor of CLabel.\r
+ a CAF (or refers to CAFs). See the IdLabel constructor of CLabel.\r
\r
* The CAF-ness of the original top-level defininions is figured out\r
(by TidyPgm) before we generate C--. This CafInfo is only set for\r
- top-level Ids; nested bindings stay with NoCafRefs.\r
+ top-level Ids; nested bindings stay with MayHaveCafRefs.\r
\r
* Currently an SRT contains (only) pointers to (top-level) closures.\r
\r
This generates C-- roughly like this:\r
f_closure: .word f_entry\r
f_entry() [info-tbl-for-f] { ...jump g_entry...jump h2... }\r
- g_entry() [info-tbl-for-g] { ...jump h1 }\r
+ g_entry() [info-tbl-for-g] { ...jump h1... }\r
\r
Note that there is no top-level closure for g (only an info table).\r
- So: info-tbl-for-f must have an SRT that keeps h1,h2 alive\r
+ This fact (whether or not there is a top-level closure) is recorded\r
+ in the InfoTable attached to the CmmProc for f, g\r
+ INVARIANT: \r
+ Any out-of-Group references to an IdLabel goes to\r
+ a Proc whose InfoTable says "I have a top-level closure".\r
+ Equivalently: \r
+ A CmmProc whose InfoTable says "I do not have a top-level\r
+ closure" is referred to only from its own Group.\r
+\r
+* So: info-tbl-for-f must have an SRT that keeps h1,h2 alive\r
info-tbl-for-g must have an SRT that keeps h1 (only) alive\r
\r
But if we just look for the free CAF refs, we get:\r
the attaching, right at the end of the pipeline. The C_SRT part\r
gives offsets within a single, shared table of closure pointers.\r
\r
+* DECIDED: we can generate SRTs based on the final Cmm program\r
+ without knowledge of how it is generated.\r
+\r
----------------------------------------------------\r
Foreign calls\r
----------------------------------------------------\r