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? > + } > } > + > + return ret; > } > > /* Detects return flags for the call STMT. */ >