How to force compile-time evaluation of literal calculations?

I often want to write large integer values such as 10^6 in performance critical functions. I would expect Julia to perform these calculations at compile-time when possible, but it doesn’t appear to do so:

julia> function f(x)
         x + 10^6
       end
f (generic function with 1 method)

julia> @code_llvm f(1)
;  @ REPL[24]:1 within `f'
define i64 @julia_f_346(i64 signext %0) {
top:
;  @ REPL[24]:2 within `f'
; ┌ @ none within `literal_pow'
; │┌ @ none within `macro expansion'
; ││┌ @ intfuncs.jl:289 within `^'
     %1 = call i64 @j_power_by_squaring_348(i64 signext 10, i64 signext 6)
; └└└
; ┌ @ int.jl:87 within `+'
   %2 = add i64 %1, %0
; └
  ret i64 %2
}
1 Like

Not sure what kinds of calculations you’re dealing with, but would it not suffice to set the literal as a constant?

const A = 10^6
function f(x)
    x + A
end
@code_llvm f(1)

Yes, defining a const would work, but makes my code more confusing than typing out 1_000_000 or 1_000_000_000 wherever I need it.

I guess I was hoping for something a bit cleaner like CT(10^6). Or even ideally just force evaluate all literals at compile-time. I don’t want to need to remember that 10^4 is optimized to 10000, but 10^6 is not.

1 Like

This seems to work (tested on Julia 1.6):

julia> f(x) = x + Int(1e6)
f (generic function with 1 method)

julia> @code_llvm f(1)
;  @ REPL[18]:1 within `f'
define i64 @julia_f_277(i64 signext %0) {
top:
; ┌ @ int.jl:87 within `+'
   %1 = add i64 %0, 1000000
; └
  ret i64 %1
}
3 Likes

I am not sure if I can suggest this, but this most simple macro ever seems to work:

julia> macro CT(expr)
         eval(expr)
       end
@CT (macro with 1 method)

julia> f(x) = x + @CT(10^6)
f (generic function with 1 method)

julia> @code_llvm f(1)

;  @ REPL[32]:1 within `f'
define i64 @julia_f_902(i64) {
top:
; ┌ @ int.jl:86 within `+'
   %1 = add i64 %0, 1000000
; └
  ret i64 %1
}


In principle it can be use to make any function call with constant arguments constant, like

julia> f(x) = x + @CT(sin(π/4) + sqrt(10) + 10^6)
1 Like