This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: PR middle-end/28779
>
> I remember this is somehow "carefuly" crafted to not cause ICEs when due to
> miscounting here we end up with ICE in inliner when inlined size goes
> negative ;)
Yep, the testcase in PR28779 is precisely about inline size getting
negative due to mismatch with what inliner does. This happens because
of what is just declaration at esitmate_num_insns becomes real function
at early inlining time. This won't happen with unit-at-a-time, since we
analyze after parsing everything unless --combine is used. Non
unit-at-a-time compilation is affected by same problem however.
This version attempts to be crafted just bit more "carefuly" than
former: The former fix replaced CALL_EXPR arguments walk by walk of
DECL_ARGUMENTS when available and CALL_EXPR as fallback. Due to thinko
it also eliminated the walk completely for functions with prototype but
no definition. This fix keeps DECL_ARGUMENTS walk but adds TYPE_ARGS
walk that is used when prototype is around keeping CALL_EXPR walk as
fallback for functions with no definition nor prototype.
Honza
>
> So I prefer that you put this on trunk first once we have branched.
> We can consider
> backporting to 4.3.1 if it turns out to be safe ;)
>
> Richard.
>
> > PR middle-end/28779
> > * tree-inline.c (estimate_num_insns_1): Fix counting of cost of call_expr.
> > Index: tree-inline.c
> > ===================================================================
> > *** tree-inline.c (revision 132380)
> > --- tree-inline.c (working copy)
> > *************** estimate_num_insns_1 (tree *tp, int *wal
> > *** 2434,2439 ****
> > --- 2434,2444 ----
> > case CALL_EXPR:
> > {
> > tree decl = get_callee_fndecl (x);
> > + tree addr = CALL_EXPR_FN (x);
> > + tree funtype = TREE_TYPE (addr);
> > +
> > + gcc_assert (POINTER_TYPE_P (funtype));
> > + funtype = TREE_TYPE (funtype);
> >
> > if (decl && DECL_BUILT_IN_CLASS (decl) == BUILT_IN_MD)
> > cost = d->weights->target_builtin_call_cost;
> > *************** estimate_num_insns_1 (tree *tp, int *wal
> > *** 2456,2476 ****
> > break;
> > }
> >
> > /* Our cost must be kept in sync with cgraph_estimate_size_after_inlining
> > ! that does use function declaration to figure out the arguments. */
> > ! if (!decl)
> > {
> > tree a;
> > call_expr_arg_iterator iter;
> > FOR_EACH_CALL_EXPR_ARG (a, iter, x)
> > d->count += estimate_move_cost (TREE_TYPE (a));
> > }
> > - else
> > - {
> > - tree arg;
> > - for (arg = DECL_ARGUMENTS (decl); arg; arg = TREE_CHAIN (arg))
> > - d->count += estimate_move_cost (TREE_TYPE (arg));
> > - }
> >
> > d->count += cost;
> > break;
> > --- 2461,2494 ----
> > break;
> > }
> >
> > + if (decl)
> > + funtype = TREE_TYPE (decl);
> > +
> > /* Our cost must be kept in sync with cgraph_estimate_size_after_inlining
> > ! that does use function declaration to figure out the arguments.
> > !
> > ! When we deal with function with no body nor prototype, base estimates on
> > ! actual parameters of the call expression. Otherwise use either the actual
> > ! arguments types or function declaration for more precise answer. */
> > ! if (decl && DECL_ARGUMENTS (decl))
> > ! {
> > ! tree arg;
> > ! for (arg = DECL_ARGUMENTS (decl); arg; arg = TREE_CHAIN (arg))
> > ! d->count += estimate_move_cost (TREE_TYPE (arg));
> > ! }
> > ! else if (funtype && prototype_p (funtype))
> > ! {
> > ! tree t;
> > ! for (t = TYPE_ARG_TYPES (funtype); t; t = TREE_CHAIN (t))
> > ! d->count += estimate_move_cost (TREE_VALUE (t));
> > ! }
> > ! else
> > {
> > tree a;
> > call_expr_arg_iterator iter;
> > FOR_EACH_CALL_EXPR_ARG (a, iter, x)
> > d->count += estimate_move_cost (TREE_TYPE (a));
> > }
> >
> > d->count += cost;
> > break;
> >