Compiler Explorer: a Rosetta Stone for Compilers

in programming •  6 years ago 

godbolt.org is a tool for exploring compiler behavior and output. It offers the ability to compile C++ and other languages with a variety of different compiler versions and machine targets, and view the resulting assembly code.

As an example, here's some code to calculate the Fibonacci numbers using tail-recursion:

and here's the resulting x64 assembly output, compiled with gcc version 8.1. using the -O1 flag:

Each line of source is color-coded to match the corresponding assembly instructions (though this mapping is not always as straightforward as one would like.) The Compiler Explorer provides help interpreting the assembly: you can hover over an instruction to get a quick summary:

What happens if we switch to a higher optimization level, and use -O2 instead?

Now the compiler has successfully implemented tail recursion. Instead of the assembly "call fibIter" to recursively call the function, the compiler has reduced fibIter to a loop. This is a great way to try out "will the compiler perform optimization X?" or try toggling individual optimizations using compiler flags.

What about -O3?

Now we have a mess. The compiler applied a lot of different optimizations that caused the code to become enormously more complex. It inlined fibIter into the fib function. It not only converted the tail recursion to a loop, but also unrolled that loop and parallelized it using SIMD instructions, to do two multiplications at once.

We can easily compare with a different architecture, like ARM, that doesn't have SIMD instructions:

You can also explore different versions of the same compiler/architecture combo to see if the output differs.

Compiler Explorer supports assembly, C, C++, CUDA, D, Go, Haskell, LLVM's intermediate representation (a psuedo-assembly language), Pascal, Rust, and Swift. Its source is online at Github (https://github.com/mattgodbolt/compiler-explorer) and its author, Matt Godbolt, has a Patreon: https://www.patreon.com/mattgodbolt

Authors get paid when people like you upvote their post.
If you enjoyed what you read here, create your account today and start earning FREE STEEM!
Sort Order:  

The Haskell compiler is smart enough to turn tail recursion into a loop, too, although it is less easy to see what's going on:

factIter :: Int -> Int -> Int
factIter 0 x = x
factIter n x = factIter (n-1) (n * x)

The core of the function is these lines of assembly code:

Example_$wfactIter_info:
.Lc2gC:
  testq %r14,%r14
  je .Lc2gI
  movq %r14,%rax
  imulq %rsi,%rax
  decq %r14
  movq %rax,%rsi
  jmp .Lc2gC
.Lc2gI:
  movq %rsi,%rbx
  jmp *(%rbp)

The variable n appears in %r14, and the variable x in %rsi, I think. (Stupid AT&T syntax.)

Congratulations @markgritter! You have completed the following achievement on Steemit and have been rewarded with new badge(s) :

Award for the number of upvotes

Click on the badge to view your Board of Honor.
If you no longer want to receive notifications, reply to this comment with the word STOP

To support your work, I also upvoted your post!

Do not miss the last post from @steemitboard:
SteemitBoard World Cup Contest - Brazil vs Belgium


Participate in the SteemitBoard World Cup Contest!
Collect World Cup badges and win free SBD
Support the Gold Sponsors of the contest: @good-karma and @lukestokes


Do you like SteemitBoard's project? Then Vote for its witness and get one more award!