Reputation: 405
Is there an attribute for functions indicating that they won't be called indirectly?
I'm doing an inter-procedural analysis and I could improve significantly if I knew which functions are called only directly (I would know statically where they get called from and where they return). So far, I don't know how to get that information so I have to treat every function as if it could be called from anywhere (and that's a bummer in terms of optimizations!).
I would assume that LLVM already has such mechanism, but if it doesn't, can I compute it? I understand that, in general, this is impossible to know if a function will be called indirectly. But are there any functions for which I can find this out? I would imagine that most local functions fall in this family. I would also imagine that LLVM already does this when it inlines a function and then removes it's definition.
I found unnamed_addr
which seems related. But as far as I can tell that only says that the address of the function is unimportant, but it could still be aliased, passed to other functions at runtime and called indirectly. Is this the right reading?
I'm working on LLVM 9.0 in case that maters, but I'm still interested if there are solutions in other versions.
Upvotes: 2
Views: 260
Reputation: 949
Since you haven't specified a language of the program(s) onto which you want to run your analysis, I will assume that you are using C.
No, LLVM does not have such a feature. The only way to be exactly sure that a function foo()
is only called directly is to perform a flow-sensitive analysis. The resulting callgraph points out all functions that are called indirectly. That way you can exclude those functions from the set of all functions in the corresponding llvm::Module
object.
However, as you probably know if you are doing an inter-procedural analysis, flow-sensitive analysis is not easy and does not scale well to large projects. If your primary focus is to find exact matches, then a flow-sensitive algorithm is your way to go.
If you want to approximate the functions that can be called directly, you can do the above callgraph without a flow-sensitive algorithm, i.e. by using an only context-sensitive or maybe in certain circumstances a field-sensitive approach. The implementation for these approaches are simpler, but contain more inaccuracies.
Relying on LLVM's function attributes alone however will not help you in solving you problem, at least not for all programs.
Upvotes: 1
Reputation: 34401
You can trust analysis that is done on functions with internal
linkage. To improve things you can plug your pass into LTO pipeline and use it with LTO-enabled linker. This will extend the "visibility" of your pass from translation unit to a whole resulting binary.
Upvotes: 1