Finding all CALL_EXPR tree nodes during GENERIC
Hello, I'm doing some testing with a gcc plugin (also helped me understand a lot of how GCC works) but I've hit a roadblock. I want to find all of a function body's CALL_EXPR nodes (i.e. what calls it has) early during GENERIC, so I assume the PLUGIN_PRE_GENERICIZE hook is what I should use right? Anyway, my problem is I don't know how to find all the CALL_EXPR nodes from the DECL_SAVED_TREE of the function's decl. So what's the simplest way to do that? The routines in tree-iterator.h don't help much, they only iterate through a statement list. Do I have to go through every expr manually? Is there no API available? (walk_tree doesn't seem to handle it, or maybe I don't know how to use it) This is obviously trivial to do in GIMPLE form (iterating through all statements and finding GIMPLE_CALL) but I need it as early as possible, so that would be in the tree representation (GENERIC?). I hope I'm just missing something obvious. Thanks.
Re: Finding all CALL_EXPR tree nodes during GENERIC
Yes, it seems walk_tree does the job, I was probably doing something wrong before. Thank you. I have a question about it. Am I correct in assuming I only have to check the subtrees of nodes that satisfy EXPR_P? So for nodes that aren't EXPR_P, can I just set *walkSubtrees to 0, or will that miss some CALL_EXPRs? In my tests, none were missed, but I don't know if this is all-encompassing for C/C++ generated AST. Oh and another thing, is it possible to change the node (or create a new one and modify the source that points to it)? I assume that's why the first parameter to walk_tree_fn is a tree* right? That would be useful to know too. On Sat, Nov 18, 2017 at 6:49 PM, Richard Biener wrote: > On November 18, 2017 5:38:35 PM GMT+01:00, Katsunori Kumatani > wrote: >>Hello, I'm doing some testing with a gcc plugin (also helped me >>understand a lot of how GCC works) but I've hit a roadblock. >> >>I want to find all of a function body's CALL_EXPR nodes (i.e. what >>calls it has) early during GENERIC, so I assume the >>PLUGIN_PRE_GENERICIZE hook is what I should use right? >> >>Anyway, my problem is I don't know how to find all the CALL_EXPR nodes >>from the DECL_SAVED_TREE of the function's decl. So what's the >>simplest way to do that? The routines in tree-iterator.h don't help >>much, they only iterate through a statement list. Do I have to go >>through every expr manually? Is there no API available? (walk_tree >>doesn't seem to handle it, or maybe I don't know how to use it) > > Walk_tree should do it. > > Richard. > >> >>This is obviously trivial to do in GIMPLE form (iterating through all >>statements and finding GIMPLE_CALL) but I need it as early as >>possible, so that would be in the tree representation (GENERIC?). I >>hope I'm just missing something obvious. >> >>Thanks. >
Re: Finding all CALL_EXPR tree nodes during GENERIC
On Mon, Nov 20, 2017 at 12:32 PM, Richard Biener wrote: > On Sun, Nov 19, 2017 at 9:27 PM, Katsunori Kumatani > wrote: >> Yes, it seems walk_tree does the job, I was probably doing something >> wrong before. Thank you. >> >> I have a question about it. Am I correct in assuming I only have to >> check the subtrees of nodes that satisfy EXPR_P? So for nodes that >> aren't EXPR_P, can I just set *walkSubtrees to 0, or will that miss >> some CALL_EXPRs? In my tests, none were missed, but I don't know if >> this is all-encompassing for C/C++ generated AST. > > You'd have to experiment, it depends on the C/C++ AST. You should be > able to skip TYPE_P though. > You're right, one example would be variable initialization. I realized the exprs are found within its DECL_INITIAL, which is part of a VAR_DECL (and so not an expr). I'll stick to TYPE_P then, thanks.
GCC Plugin Callback on template instantiation (or constexpr call evaluation)
For a GCC plugin, is there a way to have a callback registered/get called on template instantiation of a type with an attribute or some other means? Consider: template struct foo { typedef T __attribute__((bar)) type; }; void foobar(foo::type); In this case, the attribute handler callback gets called on the template definition when it registers the attribute, not instantiation in foobar which is what I need because I want to do some "processing" on the type (which in this case is int*). For instance, remove the POINTER_TYPE from it (which can easily be done with metaprogramming but that's beside the point for this simple exercise, obviously). Just as a note, I don't mind overriding any hooks (lang_hooks or targetm or otherwise) if need be (and call the old one in a chain), or just using plain plugin events, or other callbacks, etc. An alternative way would be if I could intercept a constexpr call evaluation in a plugin event, so then I can defer the whole thing to a decltype of the plugin's function. There was a patch to add a PLUGIN_EVAL_CALL_CONSTEXPR event a year ago but I've no idea what happened to it. I'm aware it's probably not possible at the moment but maybe I'm missing something non-obvious. If it must be patched, hopefully a very simple hook can be added for this purpose since it would help a lot with plugins extending metaprogramming like this. Thanks.
Re: GCC contribution
Please don't change the lang_hooks into virtual methods. Speaking from a plugin development viewpoint, C hooks are very easy to override individually, without having to change the entire object or create a new one. I realize that it's not the intended use for the hooks, and not why they were created. But they enable plugins to do a whole lot more, despite the limited plugin event callbacks already present (*especially* the targetm hooks!). For example, I wanted to add some plugin processing (actually a top-level asm statement) at the end of a translation unit (with gathered data) to add some special symbols / GAS directives (not instructions). But there's no "normal" plugin event for this. So instead I simply saved the original lang_hooks.parse_file hook (pointer), overrode the hook with the plugin's, which calls the original first and then does whatever plugin does. And it works fine. This kind of thing wouldn't be easily changed with virtual methods I believe. Once again, I realize that was not the intended use for hooks, but it's a nice side effect and IMO should be kept. Plugins suffer a lot from the "chicken and egg" problem (nobody wants to add events that would not be needed, but nobody codes plugins without enough events) and hooks kind of solve a lot of it, so that's a good thing (especially targetm, more so than lang_hooks). I mean, if you had to first suggest an event and *hope* it gets added before even starting your plugin (otherwise it would be a waste of time), you'd just give up. Or at least, the majority would. At least with hooks, nobody needs to add anything for plugins, since you can override the C hooks directly from the plugin (while maintaining a chain for the old one).
Re: GCC contribution
On Thu, Mar 29, 2018 at 8:01 PM, Mikhail Maltsev wrote: > On Wed, Mar 28, 2018 at 11:15 PM, Katsunori Kumatani > wrote: >> >> For example, I wanted to add some plugin processing (actually a top-level >> asm statement) at the end of a translation unit (with gathered data) to add >> some special symbols / GAS directives (not instructions). But there's no >> "normal" plugin event for this. >> >> So instead I simply saved the original lang_hooks.parse_file hook >> (pointer), overrode the hook with the plugin's, which calls the original >> first and then does whatever plugin does. And it works fine. This kind of >> thing wouldn't be easily changed with virtual methods I believe. > > I think this would be pretty straightforward: you will need a single plugin > event, which would allow you to provide your own instance of a class derived > from lang_hooks. You could then inherit a new class from the lang_hooks > class in the frontend and override any of its virtual methods. > > -- > Regards, >Mikhail Maltsev But the point is that, when I first started using this "trick" with overriding hooks, there was no such functionality. I'm not saying that adding it is a bad thing! I'm only saying that, in this context, C hooks are easier to change without having to account for special plugin code (which did not exist). For example what if someone else comes up with another idea like that (but which has no workaround yet), but he can't do it anymore and has to request a change? Most people would probably give up on their plugin ideas at this point. I mean, most hooks don't even have a "this" pointer or object, I don't see why making them virtual would be better anyway, especially since it's *only one* object we're talking about? (one global variable). Function pointers obviously bloat things up if there's a lot of instances of the class/struct, but this is not the case, so they make more sense in this case than virtual methods IMO.