[Haskell-cafe] vector operations

Roman Leshchinskiy rl at cse.unsw.edu.au
Mon Jun 11 22:29:56 CEST 2012


On 11/06/2012, at 18:52, Evan Laforge wrote:

> On Tue, May 29, 2012 at 12:52 PM, Roman Leshchinskiy <rl at cse.unsw.edu.au> wrote:
>> 
>> Vector should definitely fuse this, if it doesn't it's a bug. Please report if it doesn't for you. To verify, just count the number of letrecs in the optimised Core. You'll see one letrec if it has been fused and two if it hasn't.
> 
> I see two letrecs in find_before2, but both of them are on findIndex.
> I only have one findIndex so I'm not sure what's going on.  The first
> one calls the second, but there's an boxed Either argument in there,
> which must be coming out of vector internals.

Hmm, which version of GHC and what compiler flags are you using? I'm not familiar with ghc-core, maybe that's doing something wrong. Just run ghc -O2 -ddump-simpl and look at the output. Below is the code I'm getting for find_before2 with 7.4.2. As you can see, everything has been fused (although I notice that GHC isn't pushing x_a11p and y1_a124 into the branches for some reason, looks like a new regression but not a particularly bad one and nothing to do with fusion).

find_before2_rkk :: Int -> Vector Int -> Int
[GblId, Arity=2, Caf=NoCafRefs, Str=DmdType LU(LLL)m]
find_before2_rkk =
  \ (n_arE :: Int) (vec_arF :: Vector Int) ->
    case vec_arF `cast` ...
    of _ { Vector ipv_s2Jf ipv1_s2Jg ipv2_s2Jh ->
    case n_arE of _ { I# y_a11t ->
    case ># 0 y_a11t of _ {
      False ->
        letrec {
          $sfindIndex_loop_s2Qz [Occ=LoopBreaker]
            :: Int# -> Int# -> Int# -> Id (Maybe Int)
          [LclId, Arity=3, Str=DmdType LLL]
          $sfindIndex_loop_s2Qz =
            \ (sc_s2Q8 :: Int#) (sc1_s2Q9 :: Int#) (sc2_s2Qa :: Int#) ->
              case >=# sc_s2Q8 ipv1_s2Jg of _ {
                False ->
                  case indexIntArray# ipv2_s2Jh (+# ipv_s2Jf sc_s2Q8)
                  of wild_a2JM { __DEFAULT ->
                  let {
                    x_a11p [Dmd=Just L] :: Int#
                    [LclId, Str=DmdType]
                    x_a11p = +# sc1_s2Q9 wild_a2JM } in
                  case ># x_a11p y_a11t of _ {
                    False ->
                      $sfindIndex_loop_s2Qz (+# sc_s2Q8 1) x_a11p (+# sc2_s2Qa 1);
                    True -> (Just @ Int (I# sc2_s2Qa)) `cast` ...
                  }
                  };
                True -> (Nothing @ Int) `cast` ...
              }; } in
        case ($sfindIndex_loop_s2Qz 0 0 1) `cast` ... of _ {
          Nothing -> lvl_r2QO;
          Just i_arH ->
            case i_arH of _ { I# x_a11Q ->
            let {
              y1_a124 [Dmd=Just L] :: Int#
              [LclId, Str=DmdType]
              y1_a124 = -# x_a11Q 1 } in
            case <=# 0 y1_a124 of _ {
              False -> lvl_r2QO;
              True -> I# y1_a124
            }
            }
        };
      True -> lvl_r2QO
    }
    }
    }

Roman




More information about the Haskell-Cafe mailing list