#5173: Implement forward substitution of constants in the Cmm mini-inliner
---------------------------------+------------------------------------------
    Reporter:  tibbe             |       Owner:              
        Type:  bug               |      Status:  patch       
    Priority:  normal            |   Component:  Compiler    
     Version:  7.0.3             |    Keywords:              
    Testcase:                    |   Blockedby:              
          Os:  Unknown/Multiple  |    Blocking:              
Architecture:  Unknown/Multiple  |     Failure:  None/Unknown
---------------------------------+------------------------------------------

Comment(by tibbe):

 For completeness, here's some real code that benefits from this
 optimization:

 {{{
 stH_ret()
         { update_frame: <none>
           has static closure: False type: 0
           desc: 0
           tag: 32
           stack: [Just _ssK::I64]
           srt: _no_srt_
         }
     cv1:
         _cv5::I64 = I64[R1 + 7];
         _cv7::I64 = 1;
         _cv9::I64 = I64[Sp + 8];
         _cvb::I64 = 1;
         _cvd::I64 = 8;
         _cvf::I64 = _cvd::I64 * 8;
         _cvh::I64 = (_cv5::I64 + 24) + (_cv7::I64 << 3);
         _cvj::I64 = (_cv9::I64 + 24) + (_cvb::I64 << 3);
         foreign "ccall"
           MO_Memcpy((_cvj::I64, PtrHint), (_cvh::I64, PtrHint),
 (_cvf::I64,),
                     (8,))[_unsafe_call_];
         I64[_cv9::I64] = stg_MUT_ARR_PTRS_DIRTY_info;
         _cvl::I64 = (_cv9::I64 + 24) + (I64[_cv9::I64 + 8] << 3);
         _cvn::I64 = _cvb::I64 >> 7;
         foreign "ccall"
           MO_Memset((_cvl::I64 + _cvn::I64, PtrHint), (1,),
                     ((_cvb::I64 + _cvd::I64 >> 7) - _cvn::I64 + 1,),
                     (8,))[_unsafe_call_];
         R1 = ghczmprim_GHCziUnit_Z0T_closure+1;
         Sp = Sp + 16;
         jump (I64[Sp + 0]) ();
 }
 }}}

 (`MO_Memcpy` and `MO_Memset` are `CallishMachOp`s that I'm currently
 adding. These `MachOp`s will generate unrolled loops in the backend, if
 the number of iterations is statically known.)

 Note how `_cvb` and `_cvd` are both constant and used more than once.
 Here's the optimized version, without forward substitution of constants:

 {{{
 stH_ret()
         { [const 1;, const 32;]
         }
     cv1:
         _cv9::I64 = I64[Sp + 8];
         _cvb::I64 = 1;
         _cvd::I64 = 8;
         _cvh::I64 = I64[R1 + 7] + 32;
         foreign "ccall"
           MO_Memcpy(((_cv9::I64 + 24) + (_cvb::I64 << 3), PtrHint),
                     (_cvh::I64, PtrHint), (_cvd::I64 << 3,),
 (8,))[_unsafe_call_];
         I64[_cv9::I64] = stg_MUT_ARR_PTRS_DIRTY_info;
         _cvn::I64 = _cvb::I64 >> 7;
         foreign "ccall"
           MO_Memset(((_cv9::I64 + 24) + ((I64[_cv9::I64 + 8] << 3) +
 _cvn::I64),
                      PtrHint),
                     (1,), ((_cvb::I64 + _cvd::I64 >> 7) + (1 -
 _cvn::I64),),
                     (8,))[_unsafe_call_];
         R1 = GHC.Unit.()_closure+1;
         Sp = Sp + 16;
         jump (I64[Sp + 0]) ();
 }
 }}}

 `_cv7` has been inlined, as it was used exactly once, but `_cvb` and
 `_cvd` haven't.

 Here's the optimized version with forward substitution of constants:

 {{{
 stH_ret()
         { [const 1;, const 32;]
         }
     cv1:
         _cv9::I64 = I64[Sp + 8];
         _cvh::I64 = I64[R1 + 7] + 32;
         foreign "ccall"
           MO_Memcpy((_cv9::I64 + 32, PtrHint), (_cvh::I64, PtrHint),
 (64,),
                     (8,))[_unsafe_call_];
         I64[_cv9::I64] = stg_MUT_ARR_PTRS_DIRTY_info;
         _cvn::I64 = 0;
         foreign "ccall"
           MO_Memset(((_cv9::I64 + 24) + ((I64[_cv9::I64 + 8] << 3) +
 _cvn::I64),
                      PtrHint),
                     (1,), (0 - _cvn::I64 + 1,), (8,))[_unsafe_call_];
         R1 = GHC.Unit.()_closure+1;
         Sp = Sp + 16;
         jump (I64[Sp + 0]) ();
 }
 }}}

 The code is better, but not perfect. The remaining reference to a register
 with a constant value is due to the mini-inliner only inlining constants,
 not expressions that could be folded into a constant.

 I'll leave this as future work for now.

-- 
Ticket URL: <http://hackage.haskell.org/trac/ghc/ticket/5173#comment:5>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler

_______________________________________________
Glasgow-haskell-bugs mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs

Reply via email to