Of course, in a purely linear function body like g
, the usage of return
is pointless since the expression x + y
is never evaluated and we could simply make x * y
the last expression in the function and omit the return
. In conjunction with other control flow, however, return
is of real use.
- Who determines whether a part of code will be evaluated, conditional
if
or return
?
@code_llvm hypot(0,0)
julia> @code_llvm hypot(0,0)
; Function Signature: hypot(Int64, Int64)
; @ REPL[1]:1 within `hypot`
define { ptr, i8 } @julia_hypot_924(ptr noalias nocapture noundef nonnull align 8 dereferenceable(8) %union_bytes_return, i64 signext %"x::Int64", i64 signext %"y::Int64") #0 {
top:
; @ REPL[1]:2 within `hypot`
; β @ int.jl:188 within `abs`
; ββ @ int.jl:142 within `flipsign`
%0 = call i64 @llvm.abs.i64(i64 %"x::Int64", i1 false)
; ββ
; @ REPL[1]:3 within `hypot`
; β @ int.jl:188 within `abs`
; ββ @ int.jl:142 within `flipsign`
%1 = call i64 @llvm.abs.i64(i64 %"y::Int64", i1 false)
; ββ
; @ REPL[1]:4 within `hypot`
; β @ operators.jl:379 within `>`
; ββ @ int.jl:83 within `<`
%.not = icmp slt i64 %1, %0
; ββ
br i1 %.not, label %L14, label %L19
L14: ; preds = %top
; @ REPL[1]:5 within `hypot`
; β @ int.jl:97 within `/`
; ββ @ float.jl:374 within `float`
; βββ @ float.jl:348 within `AbstractFloat`
; ββββ @ float.jl:239 within `Float64`
%2 = sitofp i64 %1 to double
%3 = sitofp i64 %0 to double
; ββββ
; β @ int.jl:97 within `/` @ float.jl:494
%4 = fdiv double %2, %3
; β
; @ REPL[1]:6 within `hypot`
; β @ float.jl:493 within `*`
%5 = fmul double %4, %4
; β
; β @ promotion.jl:429 within `+` @ float.jl:491
%6 = fadd double %5, 1.000000e+00
; β
; β @ math.jl:609 within `sqrt`
%7 = call double @llvm.sqrt.f64(double %6)
; β
; β @ promotion.jl:430 within `*` @ float.jl:493
%8 = fmul double %7, %3
; β
store double %8, ptr %union_bytes_return, align 8
br label %common.ret
L19: ; preds = %top
; @ REPL[1]:8 within `hypot`
; β @ promotion.jl:639 within `==`
%.not23 = icmp eq i64 %"y::Int64", 0
; β
br i1 %.not23, label %common.ret, label %L31
common.ret: ; preds = %L31, %L19, %L14
%common.ret.op = phi { ptr, i8 } [ { ptr null, i8 1 }, %L14 ], [ { ptr null, i8 1 }, %L31 ], [ { ptr @"jl_global#939.jit", i8 -126 }, %L19 ]
; @ REPL[1] within `hypot`
ret { ptr, i8 } %common.ret.op
L31: ; preds = %L19
; @ REPL[1]:11 within `hypot`
; β @ int.jl:97 within `/`
; ββ @ float.jl:374 within `float`
; βββ @ float.jl:348 within `AbstractFloat`
; ββββ @ float.jl:239 within `Float64`
%9 = sitofp i64 %0 to double
%10 = sitofp i64 %1 to double
; ββββ
; β @ int.jl:97 within `/` @ float.jl:494
%11 = fdiv double %9, %10
; β
; @ REPL[1]:12 within `hypot`
; β @ float.jl:493 within `*`
%12 = fmul double %11, %11
; β
; β @ promotion.jl:429 within `+` @ float.jl:491
%13 = fadd double %12, 1.000000e+00
; β
; β @ math.jl:609 within `sqrt`
%14 = call double @llvm.sqrt.f64(double %13)
; β
; β @ promotion.jl:430 within `*` @ float.jl:493
%15 = fmul double %14, %10
; β
store double %15, ptr %union_bytes_return, align 8
br label %common.ret
}
contains sqrt()
part while for following g(x,y) function
julia> function g(x, y)
return x * y
x + y
end
@code_llvm g(2,3)
julia> @code_llvm g(2,3)
; Function Signature: g(Int64, Int64)
; @ REPL[5]:1 within `g`
define i64 @julia_g_1024(i64 signext %"x::Int64", i64 signext %"y::Int64") #0 {
top:
; @ REPL[5]:2 within `g`
; β @ int.jl:88 within `*`
%0 = mul i64 %"y::Int64", %"x::Int64"
; β
ret i64 %0
}
donβt have x+y
part.