freenode/#clasp - IRC Chatlog
Search
4:00:09
beach
karlosz: Wouldn't the escape analysis prevent inlining in those cases so that the infinite loop is avoided?
4:06:51
karlosz
beach: how so? the inliner inlines something like (block nil (funcall () (return nil)) fine
4:11:32
beach
In those cases, the environment of the LAMBDA can not be allocated in the parent, which is one of the criteria for inlining.
4:12:26
Bike
yeah, i thought the thing ruled that out now that the continuation is explicitly in a variable
4:13:33
beach
If the environment of the callee can not be allocated in the caller, then the callee can not be inlined.
4:14:43
beach
Conservatively, then, when the environment of the callee is captured and escapes in some way that we can not determine to be safe, then we must conclude that the environment of the callee can not be allocated in the caller.
4:15:04
Bike
karlosz: i mean that's fine, but the inliner is too conservative to notice, or ought to be
4:16:29
Bike
karlosz: functions that return like that are closures (this is another reason i added catch-instruction)
4:17:34
beach
karlosz: Sure, in this case it could be inlined. But we need to come up with criteria that work for every possible case. And if we need to be a bit conservative so that this particular case is ruled out, then that's just too bad.
4:17:52
Bike
i'm saying that i expected the inlining criteria that currently exist to rule out inlining that example even though it is obviously possible
4:18:55
karlosz
the trapper criterion that is already there doesnt care about the the function being inlined escaping, but only about subfunctions capturing its environment escaping
4:19:13
karlosz
so it amkes sense that with nly one level of nesting the trapper criterion doesnt even come into play
4:20:04
beach
Also, in this case, at some point we should include the knowledge that FUNCALL does not capture its argument in some arbitrary way.
4:20:45
Bike
it does inline closures, just as long as the closure doesn't let the environment escape
4:21:10
karlosz
yeah, otherwise it wouldnt even make sense to have a method on inline, which there clearly is
4:26:54
karlosz
it wasn't very hard to add on to the inline method on unwind and make (funcall (block nil (lambda () (if n (return nil)))) inline correctly with a branch to an illegal unwind instruction
4:28:08
karlosz
and if it doesn't introduce an illegal unwind instruction instead of the nop instruction used for the valid case
4:32:22
beach
The criterion about the environment for inlining goes like this: The environment of the callee can be allocated in the caller only if 1) The environment of the callee does not survive the invocation of the caller, and 2) There is only ever a single active invocation of the callee for each invocation of the caller.
4:34:46
beach
But we need to avoid too many special cases, in particular if they handle code that is rarely seen.
4:35:17
Bike
other than the complicated code that's supposed to keep unwinds only if needed, i guess
4:36:34
Bike
if my code works, once the function in (block nil ((lambda () (return)))) is inlined, the unwind instruction will be removed and it will be just a regular control arc
4:37:47
Bike
but for example in (block nil (foo (lambda () ((lambda () (return))))) the inner function can be inlined but there's still an unwind.
4:41:39
karlosz
yes, i think the only thing that warrants changing is the UB example. it would be nice to not infinite loop and do the right thing
4:45:28
Bike
(loop with x do (block nil (if (null x) (setf x (lambda () (return))) (funcall x)))) which is extremely artificial
4:46:27
Bike
it won't cause any memory faults or weird shit like that which is why i'm not super concerned, but it's still unfortunate
4:49:25
karlosz
Bike: i just tried it with cleavir+clisp and it gave me an out of extent return error fine
4:49:51
karlosz
but this is with the closure conversion fix so maybe that has something to do with it
4:51:02
Bike
the idea is that it hits the catch instruction, sets x, then exits the block scope to the top of the loop, then hits the catch instruction which again sets the continuation to something valid
5:04:05
karlosz
well here's one issue: i think its written somewhere that the output of enclose is never assigned to by anthing else
5:13:43
karlosz
there should be a sentence like the output of an enclose instruction is never assigned to by construction
5:15:51
karlosz
::notify Bike i see the problem in your example. yes, if you always insert cells at the top of the procedure, you are going to run into the issue. if you insert the cell inside the loop using the closure fix i wrote with dominators it works correctly
5:31:43
karlosz
::notify Bike: putting create cells at the top of the procedure essentially means that the lambdas all share the same block tag cell which keeps getting updated as the loop goes on, exactly the same problem as the (loop i ->5 collect (let ((x i)) (lambda () x)))) example
13:06:16
Colleen
Bike: karlosz said 7 hours, 50 minutes ago: i see the problem in your example. yes, if you always insert cells at the top of the procedure, you are going to run into the issue. if you insert the cell inside the loop using the closure fix i wrote with dominators it works correctly
13:59:47
beach
Bike: Suppose we had a graph where the nodes are 1) functions (as represented either by an ENTER-INSTRUCTION, by the name of a global function, or UNKNOWN) and 2) call sites (as represented by CALL-INSTRUCTIONS.
13:59:48
beach
The arcs would be 1) PARENT (between two functions represented by ENTER-INSTRUCTION), 2) MAY CALL (from call sites to functions), 3) MAY BE CALLED BY from functions to call sites, 4) MAY BE THE NTH ARGUMENT OF (from functions to call sites), and 5) may be returned as the nth value of (from functions to call sites)
14:02:48
beach
Also general escape (argument of an unknown function or of a function known to hold on to its argument, or return value of a top-level function).
14:15:59
drmeister
I want to add a quicklisp: hostname for logical pathnames because cando depends on quicklisp.
14:16:28
drmeister
First shot - I'll have a CLASP_QUICKLISP environment variable, then /opt/clasp/lib/quicklisp then ~/quicklisp ?
14:16:56
drmeister
Clasp will set the quicklisp hostname by checking those things in that order - how does that sound?
14:18:13
drmeister
Why /opt/clasp/lib/quicklisp - because we are trying to collect all of jupyterlab and quicklisp that cando needs to run into one directory tree.
14:18:29
drmeister
Then we can create a tarball of that tree and drop it into a minimal docker image.
14:19:39
drmeister
Our current docker problems are largely caused by poor version hygiene when building the docker image. We are attempting to clean this up.
14:20:19
drmeister
Shinmera: waf 2.0.7 supports Python3.7 and waf 2.0.6 (which we currently have) does not. I'll upgrade to 2.0.7 today.
14:20:43
karlosz
Shinmera: its because Python3.7 made a breaking change with respect to generators, raising a runtime exception when there was none before
14:23:42
beach
GAH, I have a strange problem. I get things like: caught ERROR: ; (during EVAL of LOAD-TIME-VALUE); The variable #:G402562 is unbound.
14:24:34
beach
It is happening when I try to compile a very simple DEFMACRO that uses a &KEY parameter.
14:44:24
drmeister
Ok - we've been improving argument handling in clasp - just making sure the world has not turned upside down and you are doing anything with clasp.
14:47:06
Bike
i'm just wondering what's dealing with the lambda list. with macrolet it would definitely be cleavir. with defmacro it depends on the definition of defmacro.
14:47:48
beach
It am pretty sure that it is something that I accidentally made the host do as opposed to Cleavir.
14:53:23
Bike
no, i can get going on that in a minute. wanted to finish something else up but it'll take time
15:15:12
drmeister
Because if it's about computers - I'll join in with you for a good 'ole "two minutes hate".
15:16:11
beach
This happened when I tried to trace all the functions in the cst-to-ast package and then translate a very simple expression.
15:16:53
karlosz
well, this is asmusing. inlining out of extent returns causes them to act like scheme's indefinite extent returns introduced by call/cc
15:17:53
karlosz
and it makes sense too, if we ignore what is out of extent or not we get a valid continuation anywhere in the function body, just like scheme
15:19:17
karlosz
so when partial inlining and hitting unwind it will inline the function by unwinding
15:21:06
karlosz
right, we want to throw an error on UB behavior - but it is still amsuing that it does what scheme would do with call/ccc