[GHC] #6135: Unboxed Booleans

GHC ghc-devs at haskell.org
Fri Jun 7 15:54:03 CEST 2013


#6135: Unboxed Booleans
-------------------------------+--------------------------------------------
  Reporter:  benl              |          Owner:  jstolarek       
      Type:  feature request   |         Status:  patch           
  Priority:  normal            |      Milestone:  7.8.1           
 Component:  Compiler          |        Version:  7.4.1           
Resolution:                    |       Keywords:                  
        Os:  Unknown/Multiple  |   Architecture:  Unknown/Multiple
   Failure:  None/Unknown      |     Difficulty:  Unknown         
  Testcase:                    |      Blockedby:                  
  Blocking:                    |        Related:  #605            
-------------------------------+--------------------------------------------

Comment(by jstolarek):

 I spent some time on figuring out why my patch works. Here's what I come
 up with (hopefully I got things right).

 Previously the !PrimOps of type `Compare` used to return `Bool`
 (`prelude/PrimOp.lhs`):

 {{{
 getPrimOpResultInfo :: PrimOp -> PrimOpResultInfo
 getPrimOpResultInfo op
   = case (primOpInfo op) of
       Compare _ _  -> ReturnsAlg boolTyCon
 }}}

 I changed them to return `Int#`:

 {{{
 getPrimOpResultInfo :: PrimOp -> PrimOpResultInfo
 getPrimOpResultInfo op
   = case (primOpInfo op) of
       Compare _ _   -> ReturnsPrim (tyConPrimRep intPrimTyCon)
 }}}

 This is how primops are converted from Core to STG (`CoreToStg.lhs`,
 `coreToStgApp` function):

 {{{
         res_ty = exprType (mkApps (Var f) args)
         app = case idDetails f of
                 -- Some primitive operator that might be implemented as a
 library call.
                 PrimOpId op      -> ASSERT( saturated )
                                     StgOpApp (StgPrimOp op) args' res_ty
 }}}

 Previously `res_ty` was set to `Bool`, now it is `Int#`. STG
 representation of a primop is converted to Cmm (`StgCmmExpr.hs`) by
 `cgExpr` function:

 {{{
 cgExpr (StgOpApp op args ty) = cgOpApp op args ty
 }}}

 So previously `cgOpApp` function matched this guard:

 {{{
   | ReturnsAlg tycon <- result_info
   , isEnumerationTyCon tycon
         -- c.f. cgExpr (...TagToEnumOp...)
   = do dflags <- getDynFlags
        tag_reg <- newTemp (bWord dflags)
        cgPrimOp [tag_reg] primop args
        emitReturn [tagToClosure dflags tycon
                                 (CmmReg (CmmLocal tag_reg))]
 }}}
 and now it matches this one:
 {{{
   | ReturnsPrim rep <- result_info
   = do dflags <- getDynFlags
        res <- newTemp (primRepCmmType dflags rep)
        cgPrimOp [res] primop args
        emitReturn [CmmReg (CmmLocal res)]
 }}}
 The main difference being that there is no call to `tagToClosure`, which
 was the goal of this ticket - to return an unboxed unlifted value instead
 of a closure that needs to be entered or have its tag examined. This leads
 me to a conclusion: since `tagToClosure` is an implementation of
 `tagToEnum#` primop, there should be no performance difference between the
 previous version of code, where call to `tagToEnum#` was generated
 implicitly by the code generator, and the new primop wrappers, which make
 the call to `tagToEnum#` explicit. In theory at least, because kahan for
 some reason is slower. I'm investigating this but so far I found nothing
 that would be obvious.

 And I'm also working on identifying code that is no longer necessary. One
 thing that keeps me puzzled is that there are still primops that return
 `Bool`, e.g.

 {{{
 primop  SameMutVarOp "sameMutVar#" GenPrimOp
    MutVar# s a -> MutVar# s a -> Bool
 }}}

 I'm not sure if this allows me to remove special case that Simon M.
 mentioned.

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



More information about the ghc-tickets mailing list