Ticket #6087 (new bug)

Opened 13 months ago

Last modified 2 months ago

Join points need strictness analysis

Reported by: simonpj Owned by:
Priority: normal Milestone: 7.6.2
Component: Compiler Version: 7.4.1
Keywords: Cc: stefan@…
Operating System: Unknown/Multiple Architecture: Unknown/Multiple
Type of failure: Runtime performance bug Difficulty: Unknown
Test Case: Blocked By:
Blocking: Related Tickets:

Description

I came across this code in the nofib/spectral progam knights, in the code for KnightHeuristic.possibleMoves:

let {
  $j_sU3
    :: GHC.Types.Int -> GHC.Types.Int -> [KnightHeuristic.Direction]
  [LclId, Arity=2]
  $j_sU3 =
    \ (ww2_sRl :: GHC.Types.Int) (ww3_sRm :: GHC.Types.Int) ->
      case ww2_sRl of ww4_XQY { GHC.Types.I# ww5_sQU ->
      case GHC.Prim.>=# ww5_sQU 1 of _ {
        GHC.Types.False -> go1_azF ys_azM;
        GHC.Types.True ->
          case ds1_azR of _ { GHC.Types.I# y1_azp ->
          case GHC.Prim.<=# ww5_sQU y1_azp of _ {
            GHC.Types.False -> go1_azF ys_azM;
            GHC.Types.True ->
              case ww3_sRm of wild6_XAB { GHC.Types.I# x_XAE ->
              case GHC.Prim.>=# x_XAE 1 of _ {
                GHC.Types.False -> go1_azF ys_azM;
                GHC.Types.True ->
                  case GHC.Prim.<=# x_XAE y1_azp of _ {
                    GHC.Types.False -> go1_azF ys_azM;
                    GHC.Types.True ->
                      case GHC.List.notElem
                             @ ChessSetList.Tile
                             ChessSetList.isSquareFree_$dEq
                             (ww4_XQY, wild6_XAB)
                             wild2_azW
                      of _ {
                        GHC.Types.False -> go1_azF ys_azM;
                        GHC.Types.True ->
                          GHC.Types.:
                            @ KnightHeuristic.Direction y_azL (go1_azF ys_azM)
                      }
                  }
              }
              }
          }
          }
      }
      } } in
case y_azL of _ {
  KnightHeuristic.UL ->
    $j_sU3
      (case ww_sQJ of _ { GHC.Types.I# x_aya ->
       GHC.Types.I# (GHC.Prim.-# x_aya 1)
       })
      (case ww1_sQK of _ { GHC.Types.I# x_aya ->
       GHC.Types.I# (GHC.Prim.-# x_aya 2)
       });
  KnightHeuristic.UR ->
    $j_sU3
      (case ww_sQJ of _ { GHC.Types.I# x_ayl ->
       GHC.Types.I# (GHC.Prim.+# x_ayl 1)
       })
      (case ww1_sQK of _ { GHC.Types.I# x_aya ->
       GHC.Types.I# (GHC.Prim.-# x_aya 2)
       });

...lots more similar case alternatives follow...

Just look at all those Ints getting boxed, and the immediately unboxed by the join point! The strictness analyser would spot this easily, but presumably the join point is constructed after strictness analysis.

There must be an opportunity here to run a later strictness analysis pass.

Change History

Changed 13 months ago by stefan

  • cc stefan@… added

Changed 8 months ago by igloo

  • milestone changed from 7.6.1 to 7.6.2

Changed 2 months ago by nfrisby

A second demand analysis at the end of the pipeline does help here.

                 let {
                    $j_sRv [Dmd=<C(C(S)),U>]
                      :: GHC.Types.Int
                         -> GHC.Types.Int
                         -> [KnightHeuristic.Direction]
    Entries     Allocs    Alloc'd Arity    Kinds      Function                      
--------------------------------------------------------------------------------
       6003      51444       1334      1    L          go{v s12q} (main:KnightHeuristic)
       5336      24190          0      2    SS         $j{v s12J} (main:KnightHeuristic)

becomes

       6003      24764       1334      1    L          go{v s187} (main:KnightHeuristic)
       5336      31464          0      2    iS         $w$j{v s18r} (main:KnightHeuristic)

This is ~ -7% overall change in allocation.

At O2 (and without my more precise ticky numbers), the opportunity for this improvement gets a bit clobbered, but others apparently show up.

        567      20851      1     0    L          go{v s1Ba} (main:KnightHeuristic)
        400       5200      2     0    ET         main:KnightHeuristic.move{v rfN}
        110       2274      5     0    SSiSL      main:KnightHeuristic.$wdescendents{v r1qa}
        168       1002      1     0    S          main:KnightHeuristic.descAndNo{v rfU}

becomes

        567      18204      1     0    L          go{v s1MK} (main:KnightHeuristic)

        111        872      5     0    SSiSL      main:KnightHeuristic.$wdescendents{v r1Cl}
        169        835      4     0    SSTL       main:KnightHeuristic.$wdescAndNo{v r1Cp}

For -3.8% allocation.

Note: See TracTickets for help on using tickets.