You can also use @code_native to look at the assembly code of any function, @code_lowered/@code_typed to see the Julia IR (which you can also modify before fully compiling, which is how source-to-source differentiation with Zygote works) and @code_warntype to evaluate the type inference result. This is a nice diagram of Julia's multi-stage compilation:
"
julia> a = function (x); x += 1; x += 1; return x; end
#13 (generic function with 1 method)
julia> @code_llvm a(3)
; @ none:1 within `#13'
define i64 @"julia_#13_17607"(i64) {
top:
; ┌ @ int.jl:53 within `+'
; └ }"Prior to reading this article, I did not know that Julia could compile LLVM at the function level... very cool!