4

A common practice in the C world to compare two fragmets of C is to see what assembly they generate. I wanted to know what code GHC would generate in the case of:

afmap :: Functor f => (a -> b -> c) -> f b -> a -> f c
afmap fn fb a' = (fn a') <$> fb

and

afmap  = flip . (((.).(.)) fmap ($))

So I tried:

$ ghc -S test.hs -o test.S

Which (unsurprisingly) yielded more or less unreadable code.

What is the correct way (if any) to evaluate how ghc optimizes code?

fakedrake
  • 6,528
  • 8
  • 41
  • 64

1 Answers1

4

Assembly is probably a bit too low-level. You probably want to look at Core, GHC's intermediate optimisation language.

Essentially, GHC translates Haskell to Core, does a wide variety of optimisation passes on it, and eventually transforms Core to STG and then on to C-- and the native code generator (i.e., assembly) or via LLVM (I don't know much about that particular pathway).

In particular, Core is still reasonably high-level, and somewhat similar to Haskell (i.e., it has similar abstractions like pattern-matching and lazy evaluation). If two programs produce the same Core, then obviously they produce the same machine code.

MathematicalOrchid
  • 61,854
  • 19
  • 123
  • 220
  • That is correct and helpful. A side note for future reference: one needs to add the line `module Test (afmap) where` at the top of the input file to have `ghc` actually compile the function. – fakedrake Jun 20 '16 at 08:16