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,057
  • 7
  • 37
  • 55

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
  • 60,742
  • 18
  • 121
  • 216
  • 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