Debugging "missing callgraph edge for call stmt"

Johannes Pfau nospam at example.com
Thu Jan 3 10:33:16 PST 2013


Am Thu, 3 Jan 2013 18:10:09 +0000
schrieb Iain Buclaw <ibuclaw at ubuntu.com>:

> On 3 January 2013 17:38, Johannes Pfau <nospam at example.com> wrote:
> 
> > Am Thu, 3 Jan 2013 16:47:00 +0000
> > schrieb Iain Buclaw <ibuclaw at ubuntu.com>:
> >
> > > On 3 January 2013 16:12, Johannes Pfau <nospam at example.com> wrote:
> > >
> > > > Then there's the question why the outer function has to be a
> > > > template as well for this to happen: It's because if it's not a
> > > > template, gdc uses a completely different code path: There's a
> > > > "!gen.functionNeedsChain (f)" check in outputFunction which is
> > > > false for the failing case. (cgraph_finalize_function marks the
> > > > function as reachable)
> > > >
> > > >
> > > That might be just it then...
> >
> > I admit I don't really know why this check is needed but even if I
> > try to call cgraph_finalize_function for indirectLess the backend
> > dies with the same error. Actually my statement above was wrong,
> > cgraph_finalize_function only marks the function as reachable if
> > it's TREE_PUBLIC/. The not-templated case works even without
> > cgraph_finalize_function so that's not the issue.
> >
> >
> I would have thought that it be a little more factors than that.
> Remember, TREE_PUBLIC only means whether or not the function is
> callable outside of the module we are compiling (TREE_PUBLIC=0 means
> that the function is not marked as global in the assembly output).

Sorry, I should try to reword that. There's indeed much more which
determines if a function is ultimately reachable or not. I debugged
much of that code (the cgraph part, I tried to stay away from gimple)
in the last 24 hours. The backend does correctly detect, for example,
that percolateDown calls indirectLess. But in the end it throws that
information away and says indirectLess is not reachable, probably
exactly because of DECL_CONTEXT. After trying to find out why the
backend falsely marks indirectLess as unreachable, I revisited the test
case and I think the backend is actually correct about indirectLess, it
is unreachable and can be optimized away.

The backend is wrong about percolateDown. And this is where TREE_PUBLIC
is the problem. TREE_PUBLIC short circuits any reachability checks. If
a function is TREE_PUBLIC it's always potentially reachable. And we
tell the backend that percolateDown is TREE_PUBLIC => reachable
although it's not.

It is of course also a bug in the backend as the reachability check for
indirectLess should probably detect that percolateDown is TREE_PUBLIC.
But we still give the backend false information, percolateDown isn't
TREE_PUBLIC and the wrong information causes the crash.

(Remember, the real issue is that when gcc verifies the percolateDown
function, the indirectLess function is not available. But as
percolateDown can never be called this is not a real runtime bug, it
just confuses the verify verifier.)


> > >
> > > I have been rolling round my head to remove the notion of
> > > functions nested in functions within the D codegen.  Having only
> > > RECORD and UNION types set in DECL_CONTEXT.  So all public
> > > functions are TREE_PUBLIC=1 (unless there's some overriding
> > > attribute), and all nested functions are TREE_PUBLIC=0.
> >
> > I see! That's why percolateDown is public, but isn't it essentially
> > a nested function in the test case?
> >
> >
> What I said was an idea that *could* be implemented, but is not yet.
> 
> See ObjectFile::setupSymbolStorage for why templates are public by
> default...
> 

OK I'll have a look at that later.


More information about the D.gnu mailing list