27

I'm currently writing a multi-module program in Haskell. I've found a strange problem where my files aren't being optimized properly, even though I'm passing in -O2 and so on. The files in question are shared 3D vector maths modules. When compiled individually to a .o, these modules are optimized correctly. When compiled as part of a larger program using --make, they are not optimized correctly. The core is quite different.

I've put in some simple stripped-down test code into a vector.hs file:

data TestVector = TestVector !Double !Double !Double !Double

addVec :: TestVector -> TestVector -> TestVector

addVec (TestVector x1 y1 z1 w1) (TestVector x2 y2 z2 w2) =
  TestVector (x1 + x2) (y1 + y2) (z1 + z2) (w1 + w2)

And imported it from main...

import Vector

This code gets compiled differently as a standalone .hs file as opposed to when I build main.hs using --make

My command line is:

ghc -tmpdir tmp -hidir hi -odir obj -fext-core -fexcess-precision -funbox-strict-fields -threaded -rtsopts -fwarn-missing-signatures -Wall -O2 Main.hs -o main

Cheers

Upendra Chaudhari
  • 6,473
  • 5
  • 25
  • 42
Tom Hammersley
  • 279
  • 2
  • 8
  • 2
    If I'm understanding correctly, you are comparing the output of two different invocations of GHC. If that's right, you should include the command line of the other invocation of GHC that you're comparing to. – Daniel Wagner Sep 09 '11 at 20:48
  • 1
    Do you get the same code if you put `{-# INLINE addVec #-}` on your code? Or if you use `{-# UNPACK #-}` on the fields of your vector? GHC might not inline across module boundaries in some circumstances. – Don Stewart Sep 09 '11 at 21:02
  • Just to explain a little more. I use the same ghc command line options to compile both. So, I'll invoke GHC with the same options to compile main.hs, which compiles vector.hs indirectly, but I also use the same command line to compile vector.hs directly. I get different results. I'll update the main question to include the core output. – Tom Hammersley Sep 10 '11 at 09:11
  • Are you using `cabal`? If not, I assume you have a good reason not to, but maybe you should try using a cabal file, and then run cabal in some kind of verbose mode. If it does what you expect, then it must be calling ghc in a different way than you are. Then of course you can just copy what cabal is doing. – Tyler Sep 23 '11 at 00:35
  • 2
    How do you actually know that it is optimized differently? Are you viewing the core file, comparing performance, or have you enabled some ```-ddump``` options? – Joachim Breitner Sep 23 '11 at 20:33
  • 4
    I tried to reproduce this, and compiled Vecor.hs twice, once with --make applied to Main.hs, and once directly. Then I compared the output of ```objdump -S -w -C -d Vector.o```, and only some identifiers differ, the byte code is the same. The ```.hi``` files are actually identical. I guess you need to clarify further how to reproduce your effect. – Joachim Breitner Sep 27 '11 at 14:54

1 Answers1

1

Add

{-# INLINE addVec #-}

in main module.

GHC needs indication of that possibility before doing that optimization, if the invokator/invokated are not in the same modules.

robermorales
  • 3,293
  • 2
  • 27
  • 36