
#7940: Building GHC 7.7.20130526 (perf) for Windows x86_64 fails with Cmm lint error -------------------------------+-------------------------------------------- Reporter: awson | Owner: Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 7.7 Keywords: | Os: Windows Architecture: x86_64 (amd64) | Failure: Building GHC failed Difficulty: Unknown | Testcase: Blockedby: | Blocking: Related: | -------------------------------+-------------------------------------------- Comment(by thoughtpolice): So, just so others can take note before I mislead myself, I believe the 'root' of the problem is here in StgCmmTicky: {{{ bumpTickyLitBy :: CmmLit -> Int -> FCode () bumpTickyLitBy lhs n = do dflags <- getDynFlags -- All the ticky-ticky counters are declared "unsigned long" in C emit (addToMem (cLong dflags) (CmmLit lhs) n) bumpTickyLitByE :: CmmLit -> CmmExpr -> FCode () bumpTickyLitByE lhs e = do dflags <- getDynFlags -- All the ticky-ticky counters are declared "unsigned long" in C emit (addToMemE (cLong dflags) (CmmLit lhs) e) }}} Essentially when the Cmm parser sees 'TICKY_ALLOC_PRIM` in PrimOps.cmm, it will bump several counters defined in the RTS. The type of those counters (in Cmm terms) is specified as 'cLong dflags' in the above code. But this is only coincidentally correct on the platforms we supported until now. Most unix machines follow the LP64 data model. So on 64 bit machines, 'long' is 64 bit, and so are pointers. 'int' 32 bit. But Windows 64 follows the LLP64 model: both 'long' AND 'int' are 32bit, while 'long long' and ptrs are 64 bit. That means on Win64, 'cLong dflags' will be 32, while on Unix it would be 64. So it is only coincidental that 'long' has aligned with the native word size, until now. The invocation that triggers this in PrimOps.cmm is: {{{ stg_newByteArrayzh ( W_ n ) { W_ words, payload_words; gcptr p; MAYBE_GC_N(stg_newByteArrayzh, n); payload_words = ROUNDUP_BYTES_TO_WDS(n); words = BYTES_TO_WDS(SIZEOF_StgArrWords) + payload_words; ("ptr" p) = ccall allocate(MyCapability() "ptr",words); TICK_ALLOC_PRIM(SIZEOF_StgArrWords,WDS(payload_words),0); // <----- problematic SET_HDR(p, stg_ARR_WORDS_info, CCCS); StgArrWords_bytes(p) = n; return (p); } }}} where SIZEOF_StgArrWords comes down to the literal '8 + 8' via CPP, which I imagine is inferred as a word-sized (64bit) quantity. Thus the type error occurs when addToMemE elaborates the LHS as 32bit thanks to cLong. Also, digging into includes/stg/Types.h, we see: {{{ #if SIZEOF_VOID_P == 8 typedef StgInt64 StgInt; typedef StgWord64 StgWord; typedef StgInt32 StgHalfInt; typedef StgWord32 StgHalfWord; #define FMT_Word FMT_Word64 #define FMT_HexWord FMT_HexWord64 #define FMT_Int FMT_Int64 #else ... }}} and in includes/stg/Ticky.h: {{{ EXTERN StgInt ALLOC_PRIM_ctr INIT(0); EXTERN StgInt ALLOC_PRIM_adm INIT(0); EXTERN StgInt ALLOC_PRIM_gds INIT(0); EXTERN StgInt ALLOC_PRIM_slp INIT(0); }}} So in any case, the Ticky code comments are certainly wrong now: the counters are not of 'unsigned long.' So I think the correct thing is that ticky counters are all word sized. But looking at the code some more, this cLong business seems to be baked into the ticky stuff a bit. I'm copying a CD (slowly) to make a build machine, but perhaps someone can build on my suspicions? Thoughts? I believe Nicholas Frisby was around this area recently, so perhaps he has input. -- Ticket URL: http://hackage.haskell.org/trac/ghc/ticket/7940#comment:5 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler