freenode/#clasp - IRC Chatlog
Search
14:37:31
Bike
i read it wrong, caller and callee only need the same prototype for musttail, not tail. still need the same calling convention though. that's annoying.
15:18:37
drmeister
You can look in build/boehm/generated/enum_inc.h for what is being exposed via clbind.
15:20:49
drmeister
I thought the translators would be generated by the macros as well - but that doesn't appear to be the case.
15:22:22
drmeister
The translators need to be available where the call is exposed so that the template code knows what to do.
15:25:18
drmeister
So SOMEWHERE there needs to be a to_object and from_object translator for llvmo::ClaspCallingConv. I'm starting to think we have to write it ourselves. Looking...
15:28:09
drmeister
https://github.com/clasp-developers/clasp/blob/master/include/clasp/core/symbolToEnumConverter.h#L114
15:31:31
drmeister
I think all header files get included before the scraper generated code that exposes functions gets compiled - so the code generated by the ENUM_TRANSLATOR will be available for the clbind template code.
15:38:57
drmeister
Clasp has built with compile-file-parallel 12 times since I changed SharedMutex and turned it back on. I'm ready to declare that the weird crashes to be due to the old broken SharedMutex.
15:42:25
Bike
i didn't do an ENUM_TRANSLATOR when i defined the atomic ordering enum, and that works fine
15:48:24
Bike
tons of compile errors. "error: no template named 'to_object': did you mean '::translate::to_object'?"
15:52:04
drmeister
Ihttps://github.com/clasp-developers/clasp/blob/master/include/clasp/core/symbolToEnumConverter.h#L114
15:52:07
drmeister
https://github.com/clasp-developers/clasp/blob/master/include/clasp/core/symbolToEnumConverter.h#L114
15:53:11
drmeister
It's not dicey - it's just stupid. If you put ENUM_TRANSLATOR inside of namespace llvmo then you end up in llvmo::translate::from_object - that can't work.
15:53:55
Bike
well no, i mean the dicey part is i don't understand why this enum needs ENUM_TRANSLATOR and others don't.
15:54:38
drmeister
It's probably why I don't use it much - C++ macros with bizarro rules about where you are allowed to use them suck.
15:55:11
drmeister
I don't know. What is the name of a function that takes one of these other enums?
15:59:50
drmeister
https://github.com/clasp-developers/clasp/blob/master/include/clasp/llvmo/llvmoExpose.h#L4527
16:02:42
drmeister
When the code that exposes the function that takes or returns these enumerated types is compiled clang needs to have the template specializer for to_object and from_object available - otherwise it falls back to the default and the default cant do anything useful with it and you get those alien whatchamawhosits errors.
16:04:49
drmeister
The macro is in the .cc file? I don't think that will work. This is arcana - but IIRC these functions all get exposed inside of gc_interface.cc and that source file includes every header file - so those translators need to be in the header file.
16:06:39
drmeister
The downside of having them in header files is if you change them - then you need to recompile EVERYTHING.
16:07:09
drmeister
So I tend to now put SYMBOL_EXPORT_SC_ and CL_ENUM_xxx in .cc files and the translators go into header files.
16:09:07
drmeister
Try the header file, right after the enum is defined, in the top level namespace.
16:10:47
drmeister
If you really want to see the sausage being made - run the C preprocessor on gc_interface.cc - that shows everything to do with exposing functions.
16:11:52
drmeister
Any .def("xxx",&xxx) where xxx takes some weird enum will be preceded by the translator and that will be preceded by the enum definition. You will have to wade through a million lines of code.
16:15:48
drmeister
We have a bit more fussiness because the scraper generates code and it gets included in gc_interface.cc and these translators need to be available when gc_interface.cc is compiled - so I generally put them in header files.
16:18:06
drmeister
Yeah - there isn't a single translator in any .cc files in clasp except for astExpose.cc and clangTooling.cc - and they use the public clbind.
16:18:58
drmeister
This stuff is very opaque as well. It's C++ compile time type/template resolution.
16:40:56
Bike
it built except that it crashed for unclear reasons while building asdf. so imma try it again
17:55:54
Bike
also, right now llvm-sys:set-calling-conv does a kind of manual dispatch rather than using a single dispatch gf, which kinda sucks?
19:10:01
drmeister
Bike: Agreed on the manual dispatch - although single dispatch may suck more. What we really need to do is make single dispatch use the generic function dispatch machinery.
19:10:24
drmeister
We were able to do this for a while - because we have the generic function dispatch interpreters.
19:12:14
drmeister
Can you remind me again why we wrote this wrapper? Kerrrriisst - I'm like a gold fish - moving from one problem to the next and immediately forgetting the solution or reason for the previous problem.
19:13:01
drmeister
This was one of those situations where I said I felt compelled to write a wrapper - or that we had to write a wrapper.
19:17:02
Bike
which is why i'll need to do something similar for setAtomic even though the enum type is not anonymous
19:22:07
Bike
void llvm_sys__ste_calling_conv(T_sp obj, ClaspCallingConv conv) { if (gc::IsA<CallBase_sp>(obj)) { gc::As_unsafe<CallBase_sp>(obj)->wrappedPtr()->setCallingConv(conv); ...
19:23:51
drmeister
And this won't work because the setCallingConf takes a llvm::CallingConv::ID, which is a typedef for uint8_t - right?
19:24:27
Bike
right. i mean, it "works" in the sense that you can then pass it a number instead of an enum symbol
19:26:49
drmeister
CL_EXTERN_DEFMETHOD(CallBase_O, (void (*)(llvmo::ClaspCallingConv))&CallBase_O::ExternalType::setCallingConv);
19:27:24
drmeister
I'm not sure it will work. I've used these method pointer casts to select overloaded methods.
19:28:31
drmeister
Here I'm trying to convince the compiler to cast the function pointer to one that takes a ClaspCallingConv as the argument. The argument doesn't need to be converted because your enums have the same integer values as the original llvm::CallingConv::ID values - right?
19:29:39
Bike
will it work with getCallingConv too, do you think? so only the return type is different
19:32:01
drmeister
In C++ you aren't allowed to overload function/method names that only differ in their return type. That touches on this but it shouldn't cause us any problems. We are casting one function pointer into another function pointer with a type that the compiler can use to find an appropriate translator. The llvm::CallingConv::ID and llvmo::ClaspCallingConv are bitwise identical.
19:42:37
Bike
we're not casting it to a void*, are we? we're casting it to another function pointer, so it's fine
20:22:40
Bike
and was talking about the possibility of another entry point to handle varargs but didn't take a closure
20:23:13
karlosz
https://github.com/clasp-developers/clasp/commit/370c82f80f6000350c132f0aa6feda0122a8b06a
20:24:04
karlosz
that way we never need to cons closure vectors for any type of local call no matter the lambda list
20:31:15
karlosz
so i implemented if-if elimination the other day and noticed for (If (not x) ... ...) the fact that we get f->m and m->f pairs sort of blocked the optimization
20:31:48
karlosz
its not that delete-transmission doesn't work anymore, its just that when the metaevaluator is simplifiying the flow graph those pairs can come into existence
20:32:37
karlosz
then the metaevaluator simplifies the flow graph and you get those next to each other
20:33:15
karlosz
so i was thinking by pushing f->m and m->f coercion instructions later we wouldn't have to worry about having to eliminate pairs of those instructions all the time
20:33:59
karlosz
unlike with constant reference it doesn't seem like an high level optimizations will ever take advantage of the fact that those instructions are "there"
20:34:47
karlosz
and those coercion instructions seem like they can be recovered from the rtype/ctypes of the computations anyway
20:34:51
Bike
sure. that's why i'm working on mv calls. then we can only use mtf and mtf when it's part of the semantics.
20:42:03
Bike
this isn't working with SyncScope for some reason. error in some file i haven't touched
21:10:45
Bike
annoying wrinkle here: error messages from the argument parsing code use the closure (unsurprisingly)
21:10:58
Bike
we can check if the call is valid ahead of time, except for keywords i guess, in general
21:12:06
Bike
maybe cleavir can have some kind of hook for what calls to local-call-ify... eck... i was hoping to be able to skip lambda list parsing in cleavir as much as possible
21:30:23
Bike
cos it's kind of nice for the error object to be able to reference a function, i guess.
21:30:26
karlosz
also, the idea is that we check ahead of time and only signal a warning at compile time but still leave a runtime error
21:30:50
Bike
sure, but we can't check keyword arguments, in the weird case of having variable keywords
21:32:29
karlosz
in python they just don't local call convert anything with &rest or variable keyword args
21:34:10
Bike
but we could just allocate a closure for the error, or not include a function object in the error. i think if cleavir marked all local calls that would be nice, there are things that can be done with that information.
21:34:46
Bike
the question of how to actually do the call is sort of lower level? like the choice of calling convention. maybe we can do that in some nice way since you were having it so that uh... i wasn't totally clear on how closures were allocated actually
21:34:56
Bike
i thought you wanted it so that each reference of a local function would get its own allocation'
21:59:00
Bike
maybe we could separate the closure-allocation consequences of local-call from the "here's the function, you can inline or whatever" aspect
22:36:12
karlosz
Bike: i kinda changed my mind on that. that's how they do it in cmucl, but it's pseudo-spec-violating
22:36:32
karlosz
since you lose EQ-ness of the function object if you cons a new one on each reference
22:37:01
karlosz
it would be super nice if we could do it so we simplify the mutually closing over labels handling
23:01:21
Bike
yeah. i don't remember the details so much. but like (make-hash-table :test #'eq) failed because the #'eq wasn't the same as the global function
23:16:33
Bike
i was lookinag at changing how multiple values are handled, and expanding multiple-value-call optimizations
23:16:39
drmeister
This is the buildbot for the last couple of days using bir and compile-file-parallel
23:20:00
drmeister
Where is the generic function discriminating interpreter defined? We have one in C++ right?
23:23:46
drmeister
So we don't have an interpreted generic function discriminator class? Did we have one and you changed it to a bytecode interpreter?
23:25:30
drmeister
I thought we had a special C++ class that could be setup to evaluate a discriminating function
23:26:57
Bike
we just have a normal funcallable instance, with the interpreter as its discriminating function.
23:28:39
drmeister
Here's what I'm musing about. We have these crap single-dispatch-generic functions that we can replace with interpreted-discriminating-functions.
23:29:50
drmeister
We can create generic-functions with satiated call histories/specializer profiles that dispatch to C++ methods based on the type of the single argument that it would dispatch on.
23:31:42
drmeister
But we have the usual bootstrapping problem - we can't do this until we have certain facilities in place. We need the aclasp/bclasp compiler
23:45:43
drmeister
If we change those two functions so that they generate something that clos__interpret_dtree_program(SimpleVector_sp program, T_sp generic_function, VaList_sp args) can use...
23:46:14
drmeister
Then I think we can get rid of the SingleDispatchxxx code and use generic functions for C++ methods.
23:48:52
drmeister
This would speed up calling of C++ methods and allow us to compile the discriminating functions if we want to.
1:44:41
drmeister
I'm proposing to replace SingleDispatchGeneric functions with the same dtrees we use for generic functions. It will simplify calling C++ methods - and probably speed it up a bit.
1:45:28
drmeister
I think the simplest way to do it is to get rid of SingleDispatchGenericFunctions and use generic functions in their place.