Later I found out that cgraph_mark_needed_node was already being called in cgraph_finalize_function, and that should really keep my function from being removed. But when the function cgraph_remove_unreachable_nodes executes, it is marked as unreachable just because at this point it is not marked as needed anymore. The piece of code which is doing that is function_and_variable_visibility, in ipa.c. Oddly, the condition for doing so is having DECL_EXTERNAL set for my fndecl, which I just said, was my former mistake. I really don't know why this erratic behavior is happening, I am explicitly setting DECL_EXTERNAL to false.
Cheers, --- Rodolfo Guilherme Wottrich Universidade Estadual de Campinas - Unicamp 2013/7/23 Rodolfo Guilherme Wottrich <rgw...@gmail.com>: > Hello, > > 2013/7/23 Martin Jambor <mjam...@suse.cz>: >> Hi, >> >> But you do call cgraph_add_new_function on it as well, right? If not, >> how is its symbol table node (also called and serving as the call >> graph node) created? > > I call finish_function for my decl. Inside that function, there's this > one call to cgraph_add_new_function, but the condition it is inside is > bypassed: > > /* ??? Objc emits functions after finalizing the compilation unit. > This should be cleaned up later and this conditional removed. */ > if (cgraph_global_info_ready) > { > cgraph_add_new_function (fndecl, false); > return; > } > > Right after that, there's a call to cgraph_finalize_function, which I > guess works the way it should, creating its cgraph node. I took a look > at the comment in cgraph_add_new_function and it states that "this > function is intended to be used by middle end and allows insertion of > new function at arbitrary point of compilation. The function can be > either in high, low or SSA form GIMPLE." As I'm doing it in parsing > time and there was no gimplification passes yet, I guess it is ok not > to use it at this point. > >> (And BTW, you are hacking on trunk, right? Older versions can be >> quite a bit different here.) > > I understand that, but I intend to use Dragonegg to obtain LLVM IR > after the gcc front-end has done its work, so I'm hacking version > 4.6.4, which is said to work better with Dragonegg. > >> What do you mean by "50% of the time?" That you get different results >> even when you do not change your compiler? That should not happen and >> means you invoke undefined behavior, most likely depending on some >> uninitialized stuff (assuming your HW is OK) so you are probably not >> clearing some allocated structure or something. (Do you know why >> DECL_EXTERNAL was set? That looks weird). > > Yeah, exactly: different results even not changing the compiler. > About DECL_EXTERNAL: it was my fault. At first I was trying to > reproduce the creation of a function_decl as in > create_omp_child_function, in omp-low.c, and I eventually forgot that > I set that attribute when playing with the possibilities. > >> Anyway, my best guess is that your function is removed by >> symtab_remove_unreachable_nodes in ipa.c. (And now I also see that >> analyze_functions in cgraphunit.c is also doing its own unreachable >> node removal, but hopefully runs early enough this should not be your >> problem.) If your function is static and is not called or referenced >> from anywhere else, gcc will try to get rid of it. > > I traced the execution path in gdb, and it happens that the function > is really being removed in cgraph_remove_unreachable_nodes in ipa.c > (that's basically the same function you pointed out, just another gcc > version). I don't know why that happens anyway, neither why it happens > intermittently when not debugging and never when debugging. My > function is not called or referenced yet, but neither is another > function in my source code which I put just in order to test this > issue, and yet it is not removed like my forged one. So it is in > respect to being or not static. A doubt: I tested setting TREE_STATIC > for my decl, but does that mean my function is static? The > documentation on the TREE_STATIC macro is: "In a FUNCTION_DECL, > nonzero if function has been defined". > >> Try setting DECL_PRESERVE_P of your decl (or calling >> cgraph_mark_force_output_node on its call graph node which is cleaner >> but should be equivalent for debugging, I suppose). If that helps, >> this is most likely your problem. > > I tried DECL_PRESERVE_P and it didn't work. In this version of gcc > there's no cgraph_mark_force_output_node. I tried > cgraph_mark_needed_node instead, didn't work either. > >> What do you mean? That your function is not output or that you cannot >> use gdb at all? > > That my function is never output when using gdb. > >> Add -fdump-ipa-all switch and look whether the function appears >> there. Especially the cgraph dump can usually tell you that a >> function was removed as unreachable. Grep all dumps for "Reclaiming >> functions:" and see whether your function is listed. > > You were right, but this is a direct consequence of my function being > removed like discussed before. > > I'll keep investigating the problem and will inform you in case > something changes. > Thank you, > > --- > Rodolfo Guilherme Wottrich > Universidade Estadual de Campinas - Unicamp