On Thu, May 22, 2014 at 2:49 PM, Martin Jambor <mjam...@suse.cz> wrote: > Hi, > > On Wed, May 21, 2014 at 04:27:32PM +0200, Richard Biener wrote: >> On Wed, May 21, 2014 at 3:16 PM, Martin Jambor <mjam...@suse.cz> wrote: >> > Hi, >> > >> > this demonstrates how results of ipa-prop escape analysis from >> > previous patches can be used at a later stage of compilation by >> > directly returning them from gimple_call_arg_flags which currently >> > relies on fnspec annotations. >> > >> > Bootstrapped and tested on x86_64-linux and also passes LTO bootstrap. >> > I have only had a brief look at behavior of this in SPEC 2006 and for >> > example in astar 1.19% of invocations of gimple_call_arg_flags return >> > noescape where we previously never did and in calculix this increases >> > from 15.62% (from annotations) to 18.14%. Noclobber flag is reported >> > far less often still but for example in gamess that number raises from >> > 5.21% to 7.66%. >> > >> > Thanks, >> > >> > Martin >> > >> > >> > 2014-04-30 Martin Jambor <mjam...@suse.cz> >> > >> > * gimple.c: Include cgraph.h. >> > (gimple_call_arg_flags): Also query bitmaps in cgraph_node. >> > >> > Index: src/gcc/gimple.c >> > =================================================================== >> > --- src.orig/gcc/gimple.c >> > +++ src/gcc/gimple.c >> > @@ -47,7 +47,7 @@ along with GCC; see the file COPYING3. >> > #include "demangle.h" >> > #include "langhooks.h" >> > #include "bitmap.h" >> > - >> > +#include "cgraph.h" >> > >> > /* All the tuples have their operand vector (if present) at the very >> > bottom >> > of the structure. Therefore, the offset required to find the >> > @@ -1349,32 +1349,50 @@ int >> > gimple_call_arg_flags (const_gimple stmt, unsigned arg) >> > { >> > tree attr = gimple_call_fnspec (stmt); >> > + int ret; >> > >> > - if (!attr || 1 + arg >= (unsigned) TREE_STRING_LENGTH (attr)) >> > - return 0; >> > - >> > - switch (TREE_STRING_POINTER (attr)[1 + arg]) >> > + if (attr && 1 + arg < (unsigned) TREE_STRING_LENGTH (attr)) >> > { >> > - case 'x': >> > - case 'X': >> > - return EAF_UNUSED; >> > - >> > - case 'R': >> > - return EAF_DIRECT | EAF_NOCLOBBER | EAF_NOESCAPE; >> > - >> > - case 'r': >> > - return EAF_NOCLOBBER | EAF_NOESCAPE; >> > - >> > - case 'W': >> > - return EAF_DIRECT | EAF_NOESCAPE; >> > - >> > - case 'w': >> > - return EAF_NOESCAPE; >> > + switch (TREE_STRING_POINTER (attr)[1 + arg]) >> > + { >> > + case 'x': >> > + case 'X': >> > + ret = EAF_UNUSED; >> > + break; >> > + case 'R': >> > + ret = EAF_DIRECT | EAF_NOCLOBBER | EAF_NOESCAPE; >> > + break; >> > + case 'r': >> > + ret = EAF_NOCLOBBER | EAF_NOESCAPE; >> > + break; >> > + case 'W': >> > + ret = EAF_DIRECT | EAF_NOESCAPE; >> > + break; >> > + case 'w': >> > + ret = EAF_NOESCAPE; >> > + break; >> > + case '.': >> > + default: >> > + ret = 0; >> > + } >> > + } >> > + else >> > + ret = 0; >> > >> > - case '.': >> > - default: >> > - return 0; >> > + tree callee_decl = gimple_call_fndecl (stmt); >> > + if (callee_decl) >> > + { >> > + cgraph_node *callee_node = cgraph_get_node (callee_decl); >> > + if (callee_node) >> > + { >> > + if (cgraph_param_noescape_p (callee_node, arg)) >> > + ret |= EAF_NOESCAPE; >> > + if (cgraph_param_noclobber_p (callee_node, arg)) >> > + ret |= EAF_NOCLOBBER; >> >> That's quite expensive. I guess we need a better way to store >> those? > > if we want to avoid the cgraph_node lookup, then I think we need to > store this information in the decl or struct function. That is > certainly possible and might even be more appropriate.
Can we? If the body is not readily available we only have decl and cgraph-node, not struct function. I suppose we could exchange the struct function pointer in tree_function_decl for a cgraph_node pointer and put the struct function pointer into the cgraph_node. Of course that may have impacts on FEs who might create struct function before creating a cgraph node. But at least it would avoid enlarging FUNCTION_DECL. In the end most of the tree_decl_with_vis stuff should move over to symtab and var-decls should get a varpool_node pointer as well. Back to the call flags stuff - I also meant the representation of the "fn spec" attribute. Rather than parsing that again and again move it to a better place (which you seem to invent?) and better unified representation. Can you try if removing the cgraph hash is possible with the struct function pointer idea? Thanks, Richard. > Thanks, > > Martin > >> >> > + } >> > } >> > + >> > + return ret; >> > } >> > >> > /* Detects return flags for the call STMT. */ >> >