Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle valid functions with the same name #2

Open
matheustavares opened this issue Sep 18, 2019 · 2 comments
Open

Handle valid functions with the same name #2

matheustavares opened this issue Sep 18, 2019 · 2 comments

Comments

@matheustavares
Copy link

matheustavares commented Sep 18, 2019

Hi, Chaudron. Thanks for this great tool! There's only one thing I really miss which is handling multiple functions with the same name. As an example, let's imagine a toy-project containing four files: a.c, b.c, header.h and c.c:

a.c:

static void a(void)
{}

void a_wrapper(void)
{
    a();
}

b.c:

void a(void)
{}

header.h:

void a(void);
void a_wrapper(void);

c.c:

#include "header.h"

int main()
{
        a();
        a_wrapper();
        return 0;
}

The result of cally's full graph for this project is:
result

But as we have two different and valid a() declarations in our project, we would expect something like this:
expected

Cally does warn of multiple definitions, which is great. But it would be even better if it could disambiguate the different definitions as they are all valid C constructions.

I know this might be a limitation of the *.expand files format: function calls contain the callee address but function declarations don't show this information, so we cannot disambiguate. But I thought that perhaps raising this issue could hopefully bring up ideas on how this could be resolved (maybe even by using more than just the *.expand files). Any thoughts/ideas on this?

@chaudron
Copy link
Owner

I quickly looked at this, but if we take multiple expand outputs, the tool does not know the relation to each other (there is no linker input).

We could assume that if the function is called and present in the same .expand file it should matched against that specific one, and not a global one.

I do not know enough about the RTL expand output, but it looks like the flags could tell us the function is static or global:

a.c.233r.expand:(call_insn 5 2 0 2 (call (mem:QI (symbol_ref:DI ("a") [flags 0xc03] <function_decl 0x15036ef00 a>) [0 a S1 A8])
c.c.233r.expand:(call_insn 5 2 6 2 (call (mem:QI (symbol_ref:DI ("a") [flags 0x41] <function_decl 0x15192de00 a>) [0 a S1 A8])

With this, we could do detect if it links against global or local version, which could help a lot in optimizing the code. From a quick look on the web there is SYMBOL_FLAG_LOCAL and SYMBOL_FLAG_EXTERNAL which could help.

I'm rather busy, but if I get time I'll try to add support...

@matheustavares
Copy link
Author

Hi, @chaudron . I tried solving this problem but, apparently, -fdump-rtl-expand doesn't dump enough information. As stated here:

GCC was designed to use RTL internally only. Correct RTL for a given program is very dependent on the particular target machine. And the RTL does not contain all the information about the program.

But a friend of mine suggested using GCC's LTO feature to overcome this problem. Since LTO happens during link-time, it already has all the information from the different compilation unities. Using this idea and the gcc-python-plugin, I managed to write a plugin to dump the call graphs. In case you might want to take a look, it is at: https://github.com/matheustavares/gcc-callgraph-plugin

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants