[refactor] Move Type::ctype into an external AA#4569
[refactor] Move Type::ctype into an external AA#4569yebblies wants to merge 17 commits intodlang:masterfrom
Conversation
|
I can't see any performance difference on the autotester. |
|
It's a logical consequence to do this, though I wonder if other alternatives have been evaluated. One alternative idea would be to have a backend header, declaring a backend specific payload, that gets embedded in the frontend types. This could remain an opaque type for the frontend. |
Other alternatives?
I thought the compiler's AA was pretty fast.
The ultimate goal is compiler-as-a-library, which cannot (reasonably) work like that. We need a way to add passes without any modification of the ast types. |
The string table is fast, the aav is better than a few years ago, but not great.
Injecting them via template argument? How often is the ctype looked up, e.g. when compiling Phobos. |
I'd consider that unreasonable.
Yeah, that's true. Although it doesn't looks like it's big enough to worry about.
Let's find out. |
|
It would help, if you can provide those numbers and also explain what other fields you want to move out of the AST. |
aggregate.h:
declaration.h:
dsymbol.h:
enum.h:
expression.h:
module.h:
mtype.h:
statement.h:
@yebblies - Did I miss any other transparent BE types? |
|
@ibuclaw The list from Would be nice for that list to be empty.
@MartinNowak Building phobos on win32 results in ~10^6 ctype lookups. I want to move all backend-specific types out of the ast. I might look at doing the same with other passes (eg ctfe) sometime in the future. |
|
Keeping backend fields in the AST also eagerly allocates memory for fields that are never used. |
src/toctype.c
Outdated
There was a problem hiding this comment.
What happened here? Seems unrelated.
There was a problem hiding this comment.
Just a minor refactoring.
In the old version: If the unqualified version of this type already has a ctype, we copy it and add the qualifiers. Otherwise we create a new Classsym/ctype.
In the new version, we generate a new ctype if this is the unqualified version, otherwise recurse to get the unqualified ctype then copy it.
As far as I can tell, the old code would generate a symbol with the wrong qualifiers when called with a qualified before being called on the unqualified symbol, because both would be generated and set to the same value but the 'add modifiers' code would never be reached.
|
The autotester isn't a great guide for performance testing, as it only deals with small programs. A compiler slows down bit by bit, from barnacles accumulating on the hull one by one. Each one doesn't do much, but the accumulation does. Perhaps use an opaque pointer instead? |
The win32 phobos build is fairly big.
I know, but sometimes it's worth it.
A pointer to what, though? Different passes need to store different data, and having a pointer for each is exactly the problem I'm hoping to avoid. There were similar concerns about the minor but systemic slowdowns from switching to the double-dispatch visitor implementation, but I think that has payed off in making the code more maintainable. My goal it to make it as easy as possible to maintain glue layers/backends, and that means removing all backend-specific code and data from the frontend ast. |
It was a requirement for ddmd, because D doesn't support implementing classes in multiple files.
Can you please try to find out what LLVM et.al. do? |
I think Walter meant |
Yeah, sort of. There were other options but that was by far the best.
The fact that you no longer need to update headers when adding a pass more than makes up for any maintenance burden IMO.
There's no guarantee it makes it slower. When running e2ir, the ctype hash table is much more likely to be in cache than the
ie the current system. Requires knowing which passes need cached data at compile time, potential wasted memory if they're not needed. Some backends require multiple values per class, and this either means lots of ugly or an extra indirection.
It's not really about optional passes, it's about not polluting the frontend code with backend-specific data members.
Not always. More cache friendly, less space allocated when not all classes are codegen'd, etc
I tried, didn't get very far. Is this just the usual knee-jerk reaction to anything that might hurt performance? Are there any concrete goals that would make this acceptable? I honestly would accept a fairly big performance hit if it got us closer to having a 100% unified frontend. |
|
@yebblies - I'm considering a future of GDC without any |
Yes. |
That's why I said non-sparse data ;), might indeed make sense for rare backend data.
The last release came with a 10-25% slowdown (Issue 14431).
That's an interesting argument, but it doesn't quite work out for ctype. The slowdown is neglectable but measureable. |
+1 - I agree, let's convert all and benchmark. |
Thanks, I can work with that. |
|
Yes, let's try it. |
|
Considering the performance impact: Why not using a factory class for AST nodes? In this case each backend could provide decorated AST nodes. The factory itself could be made configurable to support a library solution. The trade-off would be a cast to the new AST types if access to new members is required. |
The big downside of that is that it is a very invasive change. It also only supports a single backend at a time. |
Why would we want to be interchanging backends during the same compilation process? Correct me if I misread this. :-) |
I mean that CTFE is sort of another backend, etc. |
|
Any update on this? I'd like to push for removing |
|
I haven't touched it since dconf. I had a big argument with Walter about this, and he basically said that the only way he would accept this is if I can show that with all of the similar changes implemented dmd's performance improves in some measurable way. i.e. showing that the performance difference is negligible is not enough. Also that we should beware of crustaceans and their ill effects on the movement speed of ships. I did some work on |
|
If speed is a problem, maybe convert the AA hash implementation into a template? You could also allow overriding how keys are hashed to be naive for speed (eg: integer and pointer keys don't need hashing). |
|
@MartinNowak @yebblies ping. So, lets get benchmarks on this, and decide if it's the best approach? The only other approach I can think of is to have a synthetic struct pointer, which each visitor in the glue defines locally. E.g: tocsym.c And so on. However I think this is the most agreeable suggestion so far. |
|
There's been controversy on this, and @WalterBright all but vetoed this approach. However the context has changed since, what with the more widespread use of visitors by @RazvanN7 and others. Thoughts on reviving or reframing this? I'm thinking an opaque pointer is a simple technique that other compilers use as well. |
|
It's still useful on my side to have all dmd-specific fields removed. |
|
It also saves memory on frontend AST nodes (#13808). |
The idea is that backend-specific passes shouldn't need to add methods to the frontend ast classes. Using a hash scales much better, if the performance is acceptable.