Am I right in thinking that by just putting
GhcUnregisterised=YES SplitObjs=NO
in mk/build.mk every time you build GHC it ought to not only work on arches with bit-rotted mangler support but also those with none attempted? Where work means compiles the same set of programs, but the result (as well as the compilation) will be slower?
Yes, with the caveat that this applies only to the the code *generated* by the GHC you're building.
Starting with a reg compiler producing reg code and iterating a standard configure/make/make install with 6.0.1 gives these numbers on x86:
70m5.850s 86m27.550s 86m26.350s
so it looks like this is about 25% slower, although I don't know how much it will vary by architecture. This isn't purely testing GHC of course, but I think it's probably pretty close.
Interesting. Bear in mind that a lot of the time is spent in GCC, and that is going to be roughly the same for registerised vs. unregisterised, so overall compile times don't look much different. However, I think you'll find that ordinary Haskell programs will vary by about a factor of 2 in performance between registerised & unregisterised (last time I checked was a few years ago, though). What are the binary sizes like?
This seems better than no GHC at all for unsupported arch/OS combinations, and I unfortunately don't have the time to learn the details of what needs to be done and all the assembly languages and calling conventions that Debian supports.
It would also mean that anyone who does want to try to get it working registerised on an arch could skip the cross-porting stage.
Sure, shipping an unregisterised port is completely acceptable.
Incidentally, it looks to me like the comment
# NOTE: this is not the same as building the compiler itself # unregisterised. That's done by either (a) bootstrapping with a # compiler that was built with GhcUnregisterised=YES, or (b) # bootstrapping with a compiler that has way 'u' libraries, and the # flag '-unreg' is added to GhcHcOpts above.
about GhcUnregisterised in mk/config.mk is outdated given the 2-stage building process that is now the default?
Hmm, I should update that comment. Cheers, Simon
On Mon, Sep 15, 2003 at 03:18:43PM +0100, Simon Marlow wrote:
Starting with a reg compiler producing reg code and iterating a standard configure/make/make install with 6.0.1 gives these numbers on x86:
70m5.850s 86m27.550s 86m26.350s
so it looks like this is about 25% slower, although I don't know how much it will vary by architecture. This isn't purely testing GHC of course, but I think it's probably pretty close.
Interesting. Bear in mind that a lot of the time is spent in GCC, and
Ah, I hadn't thought about that, I had only considered the cases where gcc was explicitly used to compile C sources.
that is going to be roughly the same for registerised vs. unregisterised, so overall compile times don't look much different. However, I think you'll find that ordinary Haskell programs will vary by about a factor of 2 in performance between registerised & unregisterised (last time I checked was a few years ago, though).
Looks like it hasn't changed then - MAG's testsuite with some of MAG's optimisations removed takes 5m55.710s vs 12m35.560s (compile times were 2m46.870s vs 3m18.610s).
What are the binary sizes like?
magdcalc is 2730251 (reg) 7697141 (unreg) before stripping and 1375696 (reg) 4771196 (unreg) after. Ian
On Mon, Sep 15, 2003 at 03:18:43PM +0100, Simon Marlow wrote:
Am I right in thinking that by just putting
GhcUnregisterised=YES SplitObjs=NO
in mk/build.mk every time you build GHC it ought to not only work on arches with bit-rotted mangler support but also those with none attempted? Where work means compiles the same set of programs, but the result (as well as the compilation) will be slower?
Yes, with the caveat that this applies only to the the code *generated* by the GHC you're building.
Ah, and also no GHCi or TH on Linux unless you are x86, sparc or IA64. The GHCi section at the bottom of http://www.haskell.org/ghc/docs/latest/html/building/sec-porting-ghc.html looks like it might be a bit optimistic to me. A case for "switch (ehdr->e_machine)" must be added at least, and it looks as though some other tweaking and handling of relocations (I guess the ones in there are the ones that it belched on during porting?) is generally necessary.
Sure, shipping an unregisterised port is completely acceptable.
OK, I uploaded s390, hppa and alpha unregisterised for Debian unstable earlier today, with ppc to follow shortly I hope (x86, sparc and ia64 are already there registerised). I needed to apply the following patches to get them to build (this is largely to files that only matter for registerised building, but it was easier to fix them than hack the Makefiles): Numerous additions to configure/configure.in. I can add these in CVS, but I'm not sure if I should add +s390-ibm-linux*) + HostPlatform=s390-ibm-linux + TargetPlatform=s390-ibm-linux #hack + BuildPlatform=s390-ibm-linux #hack + HostPlatform_CPP='s390_ibm_linux' + HostArch_CPP='s390' + HostVendor_CPP='ibm' + HostOS_CPP='linux' + ;; as it is or with unknown instead of ibm? powerpc: --- ghc6-6.0.1.orig/ghc/compiler/nativeGen/MachCode.lhs +++ ghc6-6.0.1/ghc/compiler/nativeGen/MachCode.lhs @@ -41,7 +41,7 @@ NatM, thenNat, returnNat, mapNat, mapAndUnzipNat, mapAccumLNat, getDeltaNat, setDeltaNat, getUniqueNat, - IF_OS_darwin(addImportNat COMMA,) + IF_ARCH_powerpc(addImportNat COMMA,) ncgPrimopMoan, ncg_target_is_32bit ) [ addImportNat is later used in a #if powerpc_TARGET_ARCH - I don't know which is actually right, but as long as it compiles it doesn't matter for an unreg build ] alpha: --- ghc6-6.0.1.orig/ghc/includes/Stg.h +++ ghc6-6.0.1/ghc/includes/Stg.h @@ -33,6 +33,8 @@ # endif #endif +#include "TailCalls.h" + /* Configuration */ #include "config.h" @@ -186,7 +188,6 @@ #include "SMP.h" #include "MachRegs.h" #include "Regs.h" -#include "TailCalls.h" #include "Block.h" /* RTS public interface */ --- ghc6-6.0.1.orig/ghc/includes/TailCalls.h +++ ghc6-6.0.1/ghc/includes/TailCalls.h @@ -83,7 +83,9 @@ #ifdef alpha_TARGET_ARCH +#ifdef IN_STG_CODE register void *_procedure __asm__("$27"); +#endif #define JMP_(cont) \ do { _procedure = (void *)(cont); \ --- ghc6-6.0.1.orig/ghc/rts/Adjustor.c +++ ghc6-6.0.1/ghc/rts/Adjustor.c @@ -73,7 +73,7 @@ #if defined(alpha_TARGET_ARCH) /* To get the definition of PAL_imb: */ -#include <machine/pal.h> +#include <asm/pal.h> #endif #if defined(ia64_TARGET_ARCH) [ Don't know if this would break other OSes as it stands - could ifdef it ] --- ghc6-6.0.1.orig/ghc/rts/Signals.c +++ ghc6-6.0.1/ghc/rts/Signals.c @@ -19,7 +19,7 @@ #include "StablePriv.h" #ifdef alpha_TARGET_ARCH -# include <machine/fpu.h> +# include <asm/fpu.h> #endif #ifdef HAVE_UNISTD_H [ As above ] hppa: --- ghc6-6.0.1.orig/libraries/OpenGL/Makefile +++ ghc6-6.0.1/libraries/OpenGL/Makefile @@ -26,6 +26,10 @@ SRC_HC_OPTS += -DCALLCONV=ccall endif +ifeq "$(hppa_TARGET_ARCH)" "1" +SRC_HC_OPTS += -optc-mbig-switch +endif + SRC_HADDOCK_OPTS += -t "HOpenGL Libraries (OpenGL package)" -p prologue.txt # yeuch, have to get GL_CFLAGS & GL_LIBS in through CPP to package.conf.in [ this due to a compile failing with ../../ghc/compiler/ghc-inplace -H16m -O -Wall -fffi -Iinclude '-#include "HsOpenGL.h"' -cpp -I/usr/X11R6/include -DCALLCONV=ccall -package-name OpenGL -O -Rghc-timing -package base -hisuf p_hi -hcsuf p_hc -osuf p_o -prof -c Graphics/Rendering/OpenGL/GL/QueryUtils.hs -o Graphics/Rendering/OpenGL/GL/QueryUtils.p_o -ohi Graphics/Rendering/OpenGL/GL/QueryUtils.p_hi /tmp/ghc2550.s: Assembler messages: /tmp/ghc2550.s:46535: Error: Field out of range [-262144..262143] (262648). /tmp/ghc2550.s:46538: Error: Field out of range [-262144..262143] (263424). [more of the same] It need only apply to this file and any other affected, but I don't know if there's an easy way to do that ] alpha and hppa (probably): --- ghc6-6.0.1.orig/ghc/includes/PrimOps.h +++ ghc6-6.0.1/ghc/includes/PrimOps.h @@ -254,7 +254,7 @@ EXTFUN_RTS(catchzh_fast); EXTFUN_RTS(raisezh_fast); -extern void stg_exit(I_ n) __attribute__ ((noreturn)); +extern void stg_exit(int n) __attribute__ ((noreturn)); /* ----------------------------------------------------------------------------- --- ghc6-6.0.1.orig/ghc/rts/MBlock.h +++ ghc6-6.0.1/ghc/rts/MBlock.h @@ -75,6 +75,16 @@ # define HEAP_ALLOCED(p) ((StgPtr)(p) >= (StgPtr)(HEAP_BASE)) # define MARK_HEAP_ALLOCED(p) do {} while(0) +#elif SIZEOF_VOID_P == 8 +/* XXX: This is a HACK, and will not work in general! We just use the + * lower 32 bits of the address, and do the same as for the 32-bit + * version. As long as the OS gives us memory in a roughly linear + * fashion, it won't go wrong until we've allocated 4G. */ +# define MBLOCK_MAP_SIZE 4096 +# define MBLOCK_MAP_ENTRY(p) (((StgWord)(p) & 0xffffffff) >> MBLOCK_SHIFT) +# define HEAP_ALLOCED(p) (mblock_map[MBLOCK_MAP_ENTRY(p)]) +# define MARK_HEAP_ALLOCED(p) (mblock_map[MBLOCK_MAP_ENTRY(p)] = 1) + #else # error HEAP_ALLOCED not defined #endif --- ghc6-6.0.1.orig/ghc/rts/RtsUtils.h +++ ghc6-6.0.1/ghc/rts/RtsUtils.h @@ -27,7 +27,7 @@ extern nat stg_strlen(char *str); /*Defined in Main.c, but made visible here*/ -extern void stg_exit(I_ n) __attribute__((noreturn)); +extern void stg_exit(int n) __attribute__((noreturn)); char *time_str(void); char *ullong_format_string(ullong, char *, rtsBool); Thanks Ian
On Wed, Sep 17, 2003 at 05:14:36PM +0100, Ian Lynagh wrote:
alpha:
--- ghc6-6.0.1.orig/ghc/includes/Stg.h +++ ghc6-6.0.1/ghc/includes/Stg.h @@ -33,6 +33,8 @@ # endif #endif
+#include "TailCalls.h" + /* Configuration */ #include "config.h"
Ooops, TailCalls.h wants to be below config.h or registerised builds fail with JMP_ and friends being undefined symbols. Ian
participants (2)
-
Ian Lynagh -
Simon Marlow