2015-02-08T00:58:23Z scymtym_ quit (Ping timeout: 264 seconds) 2015-02-08T01:48:27Z zRecursive joined #sbcl 2015-02-08T02:23:33Z adlai quit (Ping timeout: 250 seconds) 2015-02-08T02:23:57Z adlai joined #sbcl 2015-02-08T02:56:29Z stassats` quit (Ping timeout: 245 seconds) 2015-02-08T02:56:55Z stassats quit (Ping timeout: 250 seconds) 2015-02-08T03:08:22Z ASau quit (Remote host closed the connection) 2015-02-08T03:11:32Z ASau joined #sbcl 2015-02-08T03:38:34Z christoph_debian quit (Ping timeout: 245 seconds) 2015-02-08T03:51:56Z christoph_debian joined #sbcl 2015-02-08T04:17:57Z adlai quit (Ping timeout: 250 seconds) 2015-02-08T04:23:32Z nyef quit (Quit: G'night all) 2015-02-08T04:31:14Z adlai joined #sbcl 2015-02-08T04:57:30Z |3b|: hmm, "The value # is not of type ARRAY." 2015-02-08T04:57:47Z |3b| wonders if i did something wrong or if windows sbcl doesn't like static-vectors 2015-02-08T05:09:07Z pkhuong_: |3b|: 32/64 bitness? 2015-02-08T05:09:07Z pkhuong_ is now known as pkhuong 2015-02-08T05:09:07Z |3b|: 64 2015-02-08T05:09:16Z pkhuong: and the same code works on 64 bit linux? 2015-02-08T05:09:23Z |3b| supposed it could also be related to whatever broke timers/timeouts on my build 2015-02-08T05:09:28Z |3b|: no clue, just wrote it :p 2015-02-08T05:10:33Z |3b|: (and just rewrote it to use cffi foreign memory instead, can try making a test case if you think it sounds worth investigating though) 2015-02-08T05:11:09Z pkhuong: that value seems pretty low in memory 2015-02-08T05:11:18Z Krystof quit (Ping timeout: 244 seconds) 2015-02-08T05:11:22Z |3b|: true 2015-02-08T05:17:50Z selat joined #sbcl 2015-02-08T05:18:55Z |3b|: apparently it is trying to print an out of bound error when it gets that error, and axis is an invalid object as well 2015-02-08T05:19:41Z |3b|: ah, i guess axis is optional and not provided 2015-02-08T05:23:13Z pkhuong: I don't see why anything but the underlying simple array is foreign allocated 2015-02-08T05:24:48Z |3b|: in static-vectors you mean? 2015-02-08T05:25:39Z pkhuong: yes 2015-02-08T05:28:08Z |3b|: well, at least the error it tried to signal was correct, works better if i index the array by the index instead of the bounds :p 2015-02-08T05:34:12Z |3b|: possibly related to the error, might have a reduced test case 2015-02-08T05:37:31Z |3b|: http://paste.lisp.org/+34FA 2015-02-08T05:41:13Z |3b|: same thing in 1.2.1 from official windows binary, so doesn't seem to be local problem 2015-02-08T05:42:22Z |3b|: and on 1.2.7.70 x8664 linux 2015-02-08T05:43:14Z pkhuong: I don't have static vectors 2015-02-08T05:44:12Z |3b|: normal array gives a proper error for same thing, so i'm willing to blame simple-vectors 2015-02-08T05:44:16Z |3b|: static-vectors i mean 2015-02-08T05:45:57Z |3b|: is it likely to be related to your comment about allocating more than the underlying simple array as foreign? (for example something in sbcl checking for it being on the heap) 2015-02-08T05:48:03Z pkhuong: not if they did it right 2015-02-08T05:48:43Z pkhuong: but the more you do the more you risk getting wrong. 2015-02-08T05:49:01Z pkhuong: the data vector is pretty straightforward. everything else, not so much 2015-02-08T05:49:46Z pkhuong: however, from the error and the code, I'd guess that static vector got the widetag wrong for x86-64 2015-02-08T05:58:25Z |3b|: any easy way to check that? 2015-02-08T05:59:12Z pkhuong: nope, widetag is correct 2015-02-08T06:01:39Z LiamH quit (Quit: Leaving.) 2015-02-08T06:02:15Z |3b|: declaring AREF notinline gives proper error 2015-02-08T06:02:31Z |3b|: oops, nevermind... wrong test 2015-02-08T06:03:02Z |3b|: ok, notinline affects correct test as well 2015-02-08T06:05:43Z zRecursive left #sbcl 2015-02-08T06:06:08Z pkhuong: I know what's going on. 2015-02-08T06:06:25Z pkhuong: debugger code works harder not to create bad objects outside the heap 2015-02-08T06:06:56Z pkhuong: you get an opaque wrapper when it reaches in the interrupt context and sees that the expected lisp pointer isn't 2015-02-08T06:10:06Z oleo is now known as Guest27093 2015-02-08T06:10:59Z oleo__ joined #sbcl 2015-02-08T06:13:31Z Guest27093 quit (Ping timeout: 250 seconds) 2015-02-08T06:25:16Z |3b|: pkhuong: if it were just the debugger, wouldn't it be giving the correct error, but with invalid-object? looks like something decides it is invalid while trying to signal the invalid index error 2015-02-08T06:28:53Z |3b|: and actually debugger seems to print contents just fine if i pass it to another function and interrupt it 2015-02-08T06:29:29Z |3b| can't get the binding to show up as a local in the function that created it though 2015-02-08T06:51:11Z pacon quit (Read error: Connection reset by peer) 2015-02-08T07:34:29Z psy_ joined #sbcl 2015-02-08T07:49:01Z Shinmera joined #sbcl 2015-02-08T07:57:43Z Krystof joined #sbcl 2015-02-08T07:57:43Z ChanServ has set mode +o Krystof 2015-02-08T08:24:11Z specbot quit (Remote host closed the connection) 2015-02-08T08:24:11Z minion quit (Remote host closed the connection) 2015-02-08T08:32:11Z minion joined #sbcl 2015-02-08T08:32:50Z specbot joined #sbcl 2015-02-08T08:33:03Z specbot quit (Remote host closed the connection) 2015-02-08T08:33:03Z minion quit (Remote host closed the connection) 2015-02-08T08:39:32Z psy_ quit (Remote host closed the connection) 2015-02-08T08:42:16Z psy_ joined #sbcl 2015-02-08T08:53:41Z Xof joined #sbcl 2015-02-08T08:53:41Z ChanServ has set mode +o Xof 2015-02-08T08:59:41Z scymtym_ joined #sbcl 2015-02-08T09:03:35Z minion joined #sbcl 2015-02-08T09:03:36Z specbot joined #sbcl 2015-02-08T09:05:05Z minion quit (Remote host closed the connection) 2015-02-08T09:05:06Z specbot quit (Remote host closed the connection) 2015-02-08T09:09:40Z minion joined #sbcl 2015-02-08T09:10:20Z specbot joined #sbcl 2015-02-08T09:14:37Z |3b|: should storing NaNs in a hash table key error? (though i suppose they would never be retrievable, so i guess the error was helpful) 2015-02-08T09:45:59Z DeadTrickster quit (Ping timeout: 250 seconds) 2015-02-08T09:52:32Z angavrilov joined #sbcl 2015-02-08T10:15:41Z Quadrescence: |3b|, how do you produce a NaN in SBCL? 2015-02-08T10:16:04Z Quadrescence: |3b|, I suppose you mean eql hash tables 2015-02-08T10:16:05Z karswell quit (Read error: Connection reset by peer) 2015-02-08T10:16:31Z karswell joined #sbcl 2015-02-08T10:16:32Z |3b|: i think in this case, normalizing 0 vectors with fp traps off, and equal (maybe equalp) tables, the nans are in a vector 2015-02-08T10:17:31Z Quadrescence: NaN should probably error (or not be stored at all) for EQUAL and EQUALP hash tables. 2015-02-08T10:18:07Z |3b|: well, presumably NaN wouldn't be EQL either, so not much point in storing them there 2015-02-08T10:18:07Z Quadrescence: For EQL hash tables, it depends on if you allow (EQL nan nan) => T. I would say, yes it should be, because I think it's reasonable to have only (= nan nan) => NIL. 2015-02-08T10:18:43Z |3b|: should different NaNs be eql? 2015-02-08T10:18:52Z |3b| supposes yes, if any are 2015-02-08T10:19:14Z Quadrescence: I think they should be. 2015-02-08T10:19:35Z |3b|: oops, i guess not... (eql 0.0 -0.0) is false, so different nans should be distinct 2015-02-08T10:20:06Z Quadrescence: oh yeah you're right 2015-02-08T10:20:36Z |3b| thinks you could argue either way on same NaNs being eql 2015-02-08T10:20:56Z |3b|: and equal/equalp just use eql to compare numbers 2015-02-08T10:21:23Z Quadrescence: No, EQUAL does, EQUALP uses = 2015-02-08T10:21:24Z |3b|: oops, equal uses eql, equalp uses = 2015-02-08T10:21:27Z |3b|: yeah 2015-02-08T10:23:22Z Quadrescence: |3b|, Actually, I'm not sure (eql -0.0 0.0) is a good argument for having different NaNs not be EQL. The reason is -0.0 and 0.0 can be used to represent different things meaningfully, whereas it's extremely unlikely anyone has ever used different NaNs to distinguish between different concepts. 2015-02-08T10:24:43Z |3b| thinks Quadrescence doesn't know enough of the wrong sort of programmers :p 2015-02-08T10:24:55Z Quadrescence: Ha. 2015-02-08T10:25:00Z |3b|: extra bits? lets store stuff there! 2015-02-08T10:25:28Z Quadrescence: Use EQ for that stuff! 2015-02-08T10:25:58Z |3b| points to google and "NaN boxing" 2015-02-08T10:27:00Z |3b|: EQ is specified to not work at all for numbers 2015-02-08T10:27:00Z Quadrescence: I didn't mean people didn't exploit the bits, but looking at NaN as a type of numerical not-a-number number, there usually isn't a distinction between different types of "not a number"s. 2015-02-08T10:27:11Z |3b|: yeah 2015-02-08T10:27:40Z |3b|: but NaN is defined to not have the same value, so fails by 'numerical' meaning too 2015-02-08T10:28:22Z |3b|: and there are at least signalling vs quiet nans one might want to distinguish 2015-02-08T10:28:28Z Quadrescence: The line from CLHS that makes me believe NaN's should be EQL is "Thus eql tells whether two objects are conceptually the same" 2015-02-08T10:29:39Z |3b|: well, arguably NaN isn't the same by definition 2015-02-08T10:29:48Z Shinmera: That's a bit of a wonky line since one could say that "a" and "a" are conceptually the same, but they are not eql. 2015-02-08T10:30:05Z Quadrescence: Shinmera, it's definitely very much up for interpretation 2015-02-08T10:30:09Z |3b|: yeah 2015-02-08T10:30:47Z Quadrescence: Shinmera, but that isn't included because of other rules, namely it's neither a number nor a character. 2015-02-08T10:31:32Z |3b|: either way, my objection is to some strange error down in sxhash stuff, rather than no error or a nice one 2015-02-08T10:31:53Z |3b| isn't sure it is worth the extra time to check for it explicitly though 2015-02-08T10:32:19Z Quadrescence: Floats as HT keys sounds like a not so good idea 2015-02-08T10:32:51Z |3b|: nah, i want exact matching 2015-02-08T10:33:04Z |3b|: if they are off by lowest bit i don't want a match 2015-02-08T10:33:53Z |3b| doesn't want NaNs in my data at all, but i'd have preferred a match there too, even if i might not think it was correct 2015-02-08T10:41:31Z alchemis7 quit (Quit: @) 2015-02-08T10:47:47Z alchemis7 joined #sbcl 2015-02-08T11:04:36Z Quadrescence quit (Quit: This computer has gone to sleep) 2015-02-08T11:12:24Z oleo__ quit (Quit: Verlassend) 2015-02-08T11:35:19Z oleo joined #sbcl 2015-02-08T11:35:28Z scymtym__ joined #sbcl 2015-02-08T11:37:19Z scymtym_ quit (Ping timeout: 256 seconds) 2015-02-08T11:48:48Z Shinmera quit (Ping timeout: 252 seconds) 2015-02-08T12:41:28Z stassats joined #sbcl 2015-02-08T13:06:37Z specbot quit (Remote host closed the connection) 2015-02-08T13:06:38Z minion quit (Remote host closed the connection) 2015-02-08T13:14:51Z specbot joined #sbcl 2015-02-08T13:14:52Z minion joined #sbcl 2015-02-08T13:15:03Z specbot quit (Remote host closed the connection) 2015-02-08T13:15:04Z minion quit (Remote host closed the connection) 2015-02-08T13:18:16Z scymtym__: is there any reason for allowing (or rather trying to allow) (defclass foo () ()) (defclass foo () () (:metaclass foo))? 2015-02-08T13:18:38Z scymtym__ is working on lp 1418883 2015-02-08T13:20:51Z scymtym__: if not, i would just catch it in ENSURE-CLASS and signal something like "FOO cannot be its own metaclass" instead of the "vicious metacycle" error that is currently signaled 2015-02-08T13:30:11Z stassats` joined #sbcl 2015-02-08T13:30:53Z stassats: usually even changing the metaclass is not allowed 2015-02-08T13:35:15Z scymtym__: ok, i'll signal an error and see what breaks 2015-02-08T13:40:11Z Shinmera joined #sbcl 2015-02-08T13:42:10Z LiamH joined #sbcl 2015-02-08T13:44:43Z stassats`: gah, for some reason only the innermost nested let reaches debug-dump 2015-02-08T13:44:53Z stassats quit (Quit: ERC Version 5.3 (IRC client for Emacs)) 2015-02-08T13:45:36Z stassats`: (defun foo () (declare (optimize (debug 3))) (let ((a (let ((b (list 1 2 3))) b))) (break "~a" a) 1)), no variables are visible 2015-02-08T14:12:50Z mega1 joined #sbcl 2015-02-08T14:20:55Z scymtym__: i would like to push these changes: https://gist.github.com/scymtym/b79b164da3ed478eca53 (paste.lisp.org seems to be down). any objections? 2015-02-08T14:26:33Z stassats`: cl.net is down 2015-02-08T14:41:24Z stassats`: so the arg A to break is # {10082662C3}> {1008263FC3}> 2015-02-08T14:41:35Z stassats`: which is weird 2015-02-08T14:44:25Z pkhuong: |3b|: eql is true ... If x and y are both numbers of the same type and the same value 2015-02-08T14:45:33Z pkhuong: I'm not even sure a NaN should be eql to itself ;) 2015-02-08T14:54:53Z gingerale joined #sbcl 2015-02-08T15:12:05Z stassats`: and i got why the inline-inline thing happens, when called with a function argument, it substitutes the references to the function with the function 2015-02-08T15:12:16Z stassats`: and the second inline doesn't find the original references, since it is now deleted 2015-02-08T15:13:28Z stassats`: probably that's what happens here, A is substituted with B 2015-02-08T15:14:29Z stassats`: right, (defun foo () (declare (optimize debug)) (let ((a (lambda ()))) (break "~a" a) 1)) doesn't show A in the debugger either 2015-02-08T15:18:49Z stassats`: filed under "i see what's going on, don't know how to fix" 2015-02-08T15:39:59Z fridim_ joined #sbcl 2015-02-08T17:02:54Z nyef joined #sbcl 2015-02-08T17:10:15Z Intensity joined #sbcl 2015-02-08T17:48:38Z stassats`: stack analysis eludes me again 2015-02-08T17:55:57Z stassats`: somehow dxes get into the XEP 2015-02-08T17:57:11Z minion joined #sbcl 2015-02-08T17:57:35Z nyef: Stack analysis? The place that easily gets confuzzled by dead code? 2015-02-08T17:57:37Z minion quit (Remote host closed the connection) 2015-02-08T17:57:52Z stassats`: i am easily confused by stack analysis 2015-02-08T17:58:16Z stassats`: i don't think i have much dead code here, though 2015-02-08T17:58:28Z stassats`: (defun test (x) (let ((a (if x (list (list x)) (list x)))) (declare (dynamic-extent a)) (print a) t)) 2015-02-08T17:58:59Z nyef: No, that shouldn't have much dead code. 2015-02-08T17:59:01Z stassats`: do you have your DCE branch handy? 2015-02-08T17:59:48Z stassats`: for some reason tl-xep, and the bind both have one of the two DX vars on their stacks 2015-02-08T17:59:56Z nyef: Two commits at the head of http://repo.or.cz/w/sbcl/nyef.git/shortlog/refs/heads/dce-phase 2015-02-08T18:00:20Z stassats`: do you have a binary of it? just to test that form? 2015-02-08T18:00:26Z nyef: Ah, not built. 2015-02-08T18:00:57Z nyef: Let me do that real quick. 2015-02-08T18:01:08Z stassats`: well, i can build it no problem 2015-02-08T18:01:20Z stassats`: just wanted to combat global warming 2015-02-08T18:02:11Z stassats`: and it'll take me longer to clone than to build it 2015-02-08T18:02:24Z nyef: Okay then. 2015-02-08T18:02:54Z stassats`: i don't have the latest git with a nifty feature "Faster cloning by borrowing objects from existing clones" 2015-02-08T18:03:17Z pkhuong: you can do a bare clone that only gets HEAD 2015-02-08T18:03:41Z pkhuong: no, wrong optiona name 2015-02-08T18:03:56Z stassats`: and what about a different branch? it'll usually take more take time to figure it out than to clone the whole thing 2015-02-08T18:04:02Z Shinmera: --depth 1 2015-02-08T18:04:05Z pkhuong: --depth 1 2015-02-08T18:04:11Z nyef: Building now. 2015-02-08T18:04:35Z nyef: What would --depth 3 do? 2015-02-08T18:04:49Z pkhuong: nyef: 3 commits deep 2015-02-08T18:05:08Z stassats`: building too 2015-02-08T18:06:17Z pkhuong: you and your fast bits. 2015-02-08T18:07:19Z stassats`: it has the same problem 2015-02-08T18:07:22Z stassats`: so, DCE doesn't help 2015-02-08T18:07:48Z stassats`: was worth a try anyway 2015-02-08T18:08:40Z stassats`: i guess what i needed was git clone --branch dce-phase --single-branch --depth 1 2015-02-08T18:08:46Z Shinmera: iirc --depth 1 breaks sbcl's version name fetching due to 'git describe' not working. 2015-02-08T18:10:15Z stassats`: --single-branch is default with --depth 2015-02-08T18:10:27Z stassats`: i will now happily forget that next time i need it 2015-02-08T18:10:59Z stassats`: git clone --reference ../oldclone --dissociate git://... should be better 2015-02-08T18:11:44Z nyef: For that matter, adding the repo as a new remote in your existing working tree and doing a fetch might also be an angle. 2015-02-08T18:12:04Z pkhuong: yeah. no. I'm boycotting advanced git ;) 2015-02-08T18:13:15Z stassats`: interestingly, (if x (list 1) (list 2)) produces only one dx-lvar 2015-02-08T18:13:39Z stassats`: but when one of them is nested, it's more, and it can't cope with that 2015-02-08T18:14:34Z stassats`: the sticky lvar is probably referenced by both successors 2015-02-08T18:15:18Z nyef: Okay, now I remember my analysis of this problem. 2015-02-08T18:15:34Z nyef: You need to create an empty dx-lvar on the other path. 2015-02-08T18:16:13Z nyef: That way both paths are balanced, and you can also do the dx thing if one path DOESN'T dx at all. 2015-02-08T18:16:41Z nyef: I got that far, but not so far as to figure out how to create the empty dx-lvar. 2015-02-08T18:16:45Z stassats`: but (if x (list (list 1)) (list (list 2))) also crashes 2015-02-08T18:16:58Z nyef: Hrm. 2015-02-08T18:17:51Z nyef: Trying to remember what that looks like when it blows up. /-: 2015-02-08T18:22:23Z minion joined #sbcl 2015-02-08T18:23:02Z specbot joined #sbcl 2015-02-08T18:25:27Z nyef: Okay, in the one dx-lvar case, any test on the lvar identity "works", because there's only one of them. 2015-02-08T18:26:00Z nyef: As soon as you add another one that's only used in one branch, there's another lvar that must be presumed to be live but any identity test won't find it. 2015-02-08T18:26:32Z nyef: Your case of (if x (list (list 1)) (list (list 2))) crashes because it's a second unique lvar on EACH branch, so twice the fail. 2015-02-08T18:27:50Z stassats`: printing blocks, things look strange 2015-02-08T18:28:07Z stassats`: changing to (if x (cons (cons 3 4) 5) (cons 1 2)), i see that (cons 1 2) pushes one lvar 2015-02-08T18:28:23Z nyef: Yes. 2015-02-08T18:28:28Z stassats`: but then one block has just '5 in it 2015-02-08T18:28:41Z stassats`: and the previous block has 30> 29: CONS {GLOBAL-FUNCTION} 31> 32: CONS {GLOBAL-FUNCTION} 33> 34: '3 35> 36: '4 2015-02-08T18:28:45Z nyef: There's something going on with the ordering requirements on DV packets. 2015-02-08T18:29:04Z stassats`: and that '5 block pushes the same lvar as (cons 1 2) 2015-02-08T18:29:05Z nyef: The one block with '5 in it also has a known-combination, doesn't it? 2015-02-08T18:29:15Z stassats`: yes 2015-02-08T18:29:25Z fridim_ quit (Ping timeout: 265 seconds) 2015-02-08T18:29:50Z stassats`: and the block with '3 '4 doesn't push anything 2015-02-08T18:29:59Z nyef: Yes it does. 2015-02-08T18:30:13Z stassats`: if it did, it wouldn't have crashed 2015-02-08T18:30:27Z stassats`: one lvar travels up to the XEP, it can't find what pushes it 2015-02-08T18:31:16Z nyef: The block with '3 '4 is also the one with two references to CONS, isn't it? 2015-02-08T18:31:23Z nyef: Its start stack should be empty. 2015-02-08T18:32:24Z stassats`: "should" is the key word 2015-02-08T18:32:52Z nyef: Prepping a paste, hang on. 2015-02-08T18:34:17Z stassats`: ok, yeah, the start stack is empty 2015-02-08T18:34:22Z nyef: http://paste.lisp.org/display/145706 2015-02-08T18:34:41Z nyef: So, what's happening is that this one block produces a dv packet. 2015-02-08T18:35:01Z nyef: The NEXT block also produces a dv packet, the SAME dv packet that the other branch of the if produces. 2015-02-08T18:36:08Z nyef: So the existence of the dv packet (dv8 in my example) gets assumed once the control flows merge, and back-propagated to find where it's created. 2015-02-08T18:36:14Z nyef: But it's NOT created on one of the branches. 2015-02-08T18:36:21Z nyef: So it goes all the way back to the beginning. 2015-02-08T18:37:23Z stassats`: i can see that 2015-02-08T18:41:20Z nyef: There's some idea here about needing a better flow-sensitive analysis. 2015-02-08T18:41:24Z stassats`: hm, minion and specbot came alive on their own? 2015-02-08T18:42:15Z stassats`: cl.net is up for 19 min, so i guess somebody started them 2015-02-08T18:44:03Z stassats`: i now see the picture even better 2015-02-08T18:44:08Z nyef: Okay, so it blows up in order-uvl-sets, but the actual error is during update-uvl-live-sets? 2015-02-08T18:45:00Z stassats`: the eventual successor of the CIF has two lvars, one branch pushes only one, but the start stack of the ultimate successor has two lvars, so one is assumed to be already pushed 2015-02-08T18:45:08Z nyef: Yes., 2015-02-08T18:45:27Z stassats`: and then CIF gets the unclaimed lvar from the second branch 2015-02-08T18:45:32Z nyef: Right. 2015-02-08T18:47:40Z stassats`: so, what if when the second branch is processed, it checks that another predecessor pushes the lvar? 2015-02-08T18:48:06Z stassats`: though it may happen in the predecessor's predecessor 2015-02-08T18:48:28Z nyef: Loops. 2015-02-08T18:48:32Z stassats`: why do we walk the block backwards? 2015-02-08T18:48:37Z stassats`: blocks 2015-02-08T18:50:18Z nyef: Don't know. 2015-02-08T18:51:00Z stassats`: and that's dx only, what happens with unknown lvars, i don't want to know either 2015-02-08T18:59:10Z nyef: A forward flow analysis doesn't tell us when the value is no longer used, a backward flow analysis doesn't tell us when the value is no longer created. 2015-02-08T18:59:30Z stassats`: i know, let's start in the middle 2015-02-08T18:59:46Z oleo is now known as Guest44597 2015-02-08T19:00:22Z nyef: I was thinking "lets do both, and then reconcile the two" 2015-02-08T19:00:38Z oleo__ joined #sbcl 2015-02-08T19:00:41Z stassats`: but we have find-pushing-blocks 2015-02-08T19:00:55Z nyef: It's not flow-sensitive. 2015-02-08T19:00:57Z stassats`: and pushed-lvars, so, if we combine the two and pass to update-uvl-live-sets? 2015-02-08T19:03:15Z Guest44597 quit (Ping timeout: 265 seconds) 2015-02-08T19:03:18Z oleo__ quit (Read error: Connection reset by peer) 2015-02-08T19:11:38Z fridim_ joined #sbcl 2015-02-08T19:13:32Z nyef: So, a forward analysis, "this has been created in the past and not destroyed", and a backward analysis "this will be destroyed in the future and not yet created". 2015-02-08T19:15:11Z nyef: Then you get blocks with multiple predecessors, some of which have created a value and some of which haven't. 2015-02-08T19:15:43Z nyef: And the flipside, blocks with multiple successors, some of which destroy a value and some of which don't. 2015-02-08T19:16:55Z attila_lendvai joined #sbcl 2015-02-08T19:17:19Z pkhuong: are you sure we don't want to find dominators? 2015-02-08T19:17:32Z stassats`: but what do we actually need for stack analysis? knowing when dx values are going out of scope? 2015-02-08T19:18:01Z nyef: pkhuong: We may want to find dominators. 2015-02-08T19:18:48Z pkhuong: I have a vague feeling that we're abusing walking the clambda chain as a way to find dominators, but that doesn't always work once we mangle the control flow graph badly enough 2015-02-08T19:19:55Z nyef: And by the time we're down at stack analysis, the flow graph is about as mangled as it's going to get. 2015-02-08T19:22:03Z karswell quit (Remote host closed the connection) 2015-02-08T19:22:12Z pkhuong: and that's about as much bandwidth as I have for SBCL. The micro DPLL hidden in http://arxiv.org/abs/1404.0703 is too appealing (: 2015-02-08T19:22:19Z karswell joined #sbcl 2015-02-08T19:23:47Z stassats`: how do dx vars become out of extent? 2015-02-08T19:23:54Z stassats`: through clean ups? 2015-02-08T19:24:08Z nyef: Yeah, ir2-block-popped or something like that. 2015-02-08T19:26:21Z nyef: DX vars are destroyed through cleanup points or something like that, and UV vars are destroyed by their DEST nodes. 2015-02-08T19:28:43Z stassats`: the only think stack analysis does is inserting pop-values and nip-values? 2015-02-08T19:29:24Z oleo__ joined #sbcl 2015-02-08T19:29:42Z pkhuong: I think you can find the blocks were values are needed/not needed for normal loops. so one option is to disable DX for variables than span > 1 block and are included in a strange loop 2015-02-08T19:30:09Z pkhuong: - typos. 2015-02-08T19:30:22Z nyef: pkhuong: We have a case of linear code where the DX spans three or four blocks. 2015-02-08T19:30:41Z nyef: stassats`: Looks like it, yes. It's all about the cleanups. 2015-02-08T19:30:58Z pkhuong: nyef: the loop for that DX would be the whole function :\ 2015-02-08T19:31:00Z stassats`: ok, so, some progress at least for establishing what's going on 2015-02-08T19:31:32Z stassats`: time to take a crack at (lambda (b) (declare ((eql -7) b) (optimize debug)) (lambda (x) (logior x b))) 2015-02-08T19:32:49Z fridim_ quit (Ping timeout: 255 seconds) 2015-02-08T19:33:35Z pkhuong: hoisting cleanups to returns is correct; the problem is that we'd run out of stack when a loop body used DX alloc. 2015-02-08T19:40:42Z psy_ quit (Ping timeout: 245 seconds) 2015-02-08T19:56:57Z adlai quit (*.net *.split) 2015-02-08T20:21:18Z stassats`: transformed to (defun test (b) (declare ((eql 1) b) (optimize (debug 2))) (lambda (x) (+ b (the (unsigned-byte 32) (- x))))) 2015-02-08T20:21:24Z stassats`: and only happens when + gets to derived the type 2015-02-08T20:22:34Z stassats`: presumably that way it gets to choose a fixnum vop 2015-02-08T20:28:59Z stassats`: somehow it doesn't allocate an offset for a tn 2015-02-08T20:41:26Z fridim_ joined #sbcl 2015-02-08T20:44:11Z nyef: ... How is -1 an (unsigned-byte 32)? 2015-02-08T20:44:25Z nyef: Oh, sorry, scratch that, mixing up my variables. 2015-02-08T20:44:37Z stassats`: the type doesn't actually matter 2015-02-08T20:44:42Z stassats`: and the function either 2015-02-08T20:44:56Z stassats`: (defun test (b) (declare ((eql 1) b) (optimize (debug 2))) (lambda (x) (+ b (the fixnum (whatever x))))) 2015-02-08T20:45:58Z stassats`: the type matters as long as it makes it into a vop 2015-02-08T20:46:16Z nyef: So, it's the LTN pass that screws it up? 2015-02-08T20:46:43Z stassats`: no idea 2015-02-08T20:47:41Z nyef: Actually, does it trigger for integers / numbers only, or also for non-numeric types? 2015-02-08T20:47:56Z nyef: (That would try to rule out modarith issues.) 2015-02-08T20:48:07Z stassats`: i did rule out modarith issue 2015-02-08T20:48:23Z nyef: Hrm. 2015-02-08T20:48:31Z stassats`: at least i think, because it started from a modarith variant 2015-02-08T20:49:05Z nyef: Could still be something crazy with an integer type deriver. 2015-02-08T20:50:42Z Quadrescence joined #sbcl 2015-02-08T20:55:25Z stassats`: it uses SB-VM::FAST-+-C/FIXNUM=>FIXNUM with 1 as an info argument 2015-02-08T20:56:57Z stassats`: (integer 10 20) doesn't affect it, maybe it propagates the constant but not carefully enough? 2015-02-08T20:59:29Z stassats`: no arithmetics: (defun test (b) (declare ((eql 1) b) (optimize (debug 2))) (lambda (x) (eq b (the fixnum (- x))))) 2015-02-08T21:01:25Z stassats`: even less arithmetics: (defun test (b) (declare ((eql #\a) b) (optimize (debug 2))) (lambda (x) (eq b (the character (whatever x))))) 2015-02-08T21:02:36Z stassats`: SB-VM::FAST-IF-EQ-CHARACTER/C is used in this case 2015-02-08T21:03:34Z stassats`: curiously enough, (defun test (b) (declare ((eql #\a) b) (optimize (debug 2))) (lambda () b)) doesn't just optimize B away and does allocate a closure 2015-02-08T21:04:28Z nyef: Does it optimize away if you use (values b) ? 2015-02-08T21:04:47Z stassats`: no, a closure 2015-02-08T21:05:53Z nyef: Hunh. 2015-02-08T21:06:37Z stassats`: so, in ltn, it treats eql types as constants 2015-02-08T21:07:32Z stassats`: removing that, no crash 2015-02-08T21:07:50Z stassats`: so, it creates a closure but doesn't use it 2015-02-08T21:08:17Z nyef: Because returns don't get LTN annotated. 2015-02-08T21:08:37Z nyef: Something like that, at least. 2015-02-08T21:09:47Z stassats`: gah, so many things called "info" 2015-02-08T21:09:54Z stassats`: like, what isn't info? 2015-02-08T21:09:57Z stassats`: the most useless name 2015-02-08T21:12:11Z stassats`: so, what should be done, should we actually stop creating closures here? 2015-02-08T21:14:13Z nyef: I don't know. 2015-02-08T21:14:15Z nyef: Maybe? 2015-02-08T21:14:25Z stassats`: at least it's a good idea overall 2015-02-08T21:14:41Z stassats`: for true constants no closures are created 2015-02-08T21:14:55Z nyef: Exactly. 2015-02-08T21:15:31Z nyef: If we have a variable that is effectively a constant then why not treat it as a constant? 2015-02-08T21:15:57Z stassats`: "why" is anything the way it is in SBCL is a good question 2015-02-08T21:30:18Z stassats`: can't figure out how closures are made 2015-02-08T21:30:21Z stassats`: or rather, why 2015-02-08T21:30:30Z stassats`: or rather, why they are not made 2015-02-08T21:30:43Z stassats`: probably via let conversion 2015-02-08T21:38:15Z ehaliewicz joined #sbcl 2015-02-08T21:41:51Z stassats`: it returns the function, so, no let conversion 2015-02-08T21:48:01Z oleo__ is now known as oleo 2015-02-08T21:48:22Z stassats`: or maybe it is let conversion 2015-02-08T21:51:41Z stassats`: incidentally, (defun test () (declare (optimize (safety 0))) (let ((b #\a)) (declare ((eql #\a) b)) (lambda (x) b))) allocates a closure 2015-02-08T21:51:53Z stassats`: and it does not if DECLARE is omitted 2015-02-08T21:55:38Z nyef: ... Because the type-test causes the constant to be used outside the closure. 2015-02-08T21:55:52Z nyef: Hrm, not quite, given safety 0. 2015-02-08T21:56:08Z stassats`: the cast is still there when it's let-converted 2015-02-08T21:59:26Z stassats`: i just can't find where constant propagation happens 2015-02-08T22:10:13Z stassats`: it's SB-C::PROPAGATE-LET-ARGS 2015-02-08T22:11:10Z Shinmera quit (Quit: しつれいしなければならないんです。) 2015-02-08T22:12:25Z stassats`: and casts are opaque to it 2015-02-08T22:12:39Z stassats`: bloody casts always causing problems, can't they be removed sooner? 2015-02-08T22:16:10Z nyef: Heh. And at one point I added a cast that could NEVER be removed. 2015-02-08T22:18:06Z stassats`: ok, i see where the thing i wanted can happen 2015-02-08T22:20:29Z stassats`: in PROPAGATE-LOCAL-CALL-ARGS and PROPAGATE-LET-ARGS 2015-02-08T22:24:00Z stassats`: should be simple enough (ha-ha) but not today 2015-02-08T22:29:37Z stassats`: what if the types get derived after propagate-let-args is called? 2015-02-08T22:33:51Z stassats`: so, ltn/pack should be made resilient against that first 2015-02-08T22:34:03Z stassats`: and then it would be just an optimization 2015-02-08T22:36:53Z nyef: The STACK phase really IS only doing half a job, isn't it? 2015-02-08T22:40:16Z angavrilov quit (Remote host closed the connection) 2015-02-08T22:41:01Z nyef: pkhuong: I suspect that any sufficiently-clever flow-sensitive analysis for STACK effects actually WILL end up finding dominators. 2015-02-08T22:42:30Z nyef: stassats`: Would you count a change to STACK that performs the analysis required to find the DX cases we were looking at earlier, but errors out because it doesn't know how to fix the situation, a net win? 2015-02-08T22:48:22Z |3b|: anyone have an opinion on whether i should file a bug for http://paste.lisp.org/display/145702 against sbcl, static-vectors, or both? 2015-02-08T22:48:57Z pkhuong: |3b|: it's not an sbcl bug: the debugger correctly refuses to reify pointers outside the lisp heap as lisp objects 2015-02-08T22:49:05Z pkhuong: you instead get an invalid object wrapper 2015-02-08T22:49:25Z |3b|: pkhuong: i mean that it is a "not of type array" when it tries to signal invalid-array-index-error 2015-02-08T22:49:26Z nyef: IS it outside the heap? 2015-02-08T22:49:43Z pkhuong: not sure how to reort that better 2015-02-08T22:49:45Z pkhuong: nyef: it is. 2015-02-08T22:49:56Z nyef: So, not in static space? 2015-02-08T22:49:56Z |3b|: debugger can see the array in other contexts 2015-02-08T22:50:17Z pkhuong: an easy option is to have a "I know what I'm doing, reify random pointers and I'll deal with GC lossage" flag 2015-02-08T22:51:04Z nyef: I don't know how "easy" that would be, given SB-KERNEL:MAKE-LISP-OBJ. 2015-02-08T22:51:28Z pkhuong: another one is to audit interrupt error handlers and check for that specific case. 2015-02-08T22:51:28Z |3b| wouldn't object to if the error actually said what was wrong in my code 2015-02-08T22:51:58Z pkhuong: nyef: we (stassats`?) added that check recently. 2015-02-08T22:52:05Z nyef: Ah, okay. 2015-02-08T22:52:37Z nyef: And, actually, as long as it's a pointer OUTSIDE of heap space, the GC should be fairly quiet about it. 2015-02-08T22:52:38Z pkhuong: %make-lisp-obj still works in a pinch ;) 2015-02-08T22:53:03Z nyef: (The cheneygc might not be quiet, but gencgc certainly should keep mum.) 2015-02-08T22:53:16Z |3b|: but as far as i could tell, it doesn't actually get to the point of signalling the error...seems like it breaks on the ftype of sb-int:invalid-array-index-error, though i couldn't reproduce it separately with an ftype 2015-02-08T22:53:31Z nyef: Well, unless you turn on the gc consistency checking logic, but that's always a hit-or-miss thing anyway. 2015-02-08T22:54:05Z fridim_ quit (Ping timeout: 250 seconds) 2015-02-08T22:55:11Z pkhuong: ... I wonder how long we can make the type system work without widening and/or a pretty full blown SAT solver. 2015-02-08T22:56:44Z nyef: I wonder if we can start to use automatic proof techniques to show that certain parts of the compiler are correct. 2015-02-08T22:59:34Z pkhuong: that would be hard ;) 2015-02-08T22:59:38Z scymtym__: pkhuong: i probably don't know what i'm doing, but with the pattern-specializer stuff i got to the point where it became easier to use DPLL for PATTERN-MORE-SPECIFIC-P relatively quickly 2015-02-08T23:00:07Z nyef: Verifying the ENTIRE compiler would be hard. But what about just certain pieces? 2015-02-08T23:00:57Z pkhuong: scymtym__: I'm actually not surprised :'( 2015-02-08T23:02:25Z scymtym__: i wish you had told me in advance (maybe you tried and i didn't get it) :) 2015-02-08T23:03:34Z pkhuong: I don't think I did. I think Ucko's work made it pretty clear that testing for implication eventually calls for a SAT solver 2015-02-08T23:07:10Z scymtym__: i can see that. after some experiments of my own i looked at his and found it too complicated to take much inspiration from there. 2015-02-08T23:14:04Z stassats`: nyef: what do you mean by errors out? the only other acceptable thing would be to refuse dx allocation 2015-02-08T23:14:08Z stassats`: or actually perform it 2015-02-08T23:14:18Z stassats`: but of course i would prefer the latter 2015-02-08T23:14:34Z stassats`: the former would be enough to close the bug, if it's much easier 2015-02-08T23:14:53Z nyef: stassats`: I mean that instead of "failed aver (subsetp ...)" it says something like "bug: don't know how to handle ..." 2015-02-08T23:15:11Z nyef: So that it's at least DETECTING the situation properly. 2015-02-08T23:15:58Z stassats`: a different error would make me any happier that my conforming code doesn't work 2015-02-08T23:16:01Z stassats`: wouldn't 2015-02-08T23:16:28Z nyef: Basically, rather than the opaque "something's going on that we didn't expect", a more transparent "such-and-such is happening, but we haven't figured out how to deal with it yet". 2015-02-08T23:16:47Z nyef: Which ALSO means that the hook is there to actually deal with it. 2015-02-08T23:17:54Z stassats`: we already know what happens, other people won't care, and if they google, they'll find the ticket 2015-02-08T23:18:25Z stassats`: and that scary error should be more motivational to get it actually fixed 2015-02-08T23:18:53Z nyef: Hrm. 2015-02-08T23:19:13Z nyef: Except that the more specific message would be closer to it actually being fixed. 2015-02-08T23:19:32Z gingerale quit (Ping timeout: 246 seconds) 2015-02-08T23:19:50Z stassats`: for whom? 2015-02-08T23:20:12Z nyef: Fair enough. 2015-02-08T23:20:37Z nyef: Guess I'll do it on a branch. 2015-02-08T23:22:35Z stassats`: now, if we stop CIFs from being allowed to dx-allocate, that'll be at least a workaround 2015-02-08T23:23:24Z stassats`: if we don't figure the right solution before the next release, we could do that 2015-02-08T23:25:12Z stassats`: (if (list x) nil) is already non-dxable 2015-02-08T23:25:34Z nyef: And why isn't it DXable? 2015-02-08T23:25:45Z nyef: It SHOULD be DXable. 2015-02-08T23:26:18Z stassats`: it does seem strange 2015-02-08T23:26:41Z nyef: In fact, I would posit that the REASON it's not DXable is THIS BUG. 2015-02-08T23:26:54Z stassats`: but wouldn't it present the same problem? 2015-02-08T23:27:23Z nyef: Yes! The EXACT same problem. 2015-02-08T23:28:19Z nyef: But here's the thing: Creating a "dummy" DX allocation that consumes no stack space should be perfectly straightforward. 2015-02-08T23:29:30Z stassats`: i'd rather solve the chief issue 2015-02-08T23:29:40Z nyef: ... not enough indians? 2015-02-08T23:30:15Z nyef: What do you consider to be the "chief" issue here? 2015-02-08T23:31:35Z stassats`: proper stack analysis in the presence of different successors 2015-02-08T23:32:11Z nyef: And the follow on question is "what do you do with the results of that analysis?" 2015-02-08T23:32:43Z nyef: Currently our stack analysis is used to insert %NIP-VALUES and %POP-VALUES forms. 2015-02-08T23:33:35Z stassats`: it just saves the stack pointer before the values are pushed and then resets it, doesn't it? 2015-02-08T23:33:48Z stassats`: so there shouldn't be any problems if different amounts are pushed 2015-02-08T23:34:10Z nyef: Exactly. 2015-02-08T23:34:19Z nyef: ... And my dinner is ready. I'll be back in a bit. 2015-02-08T23:34:33Z nyef: I think I'll work on this problem a bit over the next couple of days, though. 2015-02-08T23:49:51Z attila_lendvai quit (Quit: Leaving.)