diff options
Diffstat (limited to 'compiler/cmm')
-rw-r--r-- | compiler/cmm/CmmBuildInfoTables.hs | 2 | ||||
-rw-r--r-- | compiler/cmm/CmmMachOp.hs | 2 | ||||
-rw-r--r-- | compiler/cmm/CmmNode.hs | 2 | ||||
-rw-r--r-- | compiler/cmm/CmmPipeline.hs | 2 | ||||
-rw-r--r-- | compiler/cmm/SMRep.hs | 2 | ||||
-rw-r--r-- | compiler/cmm/cmm-notes | 370 |
6 files changed, 190 insertions, 190 deletions
diff --git a/compiler/cmm/CmmBuildInfoTables.hs b/compiler/cmm/CmmBuildInfoTables.hs index 9dc66a44e1..81c86fdad5 100644 --- a/compiler/cmm/CmmBuildInfoTables.hs +++ b/compiler/cmm/CmmBuildInfoTables.hs @@ -227,7 +227,7 @@ implemented. case, if the closure is not locally defined then we can't point to it directly from the info table, because this is the text section which cannot contain runtime relocations. In this case we skip this - optimisation and generate the singleton SRT, becase SRTs are in the + optimisation and generate the singleton SRT, because SRTs are in the data section and *can* have relocatable references. 2. [FUN] A static function closure can also be an SRT, we simply put diff --git a/compiler/cmm/CmmMachOp.hs b/compiler/cmm/CmmMachOp.hs index f8b7d4fb74..418ebec13f 100644 --- a/compiler/cmm/CmmMachOp.hs +++ b/compiler/cmm/CmmMachOp.hs @@ -135,7 +135,7 @@ data MachOp | MO_VU_Quot Length Width | MO_VU_Rem Length Width - -- Floting point vector element insertion and extraction operations + -- Floating point vector element insertion and extraction operations | MO_VF_Insert Length Width -- Insert scalar into vector | MO_VF_Extract Length Width -- Extract scalar from vector diff --git a/compiler/cmm/CmmNode.hs b/compiler/cmm/CmmNode.hs index 1b387020f5..f9bad961e6 100644 --- a/compiler/cmm/CmmNode.hs +++ b/compiler/cmm/CmmNode.hs @@ -715,7 +715,7 @@ isTickSubScope = cmp cmp (SubScope u s) s'@(SubScope u' _) = u == u' || cmp s s' -- | Combine two tick scopes. The new scope should be sub-scope of --- both parameters. We simplfy automatically if one tick scope is a +-- both parameters. We simplify automatically if one tick scope is a -- sub-scope of the other already. combineTickScopes :: CmmTickScope -> CmmTickScope -> CmmTickScope combineTickScopes s1 s2 diff --git a/compiler/cmm/CmmPipeline.hs b/compiler/cmm/CmmPipeline.hs index fbabea8f66..e7689a6bfe 100644 --- a/compiler/cmm/CmmPipeline.hs +++ b/compiler/cmm/CmmPipeline.hs @@ -297,7 +297,7 @@ cpsTop hsc_env proc = -- Sp = Sp + 16 -- ...y...y... -- --- But since we don't see any benefits from running sinking befroe stack +-- But since we don't see any benefits from running sinking before stack -- layout, this situation probably doesn't arise too often in practice. -- diff --git a/compiler/cmm/SMRep.hs b/compiler/cmm/SMRep.hs index 49137eff25..fe4ed58bfe 100644 --- a/compiler/cmm/SMRep.hs +++ b/compiler/cmm/SMRep.hs @@ -15,7 +15,7 @@ module SMRep ( StgHalfWord, fromStgHalfWord, toStgHalfWord, halfWordSize, halfWordSizeInBits, - -- * Closure repesentation + -- * Closure representation SMRep(..), -- CmmInfo sees the rep; no one else does IsStatic, ClosureTypeInfo(..), ArgDescr(..), Liveness, diff --git a/compiler/cmm/cmm-notes b/compiler/cmm/cmm-notes index 82d9673162..c1907f5908 100644 --- a/compiler/cmm/cmm-notes +++ b/compiler/cmm/cmm-notes @@ -1,185 +1,185 @@ -More notes (Aug 11)
-~~~~~~~~~~~~~~~~~~
-* CmmInfo.cmmToRawCmm expands info tables to their representations
- (needed for .cmm files as well as the code generators)
-
-* Why is FCode a lazy monad? That makes it inefficient.
- We want laziness to get code out one procedure at a time,
- but not at the instruction level.
- UPDATE (31/5/2016): FCode is strict since 09afcc9b.
-
-Things we did
- * Remove CmmCvt.graphToZgraph (Conversion from old to new Cmm reps)
- * Remove HscMain.optionallyConvertAndOrCPS (converted old Cmm to
- new, ran pipeline, and converted back)
- * Remove CmmDecl. Put its types in Cmm. Import Cmm into OldCmm
- so it can get those types.
-
-
-More notes (June 11)
-~~~~~~~~~~~~~~~~~~~~
-
-* In CmmContFlowOpts.branchChainElim, can a single block be the
- successor of two calls?
-
-* Check in ClosureInfo:
- -- NB: Results here should line up with the results of SMRep.rtsClosureType
-
-More notes (May 11)
-~~~~~~~~~~~~~~~~~~~
-In CmmNode, consider spliting CmmCall into two: call and jump
-
-Notes on new codegen (Aug 10)
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Things to do:
- - Proc points pass all arguments on the stack, adding more code and
- slowing down things a lot. We either need to fix this or even better
- would be to get rid of proc points.
-
- - Sort out Label, LabelMap, LabelSet versus BlockId, BlockEnv, BlockSet
- dichotomy. Mostly this means global replace, but we also need to make
- Label an instance of Outputable (probably in the Outputable module).
-
- EZY: We should use Label, since that's the terminology Hoopl uses.
-
- - AsmCodeGen has a generic Cmm optimiser; move this into new pipeline
- EZY (2011-04-16): The mini-inliner has been generalized and ported,
- but the constant folding and other optimizations need to still be
- ported.
-
- - AsmCodeGen has post-native-cg branch eliminator (shortCutBranches);
- we ultimately want to share this with the Cmm branch eliminator.
-
- - At the moment, references to global registers like Hp are "lowered"
- late (in CgUtils.fixStgRegisters). We should do this early, in the
- new native codegen, much in the way that we lower calling conventions.
- Might need to be a bit sophisticated about aliasing.
-
- - Move to new Cmm rep:
- * Make native CG consume New Cmm;
- * Convert Old Cmm->New Cmm to keep old path alive
- * Produce New Cmm when reading in .cmm files
-
- - Top-level SRT threading is a bit ugly
-
- - See "CAFs" below; we want to totally refactor the way SRTs are calculated
-
- - Garbage-collect https://gitlab.haskell.org/ghc/ghc/wikis/commentary/compiler/cps
- moving good stuff into
- https://gitlab.haskell.org/ghc/ghc/wikis/commentary/compiler/new-code-gen-pipeline
-
- - Currently AsmCodeGen top level calls AsmCodeGen.cmmToCmm, which is a small
- C-- optimiser. It has quite a lot of boilerplate folding code in AsmCodeGen
- (cmmBlockConFold, cmmStmtConFold, cmmExprConFold), before calling out to
- CmmOpt. ToDo: see what optimisations are being done; and do them before
- AsmCodeGen.
-
- - If we stick CAF and stack liveness info on a LastCall node (not LastRet/Jump)
- then all CAF and stack liveness stuff be completed before we split
- into separate C procedures.
-
- Short term:
- compute and attach liveness into LastCall
- right at end, split, cvt to old rep
- [must split before cvt, because old rep is not expressive enough]
-
- Longer term:
- when old rep disappears,
- move the whole splitting game into the C back end *only*
- (guided by the procpoint set)
-
-----------------------------------------------------
- Proc-points
-----------------------------------------------------
-
-Consider this program, which has a diamond control flow,
-with a call on one branch
- fn(p,x) {
- h()
- if b then { ... f(x) ...; q=5; goto J }
- else { ...; q=7; goto J }
- J: ..p...q...
- }
-then the join point J is a "proc-point". So, is 'p' passed to J
-as a parameter? Or, if 'p' was saved on the stack anyway, perhaps
-to keep it alive across the call to h(), maybe 'p' gets communicated
-to J that way. This is an awkward choice. (We think that we currently
-never pass variables to join points via arguments.)
-
-Furthermore, there is *no way* to pass q to J in a register (other
-than a parameter register).
-
-What we want is to do register allocation across the whole caboodle.
-Then we could drop all the code that deals with the above awkward
-decisions about spilling variables across proc-points.
-
-Note that J doesn't need an info table.
-
-What we really want is for each LastCall (not LastJump/Ret)
-to have an info table. Note that ProcPoints that are not successors
-of calls don't need an info table.
-
-Figuring out proc-points
-~~~~~~~~~~~~~~~~~~~~~~~~
-Proc-points are identified by
-CmmProcPoint.minimalProcPointSet/extendPPSet Although there isn't
-that much code, JD thinks that it could be done much more nicely using
-a dominator analysis, using the Dataflow Engine.
-
-----------------------------------------------------
- CAFs
-----------------------------------------------------
-
-* The code for a procedure f may refer to either the *closure*
- or the *entry point* of another top-level procedure g.
- If f is live, then so is g. f's SRT must include g's closure.
-
-* The CLabel for the entry-point/closure reveals whether g is
- a CAF (or refers to CAFs). See the IdLabel constructor of CLabel.
-
-* The CAF-ness of the original top-level definitions is figured out
- (by TidyPgm) before we generate C--. This CafInfo is only set for
- top-level Ids; nested bindings stay with MayHaveCafRefs.
-
-* Currently an SRT contains (only) pointers to (top-level) closures.
-
-* Consider this Core code
- f = \x -> let g = \y -> ...x...y...h1...
- in ...h2...g...
- and suppose that h1, h2 have IdInfo of MayHaveCafRefs.
- Therefore, so will f, But g will not (since it's nested).
-
- This generates C-- roughly like this:
- f_closure: .word f_entry
- f_entry() [info-tbl-for-f] { ...jump g_entry...jump h2... }
- g_entry() [info-tbl-for-g] { ...jump h1... }
-
- Note that there is no top-level closure for g (only an info table).
- This fact (whether or not there is a top-level closure) is recorded
- in the InfoTable attached to the CmmProc for f, g
- INVARIANT:
- Any out-of-Group references to an IdLabel goes to
- a Proc whose InfoTable says "I have a top-level closure".
- Equivalently:
- A CmmProc whose InfoTable says "I do not have a top-level
- closure" is referred to only from its own Group.
-
-* So: info-tbl-for-f must have an SRT that keeps h1,h2 alive
- info-tbl-for-g must have an SRT that keeps h1 (only) alive
-
- But if we just look for the free CAF refs, we get:
- f h2 (only)
- g h1
-
- So we need to do a transitive closure thing to flesh out
- f's keep-alive refs to include h1.
-
-* The SRT info is the C_SRT field of Cmm.ClosureTypeInfo in a
- CmmInfoTable attached to each CmmProc. CmmPipeline.toTops actually does
- the attaching, right at the end of the pipeline. The C_SRT part
- gives offsets within a single, shared table of closure pointers.
-
-* DECIDED: we can generate SRTs based on the final Cmm program
- without knowledge of how it is generated.
-
+More notes (Aug 11) +~~~~~~~~~~~~~~~~~~ +* CmmInfo.cmmToRawCmm expands info tables to their representations + (needed for .cmm files as well as the code generators) + +* Why is FCode a lazy monad? That makes it inefficient. + We want laziness to get code out one procedure at a time, + but not at the instruction level. + UPDATE (31/5/2016): FCode is strict since 09afcc9b. + +Things we did + * Remove CmmCvt.graphToZgraph (Conversion from old to new Cmm reps) + * Remove HscMain.optionallyConvertAndOrCPS (converted old Cmm to + new, ran pipeline, and converted back) + * Remove CmmDecl. Put its types in Cmm. Import Cmm into OldCmm + so it can get those types. + + +More notes (June 11) +~~~~~~~~~~~~~~~~~~~~ + +* In CmmContFlowOpts.branchChainElim, can a single block be the + successor of two calls? + +* Check in ClosureInfo: + -- NB: Results here should line up with the results of SMRep.rtsClosureType + +More notes (May 11) +~~~~~~~~~~~~~~~~~~~ +In CmmNode, consider splitting CmmCall into two: call and jump + +Notes on new codegen (Aug 10) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Things to do: + - Proc points pass all arguments on the stack, adding more code and + slowing down things a lot. We either need to fix this or even better + would be to get rid of proc points. + + - Sort out Label, LabelMap, LabelSet versus BlockId, BlockEnv, BlockSet + dichotomy. Mostly this means global replace, but we also need to make + Label an instance of Outputable (probably in the Outputable module). + + EZY: We should use Label, since that's the terminology Hoopl uses. + + - AsmCodeGen has a generic Cmm optimiser; move this into new pipeline + EZY (2011-04-16): The mini-inliner has been generalized and ported, + but the constant folding and other optimizations need to still be + ported. + + - AsmCodeGen has post-native-cg branch eliminator (shortCutBranches); + we ultimately want to share this with the Cmm branch eliminator. + + - At the moment, references to global registers like Hp are "lowered" + late (in CgUtils.fixStgRegisters). We should do this early, in the + new native codegen, much in the way that we lower calling conventions. + Might need to be a bit sophisticated about aliasing. + + - Move to new Cmm rep: + * Make native CG consume New Cmm; + * Convert Old Cmm->New Cmm to keep old path alive + * Produce New Cmm when reading in .cmm files + + - Top-level SRT threading is a bit ugly + + - See "CAFs" below; we want to totally refactor the way SRTs are calculated + + - Garbage-collect https://gitlab.haskell.org/ghc/ghc/wikis/commentary/compiler/cps + moving good stuff into + https://gitlab.haskell.org/ghc/ghc/wikis/commentary/compiler/new-code-gen-pipeline + + - Currently AsmCodeGen top level calls AsmCodeGen.cmmToCmm, which is a small + C-- optimiser. It has quite a lot of boilerplate folding code in AsmCodeGen + (cmmBlockConFold, cmmStmtConFold, cmmExprConFold), before calling out to + CmmOpt. ToDo: see what optimisations are being done; and do them before + AsmCodeGen. + + - If we stick CAF and stack liveness info on a LastCall node (not LastRet/Jump) + then all CAF and stack liveness stuff be completed before we split + into separate C procedures. + + Short term: + compute and attach liveness into LastCall + right at end, split, cvt to old rep + [must split before cvt, because old rep is not expressive enough] + + Longer term: + when old rep disappears, + move the whole splitting game into the C back end *only* + (guided by the procpoint set) + +---------------------------------------------------- + Proc-points +---------------------------------------------------- + +Consider this program, which has a diamond control flow, +with a call on one branch + fn(p,x) { + h() + if b then { ... f(x) ...; q=5; goto J } + else { ...; q=7; goto J } + J: ..p...q... + } +then the join point J is a "proc-point". So, is 'p' passed to J +as a parameter? Or, if 'p' was saved on the stack anyway, perhaps +to keep it alive across the call to h(), maybe 'p' gets communicated +to J that way. This is an awkward choice. (We think that we currently +never pass variables to join points via arguments.) + +Furthermore, there is *no way* to pass q to J in a register (other +than a parameter register). + +What we want is to do register allocation across the whole caboodle. +Then we could drop all the code that deals with the above awkward +decisions about spilling variables across proc-points. + +Note that J doesn't need an info table. + +What we really want is for each LastCall (not LastJump/Ret) +to have an info table. Note that ProcPoints that are not successors +of calls don't need an info table. + +Figuring out proc-points +~~~~~~~~~~~~~~~~~~~~~~~~ +Proc-points are identified by +CmmProcPoint.minimalProcPointSet/extendPPSet Although there isn't +that much code, JD thinks that it could be done much more nicely using +a dominator analysis, using the Dataflow Engine. + +---------------------------------------------------- + CAFs +---------------------------------------------------- + +* The code for a procedure f may refer to either the *closure* + or the *entry point* of another top-level procedure g. + If f is live, then so is g. f's SRT must include g's closure. + +* The CLabel for the entry-point/closure reveals whether g is + a CAF (or refers to CAFs). See the IdLabel constructor of CLabel. + +* The CAF-ness of the original top-level definitions is figured out + (by TidyPgm) before we generate C--. This CafInfo is only set for + top-level Ids; nested bindings stay with MayHaveCafRefs. + +* Currently an SRT contains (only) pointers to (top-level) closures. + +* Consider this Core code + f = \x -> let g = \y -> ...x...y...h1... + in ...h2...g... + and suppose that h1, h2 have IdInfo of MayHaveCafRefs. + Therefore, so will f, But g will not (since it's nested). + + This generates C-- roughly like this: + f_closure: .word f_entry + f_entry() [info-tbl-for-f] { ...jump g_entry...jump h2... } + g_entry() [info-tbl-for-g] { ...jump h1... } + + Note that there is no top-level closure for g (only an info table). + This fact (whether or not there is a top-level closure) is recorded + in the InfoTable attached to the CmmProc for f, g + INVARIANT: + Any out-of-Group references to an IdLabel goes to + a Proc whose InfoTable says "I have a top-level closure". + Equivalently: + A CmmProc whose InfoTable says "I do not have a top-level + closure" is referred to only from its own Group. + +* So: info-tbl-for-f must have an SRT that keeps h1,h2 alive + info-tbl-for-g must have an SRT that keeps h1 (only) alive + + But if we just look for the free CAF refs, we get: + f h2 (only) + g h1 + + So we need to do a transitive closure thing to flesh out + f's keep-alive refs to include h1. + +* The SRT info is the C_SRT field of Cmm.ClosureTypeInfo in a + CmmInfoTable attached to each CmmProc. CmmPipeline.toTops actually does + the attaching, right at the end of the pipeline. The C_SRT part + gives offsets within a single, shared table of closure pointers. + +* DECIDED: we can generate SRTs based on the final Cmm program + without knowledge of how it is generated. + |