summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergei Trofimovich <slyfox@gentoo.org>2017-03-29 17:30:50 -0400
committerBen Gamari <ben@smart-cactus.org>2017-03-29 18:06:21 -0400
commit01b062ec3fa138b92124ce7ca4deca0ddcb474ea (patch)
treeb37ab33bf148c86aa3d7aa94f450d4ef8a248e89
parent26c95f46e679fb73e1ec2bec2be0801c72fd1449 (diff)
downloadhaskell-01b062ec3fa138b92124ce7ca4deca0ddcb474ea.tar.gz
unique: fix UNIQUE_BITS crosscompilation (Trac #13491)
The #13491 manifests best when we try to crosscompile from 32-bit (i386-linux) to 64-bit (powerpc64-linux) system: ./configure --target=powerpc64-unknown-linux-gnu The build fails at assembly time: "inplace/bin/ghc-stage1" ... -c rts/StgStartup.cmm /tmp/ghc19687_0/ghc_4.s: Assembler messages: /tmp/ghc19687_0/ghc_4.s:11:0: error: Error: unknown pseudo-op: `.l' | 11 | .L<\x00>4: | ^ That happens because UNIQUE_BITS is defined in terms of WORD_SIZE_IN_BITS macro: #define UNIQUE_BITS (WORD_SIZE_IN_BITS - 8) WORD_SIZE_IN_BITS is 64 bits (equals to target value) while ghc-stage1 is still running on i386-linux The fix is to stop relying on target macros and use host's 'sizeof (HsInt)' and 'finiteBitSize' way to determine unique layout. Signed-off-by: Sergei Trofimovich <slyfox@gentoo.org> Test Plan: build i386-to-powerpc64 crosscompiler Reviewers: rwbarton, austin, bgamari Reviewed By: bgamari Subscribers: RyanGlScott, thomie Differential Revision: https://phabricator.haskell.org/D3397
-rw-r--r--compiler/Unique.h8
-rw-r--r--compiler/basicTypes/UniqSupply.hs2
-rw-r--r--compiler/basicTypes/Unique.hs11
-rw-r--r--compiler/cbits/genSym.c1
4 files changed, 15 insertions, 7 deletions
diff --git a/compiler/Unique.h b/compiler/Unique.h
index a786d8ff3e..e4cd2671a1 100644
--- a/compiler/Unique.h
+++ b/compiler/Unique.h
@@ -1,3 +1,5 @@
-#include "../includes/MachDeps.h"
-
-#define UNIQUE_BITS (WORD_SIZE_IN_BITS - 8)
+/* unique has the following structure:
+ * HsInt unique =
+ * (unique_tag << (sizeof (HsInt) - UNIQUE_TAG_BITS)) | unique_number
+ */
+#define UNIQUE_TAG_BITS 8
diff --git a/compiler/basicTypes/UniqSupply.hs b/compiler/basicTypes/UniqSupply.hs
index 431c96cf58..da1a924736 100644
--- a/compiler/basicTypes/UniqSupply.hs
+++ b/compiler/basicTypes/UniqSupply.hs
@@ -77,7 +77,7 @@ takeUniqFromSupply :: UniqSupply -> (Unique, UniqSupply)
-- ^ Obtain the 'Unique' from this particular 'UniqSupply', and a new supply
mkSplitUniqSupply c
- = case ord c `shiftL` UNIQUE_BITS of
+ = case ord c `shiftL` uNIQUE_BITS of
mask -> let
-- here comes THE MAGIC:
diff --git a/compiler/basicTypes/Unique.hs b/compiler/basicTypes/Unique.hs
index 8e0f5e6f36..a49fa80946 100644
--- a/compiler/basicTypes/Unique.hs
+++ b/compiler/basicTypes/Unique.hs
@@ -22,6 +22,7 @@ Haskell).
module Unique (
-- * Main data types
Unique, Uniquable(..),
+ uNIQUE_BITS,
-- ** Constructors, destructors and operations on 'Unique's
hasKey,
@@ -98,6 +99,10 @@ Fast comparison is everything on @Uniques@:
-- These are sometimes also referred to as \"keys\" in comments in GHC.
newtype Unique = MkUnique Int
+{-# INLINE uNIQUE_BITS #-}
+uNIQUE_BITS :: Int
+uNIQUE_BITS = finiteBitSize (0 :: Int) - UNIQUE_TAG_BITS
+
{-
Now come the functions which construct uniques from their pieces, and vice versa.
The stuff about unique *supplies* is handled further down this module.
@@ -132,7 +137,7 @@ newTagUnique u c = mkUnique c i where (_,i) = unpkUnique u
-- | How many bits are devoted to the unique index (as opposed to the class
-- character).
uniqueMask :: Int
-uniqueMask = (1 `shiftL` UNIQUE_BITS) - 1
+uniqueMask = (1 `shiftL` uNIQUE_BITS) - 1
-- pop the Char in the top 8 bits of the Unique(Supply)
@@ -146,14 +151,14 @@ mkUnique :: Char -> Int -> Unique -- Builds a unique from pieces
mkUnique c i
= MkUnique (tag .|. bits)
where
- tag = ord c `shiftL` UNIQUE_BITS
+ tag = ord c `shiftL` uNIQUE_BITS
bits = i .&. uniqueMask
unpkUnique (MkUnique u)
= let
-- as long as the Char may have its eighth bit set, we
-- really do need the logical right-shift here!
- tag = chr (u `shiftR` UNIQUE_BITS)
+ tag = chr (u `shiftR` uNIQUE_BITS)
i = u .&. uniqueMask
in
(tag, i)
diff --git a/compiler/cbits/genSym.c b/compiler/cbits/genSym.c
index 4af39408ed..6943ab15d6 100644
--- a/compiler/cbits/genSym.c
+++ b/compiler/cbits/genSym.c
@@ -5,6 +5,7 @@
static HsInt GenSymCounter = 0;
static HsInt GenSymInc = 1;
+#define UNIQUE_BITS (sizeof (HsInt) * 8 - UNIQUE_TAG_BITS)
#define UNIQUE_MASK ((1ULL << UNIQUE_BITS) - 1)
STATIC_INLINE void checkUniqueRange(HsInt u STG_UNUSED) {