Changes between Version 34 and Version 35 of Commentary/Compiler/NewCodeGenStupidity


Ignore:
Timestamp:
Feb 8, 2012 4:03:15 PM (2 years ago)
Author:
simonmar
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • Commentary/Compiler/NewCodeGenStupidity

    v34 v35  
    33Presently compiling using the new code generator results in a fairly sizable performance hit, because the new code generator produces sub-optimal (and sometimes absolutely terrible code.) There are [http://darcs.haskell.org/ghc/compiler/cmm/cmm-notes a lot of ideas for how to make things better]; the idea for this wiki page is to document all of the stupid things the new code generator is doing, to later be correlated with specific refactorings and fixes that will hopefully eliminate classes of these stupid things. The hope here is to develop a sense for what the most endemic problems with the newly generated code is. 
    44 
    5 == Double proc points == 
    6  
    7 Given a simple case expression 
    8  
    9 {{{ 
    10 f x = case x of 
    11          I# y -> y 
    12 }}} 
    13  
    14 we generate *two* proc points, not one. 
    15  
    16 {{{ 
    17   cbR: 
    18       if (_sbl::I64 & 7 != 0) goto cbU; else goto cbV; 
    19   cbU: 
    20       _sbp::I64 = _sbl::I64; 
    21       goto cbW; 
    22   cbV: 
    23       R1 = _sbl::I64; 
    24       I64[(young<cbE> + 8)] = cbE; 
    25       call (I64[_sbl::I64])(...) returns to Just cbE (8) (8) with update frame 8; 
    26   cbE: 
    27       _sbp::I64 = R1; 
    28       goto cbW; 
    29   cbW: 
    30       _sbo::I64 = I64[_sbp::I64 + 7]; 
    31       _cbJ::I64 = _sbo::I64 + 1; 
    32       // emitReturn: Sequel: Return 
    33       R1 = _cbJ::I64; 
    34       call (I64[(old + 8)])(...) returns to Nothing (8) (0) with update frame 8; 
    35 }}} 
    36  
    37 Both `cbE` and `cbW` are going to become proc points. 
    38  
    39 To avoid it we should generate code that re-uses `cbE` as the destination for the first `if`; that is, we need to load up the registers as if we were returning from the call.  This needs some refactoring in the code generator. 
    405 
    416== Cantankerous Comparisons == 
     
    334299Another cause of all of these temporary variables is that the new code generator immediately assigns any variables that were on the stack to temporaries immediately upon entry to a function. This is on purpose. The idea is we optimize these temporary variables away. 
    335300 
     301== Double proc points == 
     302 
     303FIXED in newcg branch. 
     304 
     305Given a simple case expression 
     306 
     307{{{ 
     308f x = case x of 
     309         I# y -> y 
     310}}} 
     311 
     312we generate *two* proc points, not one. 
     313 
     314{{{ 
     315  cbR: 
     316      if (_sbl::I64 & 7 != 0) goto cbU; else goto cbV; 
     317  cbU: 
     318      _sbp::I64 = _sbl::I64; 
     319      goto cbW; 
     320  cbV: 
     321      R1 = _sbl::I64; 
     322      I64[(young<cbE> + 8)] = cbE; 
     323      call (I64[_sbl::I64])(...) returns to Just cbE (8) (8) with update frame 8; 
     324  cbE: 
     325      _sbp::I64 = R1; 
     326      goto cbW; 
     327  cbW: 
     328      _sbo::I64 = I64[_sbp::I64 + 7]; 
     329      _cbJ::I64 = _sbo::I64 + 1; 
     330      // emitReturn: Sequel: Return 
     331      R1 = _cbJ::I64; 
     332      call (I64[(old + 8)])(...) returns to Nothing (8) (0) with update frame 8; 
     333}}} 
     334 
     335Both `cbE` and `cbW` are going to become proc points. 
     336 
     337To avoid it we should generate code that re-uses `cbE` as the destination for the first `if`; that is, we need to load up the registers as if we were returning from the call.  This needs some refactoring in the code generator. 
     338 
    336339== Rewriting stacks == 
    337340