GHC Alpha port?

Simon Marlow simonmar@microsoft.com
Thu, 19 Jul 2001 10:36:31 +0100


> For better or for worse, this message will be one full of questions...
>=20
> It took a couple (one? two? I can't remember) iterations of ghc
> building itself purely on the Alpha before the .hc files reached
> fixpoint...  I suspect it's because the compiler on i386-linux didn't
> realise that it could fit an entire double in one word.

Yes, I think that's because you were using the i386-linux config to
build the first set of .hc files - it should have been possible to use
the Alpha config.h at this point.

> I've been looking for test suites to run, to make myself more
> confident of the port.  I found two likely suspects in the CVS
> repository, namely fptools/testsuite and fptools/ghc/tests.  Neither
> of them pass without unexpected failures on a clean i386-linux build,
> though.  Any suggestions?

We're in the process of transitioning from the old suite in ghc/tests to
the new on in fptools/testsuite.  Use ghc/tests for now, and look for
failures that don't also fail on i386-linux.

> At what seems now to be a long time ago you said:
>=20
> > Once you have an unregisterised build working (&=20
> bootstrapped), you can
> > start trying to get the mangler going for full registerised support.
> > The mangler has Alpha support, but it is old and bound to=20
> be rotten to
> > some extent.
>=20
> Any suggestions for how I should start on this, and what to watch out
> for?  The mangler looks, well, evil.  (Time to glorify it, as was done
> to the driver?)

It's evil, but I don't think we're going to glorify it (it's not clear
that a Haskell version would be any less evil, anyhow).  It's more
likely that we'll eventually ditch it and do something else, but exactly
what we don't know yet.

It shouldn't be too hard to get the mangler going on Alpha again, given
a working knowledge of Alpha assembly.  It basically does the following
things:  it puts the info table next to the entry code for a closure,
puts the fast entry point directly after the slow entry point and
eliminates the jump in between, and removes the "prologue" and
"epilogue" code from the C functions so that tail-calls work properly.

To get a fully registerised compiler working, you also have to check the
register assignment in includes/MachRegs.h, the tail call settings in
includes/TailCalls.h, and the C<->Haskell glue code in rts/StgCRun.c.

Let me know if you need any more help.

> Regarding our wanting to
>=20
> >   - add some support for cross-compilation to the build system.
>=20
> The only cross-compilation support I can see that isn't too hard to
> add would be documented procedures for shipping the "three wrinkles"
> between the build and target systems: ghc/includes/config.h, .hs
> output from hsc2hs, and ghc/compiler/main/Config.hs.  Is this kind of
> support basically what you meant, or did you have something else in
> mind?

Well, I guess a set of instructions would be fine.  I had in mind some
build system support for cross-compilation, but that probably has a low
payoff to effort ratio.

> >   - write down exactly what one needs to do to make this work, and
> >     put the instructions in the build system documentation.
>=20
> I'd be happy to write down what I did in the near future.  It's
> basically the standard steps for creating .hc files, with the
> abovementioned "three wrinkles".  (Provided that the patches I just
> sent are applied -- prod prod :).

Great - if you write down the procedure, I'll mark it up for the build
system documentation.

> > >     SOLUTION: Modify MachDeps.h to #include the config.h from
> > >     alpha-osf3, even when compiling on i386-linux.
> > Yep: for cross compilation of the .hc files, the first=20
> thing to do is
> > run ./configure on the target platform and take the output=20
> back to the
> > host.
>=20
> I didn't overwrite the i386 config.h with the Alpha one -- I only
> changed MachDeps.h and ArrayBase.hs.  Should I have taken the more
> drastic route of overwriting?

I suspect that overwriting is the right way to do it.  But again, I'm
sure there are one or two wrinkles to work out.

> By the way, why does MachDeps.h #define FLOAT_SIZE_IN_BYTES to be
> SIZEOF_DOUBLE rather than SIZEOF_FLOAT if SIZEOF_DOUBLE =3D=3D
> SIZEOF_VOID_P?

That's a hangover from the way we used to do floats on 64-bit machines:
they used to be the same size as a Double, because after all you have a
full double word to store them in.  We ditched that because you need to
have a real float-sized object for communicating with external C
functions.

> > > The assertion in question is:
> > >       /* make sure the info pointer is into text space */
> > >       ASSERT(q && (LOOKS_LIKE_GHC_INFO(GET_INFO(q))
> > >                    || IS_HUGS_CONSTR_INFO(GET_INFO(q))));
> > >
> > > It seems that the GC code is sensitive to the layout of=20
> the virtual
> > > memory address space.  In particular, I had to change=20
> HEAP_BASE from
> > > 0x50000000 to 0x200000000L in MBlock.h to get GC to work even with
> > > -static.
> >
> > So it doesn't work without -static?  A HEAP_BASE change is not
> > unexpected, it all depends where the system puts its shared=20
> libraries.
>=20
> Okay, so with -static, I easily found the seemingly working setting of
> HEAP_BASE =3D=3D 0x180000000L (with the help of some Alpha assembly
> programming documentation).  Without -static, is there some way to
> (reliably?) know what HEAP_BASE should be set to?

You need to get a memory map of a typical process and find a free spot,
preferably at a higher address than the code of the process (shared
libraries don't count).  eg. on Linux, it's something like 'cat
/proc/<n>/maps'.

> I'm not even sure if the HEAP_BASE setting is the problem, but it
> seems likely.  (Specifically: When I looked at the assert failure core
> dump inside gdb, GET_INFO(q) did in fact look like ghc info to my
> human eyes; the reason LOOKS_LIKE_GHC_INFO(GET_INFO(q)) was false was
> that HEAP_ALLOCED(GET_INFO(q)) was true.)
>
> The getMBlocks function in MBlock.c does not check to make sure that
> the pointer returned by mmap() is the address it asked for.  Should
> it?

It checks that the block is properly aligned, which is enough.  I
suspect that the case where mmap returns a block which is properly
aligned but isn't at the address we asked for never happens, though.

> An entirely separate question: Why are there both rts/Linker.h and
> includes/Linker.h?

Good question.  I'll investigate.

Cheers,
	Simon