summaryrefslogtreecommitdiff
path: root/compiler/cmm/CmmPipeline.hs
diff options
context:
space:
mode:
authorSimon Marlow <marlowsd@gmail.com>2012-10-24 12:03:34 +0100
committerSimon Marlow <marlowsd@gmail.com>2012-10-24 12:03:34 +0100
commit65fec07bfbf41846689e0b28bc94b168c8cacc84 (patch)
tree7d6506ef410e6fd6b0d0d8f8cf5da4df23534fa9 /compiler/cmm/CmmPipeline.hs
parent09209de417b16cf9a06d655dbe7415ba9eea757d (diff)
downloadhaskell-65fec07bfbf41846689e0b28bc94b168c8cacc84.tar.gz
Comment to explain why we need to split proc points on x86/Darwin with -fPIC
Diffstat (limited to 'compiler/cmm/CmmPipeline.hs')
-rw-r--r--compiler/cmm/CmmPipeline.hs32
1 files changed, 31 insertions, 1 deletions
diff --git a/compiler/cmm/CmmPipeline.hs b/compiler/cmm/CmmPipeline.hs
index c523b137e0..aa8fa2c1f5 100644
--- a/compiler/cmm/CmmPipeline.hs
+++ b/compiler/cmm/CmmPipeline.hs
@@ -179,11 +179,41 @@ cpsTop hsc_env proc =
-- the entry point.
splitting_proc_points = hscTarget dflags /= HscAsm
|| not (tablesNextToCode dflags)
- || usingDarwinX86Pic
+ || usingDarwinX86Pic -- Note [darwin-x86-pic]
usingDarwinX86Pic = platformArch platform == ArchX86
&& platformOS platform == OSDarwin
&& gopt Opt_PIC dflags
+{- Note [darwin-x86-pic]
+
+On x86/Darwin, PIC is implemented by inserting a sequence like
+
+ call 1f
+ 1: popl %reg
+
+at the proc entry point, and then referring to labels as offsets from
+%reg. If we don't split proc points, then we could have many entry
+points in a proc that would need this sequence, and each entry point
+would then get a different value for %reg. If there are any join
+points, then at the join point we don't have a consistent value for
+%reg, so we don't know how to refer to labels.
+
+Hence, on x86/Darwin, we have to split proc points, and then each proc
+point will get its own PIC initialisation sequence.
+
+This isn't an issue on x86/ELF, where the sequence is
+
+ call 1f
+ 1: popl %reg
+ addl $_GLOBAL_OFFSET_TABLE_+(.-1b), %reg
+
+so %reg always has a consistent value: the address of
+_GLOBAL_OFFSET_TABLE_, regardless of which entry point we arrived via.
+
+-}
+
+
+
runUniqSM :: UniqSM a -> IO a
runUniqSM m = do
us <- mkSplitUniqSupply 'u'