adding isWHNF primop to 5.00.2 native code generator

Bernard James POPE bjpop@cs.mu.OZ.AU
Wed, 1 Aug 2001 19:46:50 +1000 (EST)

Hi all,

More mind boggling questions on prim ops :)

I am happy with isWHNF that is implemented with:

#define isHNFzh(r,a) r=(! closure_THUNK((StgClosure *)a))

I will re-write for the IO Monad later.

I want to mimic this behaviour in the native code
generator.

Sigbjorn gave me this suggestion, which is based on
DataToTagOp.

\begin{code}
primCode [res] IsHNF [arg]
= let res'        = amodeToStix res
arg'        = amodeToStix arg
arg_info    = StInd PtrRep arg'
word_32     = StInd WordRep (StIndex PtrRep arg_info (StInt (-1)))
masked_le32 = StPrim SrlOp [word_32, StInt 16]
masked_be32 = StPrim AndOp [word_32, StInt 65535]
#ifdef WORDS_BIGENDIAN
#else
#endif
not_a_thunk = StPrim IntEqOp [ StPrim AndOp [ty_info, StInt 0x10]
, StInt 0x0
]
-- ToDo: don't hardwire the value of _THUNK from InfoTables.h
in
returnUs (\ xs -> assign : xs)
\end{code}

I get different results with the version using the C macro and
the native code version. In particular I get the wrong (unexpected
result from the native code version).

The C macro version works like this (uses these macros):

#define closureFlags(c)         (closure_flags[get_itbl(c)->type])
-- in ghc/includes/InfoTables.h

#define closure_THUNK(c)        (  closureFlags(c) & _THU)
-- in ghc/includes/InfoTables.h

-- in ghc/includes/ClosureMacros.h

#define INFO_PTR_TO_STRUCT(info) ((StgInfoTable *)(info) - 1)
-- in ghc/includes/ClosureMacros.

The (-1) scares me a little bit, in INFO_PTR_TO_STRUCT.

The array closure_flags[] is just a look up table, indexed by the
closure type. So the key part of the code above is:

get_itbl(c)->type

In the native code version above, the lines below act like get_itbl(c):

arg_info    = StInd PtrRep arg'
word_32     = StInd WordRep (StIndex PtrRep arg_info (StInt (-1)))

After this I am lost. It seems to be grabbing the top or bottom 16 bits
of word_32 (depending on endianness) and then ANDing those bits with
0x10 (which is the bit mask for _THU), and checking for 0.

My feeling is that I should be finding out the "type" field from
the closure and then switching on its value.

I don't understand the native code generator well enough. I am assuming
that closures are laid out the same way as via-C, in particular that
there is going to be some stuff in the info table before the "type"
field (this looks variable depending on how things are
built). Basically I'm looking for a way to do the equivalent of
"->type". Maybe there is a better way to do it.

Thanks once again, and apologies if I missed something obvious.

Cheers,
Bernie.