grin-compiler / grin

GRIN is a compiler back-end for lazy and strict functional languages with whole program optimization support.

Home Page:https://grin-compiler.github.io/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

InlineApply causes non-defined function when self recursive

Z-snails opened this issue · comments

When the function apply includes a call to itself, InlineApply inlines the apply function, and replaces the occurance of it with apply.0, however this function doesn't exist.

test.grin

 apply fnp argp =
    fn <- fetch fnp
    case fn of
        (P1MyFun) ->
            x <- store (CNull)
            apply argp fnp
        (P1OtherFun) ->
            pure (CNull)

grinMain =
    fn1 <- store (P1MyFun)
    arg1 <- store (P1OtherFun)
    apply fn1 arg1

grin --optimize test.grin

.output/002.InlineApply.grin



grinMain =
  fn1 <- store (P1MyFun)
  arg1 <- store (P1OtherFun)
  do
    fnp.0 <- pure fn1
    argp.0 <- pure arg1
    fn.0 <- fetch fnp.0
    case fn.0 of
      (P1MyFun) ->
        x.0 <- store (CNull)
        apply.0 $ argp.0 fnp.0 -- Problem is here
      (P1OtherFun) ->
        pure (CNull)

This is a handwritten example, but I encountered this problem when compiling a simple program with my idris2 grin backend, as inlining of other functions caused apply to be self recursive.

I can think of 2 solutions:

  1. don't inline apply if it's self recursive - this could reduce effectiveness of other optimisations
  2. keep the definition of apply around after inling.

I don't know the grin codebase very well, but I'll have a go at fixing this. I really don't know the codebase or recursion schemes, so I can't fix it (at least not without learning recursion schemes first).

Actually, the grin optimiser inlines apply and eval before anything else, so this isn't really an issue. I just need to turn off the inlining optimisation in my idris2 grin backend (or inline apply and eval first).