Changes between Version 30 and Version 31 of Commentary/Compiler/CodeGen


Ignore:
Timestamp:
Feb 3, 2014 1:56:20 PM (17 months ago)
Author:
jstolarek
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • Commentary/Compiler/CodeGen

    v30 v31  
    11= Code Generator = 
    22 
    3 This page describes code generator ("codegen") in GHC. It is meant to reflect current state of the implementation. If you notice any inacurracies please update the page (if you know how) or complain on ghc-devs. 
     3This page describes code generator ("codegen") in GHC. It is meant to reflect current state of the implementation. If you notice any inaccuracies please update the page (if you know how) or complain on ghc-devs. 
    44 
    55== A brief history of code generator == 
    66 
    7 You might ocasionally hear about "old" and "new" code generator. GHC 7.6 and earlier used the old code generator. New code generator was being developed since 2007 and it was [changeset:832077ca5393d298324cb6b0a2cb501e27209768/ghc enabled by default on 31 August 2012] after the release of GHC 7.6.1. The first stable GHC to use the new code generator is 7.8.1 released in early 2014. The commentary on the old code generator can be found [wiki:Commentary/Compiler/OldCodeGen here]. Notes from the development process of the new code generator are located in a couple of pages on the wiki - go to [wiki:TitleIndex Index] and look for pages starting with "!NewCodeGen". 
     7You might occasionally hear about "old" and "new" code generator. GHC 7.6 and earlier used the old code generator. New code generator was being developed since 2007 and it was [changeset:832077ca5393d298324cb6b0a2cb501e27209768/ghc enabled by default on 31 August 2012] after the release of GHC 7.6.1. The first stable GHC to use the new code generator is 7.8.1 released in early 2014. The commentary on the old code generator can be found [wiki:Commentary/Compiler/OldCodeGen here]. Notes from the development process of the new code generator are located in a couple of pages on the wiki - go to [wiki:TitleIndex Index] and look for pages starting with "!NewCodeGen". 
    88 
    99There are some plans for the future development of code generator. One plan is to expand the capability of the pipeline so that it does native code generation too so that existing backends can be discarded - see [wiki:Commentary/Compiler/IntegratedCodeGen IntegratedCodeGen] for discussion of the design. It is hard to say if this will ever happen as currently there is no work being done on that subject and in the meanwhile there was an alternative proposal to [wiki:Commentary/Compiler/Backends/LLVM/ReplacingNCG replace native code generator with LLVM]. 
     
    4242 * '''Common Block Elimination''', implemented in `CmmCommonBlockElim`, eliminates blocks that are identical (except for the label on their first node). Since this pass traverses blocks in depth-first order any unreachable blocks introduced by Control Flow Optimisations are eliminated. '''This pass is optional.''' 
    4343 
    44  * '''Determine proc-points''', implemented in `CmmProcPoint`. The idea behind the "proc-point splitting" is that we first determine proc-points, ie. blocks in the graph that can be turned into entry points of procedures, and then split a larger function into many smaller ones, each having a proc-point as its entry point. This is required for the LLVM backend. The proc-point splitting itself is done later in the pipeline, but here we only determine the set of proc-points. We first call `callProcPoints`, which assumes that entry point to a Cmm graph and every continuation of a call is a procpoint. If we are aplitting proc-points we update the list of proc-points by calling `minimalProcPointSet`, which adds all blocks reachable from more than one block in the graph. The set of proc-points is required by the stack layout pass. 
     44 * '''Determine proc-points''', implemented in `CmmProcPoint`. The idea behind the "proc-point splitting" is that we first determine proc-points, ie. blocks in the graph that can be turned into entry points of procedures, and then split a larger function into many smaller ones, each having a proc-point as its entry point. This is required for the LLVM backend. The proc-point splitting itself is done later in the pipeline, but here we only determine the set of proc-points. We first call `callProcPoints`, which assumes that entry point to a Cmm graph and every continuation of a call is a procpoint. If we are splitting proc-points we update the list of proc-points by calling `minimalProcPointSet`, which adds all blocks reachable from more than one block in the graph. The set of proc-points is required by the stack layout pass. 
    4545 
    4646 * '''Figure out the stack layout''', implemented in `CmmStackLayout`. The job of this pass is to: 
     
    5050   * save any variables that are live across a call, and reload them as 
    5151   necessary. 
    52  '''Invariant violation''': It may happen that stack layout will invalidate the computed set of proc-points by removing a block that is a proc-point. This means that at this point in the pipeline we have insonsistent data and subsequent steps must be prepared for it. 
     52 '''Important''': It may happen that stack layout will invalidate the computed set of proc-points by making a proc-point unreachable. This unreachable block is eliminated by one of subsequent passes that performs depth-first traversal of a graph: sinking pass (if optimisations are enabled), proc-point analysis (if optimisations are disabled and we're doing proc-point splitting) or at the very end of the pipeline (if optimisations are disabled and we're not doing proc-point splitting). This means that starting from this point in the pipeline we have inconsistent data and subsequent steps must be prepared for it. 
    5353  
    5454 * '''Sinking assignments''', implemented in `CmmSink`, performs these optimizations: 
     
    107107}}} 
    108108 
    109 "Cmm produced by new codegen" is emited in `HscMain` module after converting STG to Cmm. This Cmm has not been processed in any way by the Cmm pipeline. If you see that something is incorrect in that dump it means that the problem is located in the STG->Cmm pass. The last section, "Output Cmm", is also dumped in `HscMain` but this is done after the Cmm has been processed by the whole Cmm pipeline. All other sections are dumped by the !CmmPipeline. You can dump only selected passes with more specific flags. For example, if you know (or suspect) that the sinking pass is performing some incorrect transformations you can make the dump shorter by adding `-ddump-cmm-sp -ddump-cmm-sink` flags. This will produce only the "Layout Stack" dump (just before sinking pass) and "Sink assignments" dump (just after the sinking pass) allowing you to focus on the changes introduced by the sinking pass. 
     109"Cmm produced by new codegen" is emited in `HscMain` module after converting STG to Cmm. This Cmm has not been processed in any way by the Cmm pipeline. If you see that something is incorrect in that dump it means that the problem is located in the STG->Cmm pass. The last section, "Output Cmm", is also dumped in `HscMain` but this is done after the Cmm has been processed by the whole Cmm pipeline. All other sections are dumped by the Cmm pipeline. You can dump only selected passes with more specific flags. For example, if you know (or suspect) that the sinking pass is performing some incorrect transformations you can make the dump shorter by adding `-ddump-cmm-sp -ddump-cmm-sink` flags. This will produce only the "Layout Stack" dump (just before sinking pass) and "Sink assignments" dump (just after the sinking pass) allowing you to focus on the changes introduced by the sinking pass. 
    110110