dotty-linker / dotty

Modified version of dotty suporting language specific and library-specific optimizations
Other
37 stars 5 forks source link

Support to apply rewrite on any function #5

Open siriux opened 8 years ago

siriux commented 8 years ago

I would like to be able to apply rewrite rules where "from" applies to any function.

Apart from applying the rule to any function, we would need a way to extract the different parts of the function, like, arguments, body, return type, ... so that it can be fully reconstructed (probably with some changes).

This could open a whole new type of optimizations (the ones I'm thinking are things like controlled stack allocation, value classes with multiple values, ideas to improve scala-offheap, etc).

We started to discuss it on gitter with @DarkDimius and others (and probably @xeno-by is interested too) but I think is better to have a formal discussion here.

I understand that for some optimizations we don't know yet if they will work faster, and therefore the potential use cases are not clear. But being able to try them easily means we may find that some of them actually work, and that's a big win in my opinion.

I hope we can discuss it in detail and find a way to support it.

DarkDimius commented 8 years ago

@siriux, while this is a nice idea in general that can simplify prototyping of compiler optimizations, I'd prefer not to extend the scope of the project yet, to make sure we can deliver on it.

But as soon as we'll have a good and widely used implementation of rewrite rules, it would be good moment to reconsider and see if we can easily extend them to cover more use-cases. No promises though.

We can start discussion now though. Let's say you assume that you can deconstruct function definitions, what would you implement with it? I have an impression that implementing something like on-stack allocation requires some analysis(at least current implementation on linker relies on it). I wonder if this case can be covered without complicating rewrite rule syntax\engine.

Another question is that as rules are very powerful, I'd like them to automatically become tests. So far, I don't see a straightforward way to automatically test definition-transforming rules in a decent way.

siriux commented 8 years ago

The approach I have in mind for stack allocation is similar to scala-offheap and scala native structs.

The idea is to annotate the classes you want to behave like structs allocated on the stack, and they become value classes that point into an array that behaves as the stack. This would be done using the new scala-meta macro annotations. It's definitely possible, as shown in scala-offheap, and scala-meta would make it relatively easy.

Once you have that, your only problem is to manage the stack. For that I just need to insert some code before the body of the function, before every call that returns a struct, and before every return of the function. That can be done using scala-meta.

The only critical thing is to get the right stack for your thread. For ScalaJS is simple, as is single threaded. On the JVM it can be done much faster than you can imagine, as shown in the tests I did for the value-plugin of miniboxing (see smart cache): https://github.com/miniboxing/value-benchmarks/blob/master/src/main/scala/valium/benchmark/MultivalueBenchmark.scala

Apart from that, there are many uses for it. I think that most of the interesting use cases of aspect oriented programming could be implemented this way. In particular you could add logging, monitoring, benchmarking, ...

About the tests, just an idea, because I don't have a clear picture of what you want. The way I imagine this is with a new object RewriteFunctions(...). As I imagine that you would only convert to tests the Rewrite objects, not Warn or Error objects, this would not be converted to tests either.