Manual type inference of hand-written IRCode

@jameson has answered:
Probably not really, since the question is underspecified once you have an IRCode stripped of its MethodInstance. The MethodInstance is needed to provide context to inference

@aviatesk has answered:
It’s very hacky and not recommended, but you can do something like:

julia> function foo(x,y)
         z = x * y
         z + sin(x)
       end;

julia> ir, = only(Base.code_ircode(foo, (Float64,Float64,)));

julia> ir.stmts.type .= Any;

julia> ir
2 1 ─ %1 = Base.mul_float(_2, _3)::Any                                │╻ *
3 │   %2 = invoke Main.sin(_2::Float64)::Any                          │ 
  │   %3 = Base.add_float(%1, %2)::Any                                │╻ +
  └──      return %3                                                  │ 
                                                                        

julia> interp = Core.Compiler.NativeInterpreter();

julia> world = Core.Compiler.get_world_counter(interp);

julia> mi = only(methods(foo)).specializations;

julia> argtypes = Any[Core.Const(foo), Float64, Float64];

julia> src = first(@code_typed foo(1.0, 2.0));

julia> method_info = Core.Compiler.MethodInfo(src);

julia> irsv = Core.Compiler.IRInterpretationState(interp, method_info, ir, mi, argtypes, world, src.min_world, src.max_world);

julia> irsv.argtypes_refined .|= true; # force reinference

julia> Core.Compiler.ir_abstract_constant_propagation(interp, irsv);

julia> irsv.ir
2 1 ─ %1 = Base.mul_float(_2, _3)::Float64                            │╻ *
3 │   %2 = invoke Main.sin(_2::Float64)::Float64                      │ 
  │   %3 = Base.add_float(%1, %2)::Float64                            │╻ +
  └──      return %3                                                  │
1 Like