juliallvm

Detecting CPU capabilities at compile time and "dispatching" on them


Is it possible to write a function which would use different algorithms depending on Julia/LLVM compile target?

The goal is to do this at compile-time, and hopefully to make this function inline-able.

Just to have some code, this could look like:

function do_it()
    if (CPU_has_avx512) # resolved at compile. code for one branch generated
        ...
    else
        ...
    end
end

Solution

  • You can create the following macro:

    using CpuId
    macro cpuf(what)
        quote
            $(CpuId.cpufeature(what.value))
        end
    end
    

    This obviously replaces a call with a fixed value at compile time:

    julia> @macroexpand @cpuf(:AVX)
    quote
        #= REPL[75]:3 =#
        true
    end
    

    So now we can dispatch on the Val type:

    f1(::Val{true}) = 100
    f1(::Val{false}) = -100
    
    julia> f1(Val{@cpuf(:AVX)}())
    100
    

    And this all gets compiled-in as you wanted:

    julia> @code_llvm f1(Val{@cpuf(:AVX)}())
    ;  @ REPL[89]:1 within `f1`
    ; Function Attrs: uwtable
    define i64 @julia_f1_935() #0 {
    top:
      ret i64 100
    }