[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