Skip to content

Instantly share code, notes, and snippets.

@aviatesk
Last active May 24, 2024 10:01
Show Gist options
  • Save aviatesk/e6349fabf690a37f63a166cacb9b9674 to your computer and use it in GitHub Desktop.
Save aviatesk/e6349fabf690a37f63a166cacb9b9674 to your computer and use it in GitHub Desktop.
Using irinterp to replace `sin(::Float64)` to `cos(::Float64)` with inlining it.
using Test
Base.setindex!(inst::CC.Instruction, args...) = CC.setindex!(inst, args...)
function topfunc(x)
return sin(x)
end
ir = first(only(Base.code_ircode(topfunc, (Float64,))))
ir.stmts[1][:info] = CC.NoCallInfo()
ir.stmts[1][:inst] = Expr(:call, GlobalRef(Base.Math, :cos), Core.Argument(2))
ir.stmts[1][:flag] |= CC.IR_FLAG_REFINED
interp = CC.NativeInterpreter()
mi = only(methods(topfunc, (Float64,))).specializations
method_info = CC.MethodInfo(false, nothing)
world = Base.get_world_counter()
min_world = Base.get_world_counter()
max_world = typemax(UInt64)
irsv = CC.IRInterpretationState(interp, method_info, ir, mi, Any[Core.Const(topfunc), Float64], world, min_world, max_world);
CC.ir_abstract_constant_propagation(interp, irsv)
@test irsv.ir.stmts[1][:info] != CC.NoCallInfo() # => now this statement has a call info for `cos(::Float64)`
irsv.ir.stmts[1][:flag] |= CC.IR_FLAG_INLINE # force inlining for this statement
inlining = CC.InliningState(interp)
ir = CC.ssa_inlining_pass!(irsv.ir, inlining, false)
ir.argtypes[1] = Tuple{}
oc = Core.OpaqueClosure(ir)
@test oc(42.0) == cos(42.0)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment