I searched the doxygen documentation and could not find a solution to my
task:
In a ModulePass running at EP_OptimizerLast, if I have a function F like in:
bool Foo:runOnModule(Module &M) {
LLVMContext &C = M.getContext();
for (auto &F : M) {
// magic here
if I want to know from which function (callee) each function is called -
how can I do this?
(so that I e.g. have a "Function *callee" result or a list if it is
called from several other functions - or even better, the specific basic
blocks where the calls are.)
I am aware that this will not work for calls that are made outside of
the analyzed module.
bool Foo:runOnModule(Module &M) {
LLVMContext &C = M.getContext();
for (auto &F : M) {
// magic here
if I want to know from which function (callee) each function is called -
how can I do this?
To get the direct callers you would iterate through the users of F,
and check whether it's being used as the callee operand in a CallInst
or InvokeInst. Fortunately there's a CallSite class that abstracts
away many of the differences. So something like:
for (auto &U : F.getUsers()) {
if (auto CS = CallSite(U)) {
if (CS->getCalledFunction() == F)
doStuff(CS);
}
}
I am aware that this will not work for calls that are made outside of
the analyzed module.
> bool Foo:runOnModule(Module &M) {
> LLVMContext &C = M.getContext();
> for (auto &F : M) {
> // magic here
>
> if I want to know from which function (callee) each function is called -
> how can I do this?
To get the direct callers you would iterate through the users of F,
and check whether it's being used as the callee operand in a CallInst
or InvokeInst. Fortunately there's a CallSite class that abstracts
away many of the differences. So something like:
for (auto &U : F.getUsers()) {
if (auto CS = CallSite(U)) {
if (CS->getCalledFunction() == F)
doStuff(CS);
}
}
Nit: This might visit the same call site multiple times if the function
is passed as a function pointer argument to recursive call `f(&f, &f)`.
for (auto &U : F.getUses()) {
if (auto CS = CallSite(U.getUser())) {
if (CS->isCallee(&U))
doStuff(CS);
}
}
or, if you also want to deal with callback calls [0, 1, 2], you can do:
for (auto &U : F.getUses()) {
if (auto ACS = AbstractCallSite(U))
doStuff(ACS); // or ACS.getCallSite()
}