Changes between Version 19 and Version 20 of Commentary/Compiler/IntegratedCodeGen


Ignore:
Timestamp:
Jun 9, 2008 11:28:02 AM (7 years ago)
Author:
simonpj
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • Commentary/Compiler/IntegratedCodeGen

    v19 v20  
    6666 
    6767 0. Convert from {{{STG}}} to an control flow graph {{{CmmGraph}}}: 
    68 {{{ 
    69 STG -> CmmGraph Cmm.Middle Cmm.Last 
    70 }}} 
    7168 0. Instruction selection: 
    72 {{{ 
    73 CmmGraph Cmm.Middle Cmm.Last -> CmmGraph I386.Middle I386.Last 
    74 }}} 
    7569 0. Optimise: 
    76 {{{ 
    77 CmmGraph I386.Middle I386.Last -> CmmGraph I386.Middle I386.Last 
    78 }}} 
    7970 0. Proc-point analysis, and transformation 
    80 {{{ 
    81 analyse :: CmmGraph I386.Middle I386.Last -> [BlockId] 
    82 transform :: [BlockId] -> CmmGraph I386.Middle I386.Last -> CmmGraph I386.Middle I386.Last 
    83 }}} 
     71 0. Register allocation 
     72 0. Stack layout 
     73 0. Tidy up 
    8474 
    8575 
     
    8777 
    8878Convert from {{{STG}}} to an control flow graph {{{CmmGraph}}} ([[GhcFile(compiler/cmm/ZipCfg.hs)]], [[GhcFile(compiler/cmm/ZipCfgCmmRep.hs)]]).  This step is Simon PJ's "new code generator" from September 2007.  This conversion may introduce new variables, stack slots, and compile-time constants.  
     79{{{ 
     80STG -> CmmGraph Cmm.Middle Cmm.Last 
     81}}} 
    8982   * Implements calling conventions for call, jump, and return instructions: all parameter passing is turned into data-movement instructions (register-to-register move, load, or store), and stack-pointer adjustments are inserted. After this point, calls, returns, and jumps are just control-transfer instructions -- the parameter passing has been compiled away.   
    9083   * How do we refer to locations on the stack when we haven't laid it out yet? The compiler names a stack slot using the idea of a "late compile-time constant," which is just a symbolic constant that will be replaced with an actual stack offset when the stack layout is chosen.One departure from the old code generator is that '''we do not build a {{{Cmm}}} abstract-syntax tree;''' instead we go straight to a control-flow graph. 
     
    117110  ..etc.. 
    118111}}} 
    119 This allows us to  '''make code improvements machine-independent''', by using machine-dependent functions to capture the semantics of instructions. 
     112This allows us to  '''make code improvements machine-independent''', by using machine-dependent functions to capture the semantics of instructions.  Figuring out precisely what the interace should be is a key step.  For example, to support copy propagation we might want an operation 
     113{{{  
     114  isCopy :: i -> Maybe (LocalReg,LocalReg) 
     115}}} 
     116Similarly, to support peephole optimsation (eg transform `x = y+2; p = bits32[x]` to `p = bits32[y+2]`) we might want something like 
     117{{{ 
     118  availExprs :: i -> [(LocalReg,CmmExpr)] 
     119  substExprs :: [(LocalReg,CmmExpr)] -> i -> Maybe i 
     120}}} 
     121The `substExprs` operation returns a `Just` iff a substitution took place. 
     122 
     123Interfaces like these would require the machine-specific abstract type `i` to contain enough information to reconstruct a `LocalReg` or `CmmExpr`.  Later one, we'll need to construct SRTs too, so we must continue to track pointer-hood. 
     124 
     125One possible implementation for `I386` or `Sparc` would be to use a generic RTL representation, together with a recogniser to maintain the machine invariant.  Our initial idea, though, is that  is an implementation choice.   
    120126 
    121127=== Optimisation === 
     
    135141=== Proc-point analysis === 
    136142 
    137 Proc-point analysis: {{{LGraph Instrs}}} (with variables, stack slots, and compile-time constants) -> {{{LGraph Instrs}}} (with variables, stack slots, and compile-time constants) 
     143{{{ 
     144analyse :: CmmGraph I386.Middle I386.Last -> [BlockId] 
     145transform :: [BlockId] -> CmmGraph I386.Middle I386.Last -> CmmGraph I386.Middle I386.Last 
     146}}} 
     147Both input and output still have variables and stack-slot addressing modes. 
     148 
    138149  * Proc points are found, and the appropriate control-transfer instructions are inserted. 
    139150  * Why so early(before register allocation, stack layout)? Depending on the back end (think of C as the worst case), the proc-point analysis might have to satisfy some horrible calling convention. We want to make these requirements explicit before we get to the register allocator.  We also want to '''exploit the register allocator''' to make the best possible decisions about ''which live variables (if any) should be in registers at a proc point''.