clasp icon indicating copy to clipboard operation
clasp copied to clipboard

Do not interpolate at IR level

Open Bike opened this issue 2 years ago • 4 comments

Function interpolation in BIR is closely related to several bugs, such as #1402, #1401, #1365, #1330 maybe, #1326 maybe, #1266 maybe, #1264, #1260, probably more. It's inherently a complex mutation of the IR and thus bug-prone.

I think we can avoid ever interpolating by taking local calls more seriously. Specifically,

  1. Cleavir should understand a local call as deeply as it understands other control flow. For example, say we have (lambda (x) (print (1+ x)) (* 2 x)), and that both of its call sites pass it a double and ignore its result. Then we must be able to optimize the addition to be an unboxed floating point addition, and to delete the unused call to * entirely.
  2. The code generator (i.e. translate+LLVM) should never translate a unique call to a local function as an actual call: as far as LLVM is concerned it ought to be the same as if we had interpolated.

Assuming we can get two conditions in place, I don't think interpolating has any benefit.

Bike avatar Mar 30 '23 17:03 Bike

SBCL does both of these points in the way it represents local calls in the graph by the way. We should just copy exactly what the IR there does because I think it's the Right Thing. After I changed the contification in sbcl to be as powerful as the one in cleavir it's strictly better now.

karlosz avatar Apr 02 '23 16:04 karlosz

I've been working towards this again. A few more points.

The major blocking issue is, ridiculously enough, debug information. LLVM is pretty strict and will not accept, for example, different instructions in the same function having different functions in their source info, unless the inlinedAt markers are set properly. We have some mechanisms for fixing that up already, but it's pretty ugly. I was hoping to resolve that by letting LLVM do procedure integration instead of us doing it. I have got that working (in redebug branch), but it's not perfect: first off I don't think LLVM does anything like contification, and secondly it doesn't know how to optimize our nonlocal exits into local jumps. (I'm considering writing that as an LLVM pass, but it's a long way off at best.)

Therefore I'm coming back around to thinking we should contify ourselves. I'm hoping I can still avoid these problems by only actually doing the procedural integration very late (after meta evaluation). And I suppose I should check out what SBCL is doing.

ETA: Also I could set it up so that Cleavir contifies just by merging local calls in the same position. That gives a question of what to do with the source info, but it might be interesting also for letting mv-calls and non-mv-calls be merged (into mv-calls).

Bike avatar May 17 '24 19:05 Bike

SBCL calls contification assignment conversion.

karlosz avatar May 17 '24 19:05 karlosz

righto. I see the A_call entirely in that when condition.

I think what I will do is come up with a BIR cloner, and then use that for interpolation instead of modifying the inlinee's IR, which will hopefully be a little less error-prone. Then in the course of making that copy I can fix up the source info. A cloner would be good anyway for various reasons, e.g. if we wanted to allow inlining a function in multiple places (at IR level, since currently we do that with AST cloning, but that doesn't help with local functions anyway).

Bike avatar May 17 '24 21:05 Bike