<div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr">I am try to build Call graph as a practice following the assignment at [1]<div>The objective it to take in IR and give back Call graph featuring which functions calls which Functions.</div><div>The problem is dealing with function pointers as they usually are indirect CallSite.</div><div>I tried to overcome the problem by using Alias Analysis (with the new pass manager).</div><div>I set up the pipeline like this</div><div><font face="monospace, monospace"><span style="color:rgb(0,0,0)">int main (int argc, char **argv, const char **env) {  </span><br>        // Before this point I would setup the module object, cl and friends
<br>        //
<br>        PassBuilder PB;  <br>        ModulePassManager MPM(true);  <br>        LoopAnalysisManager LAM(false);  <br>        FunctionAnalysisManager FAM(true);  <br>        CGSCCAnalysisManager CAM(false);  <br>        ModuleAnalysisManager MAM(true);  <br>        AAManager AA ;//= PB.buildDefaultAAPipeline();  <br>        if (auto Err = PB.parseAAPipeline(AA, "basicaa"))  <br>                report_fatal_error("Error parsing basicaa AA pipeline");  <br>        FAM.registerPass([&] {return std::move(AA);});  <br>        MAM.registerPass([&] {return callgraphs::WeightedCallGraph();});  <br>        PB.registerModuleAnalyses(MAM);  <br>        PB.registerCGSCCAnalyses(CAM);  <br>        PB.registerFunctionAnalyses(FAM);  <br>        PB.registerLoopAnalyses(LAM);  <br>        PB.crossRegisterProxies(LAM, FAM, CAM, MAM);  <br>
<br>        MPM.addPass(callgraphs::WeightedCallGraphPrinter(outs()));  <br>        MPM.run(*module, MAM);  <br>        return 0;  <br>}<br></font><font face="monospace">callgraphs hold the Analysis and transformation pass they do the following:-</font></div><div><span style="font-family:monospace">A- generate the graph</span></div><div><span style="font-family:monospace">B- Print it.</span></div><div><span style="font-family:monospace"><br></span></div><div><span style="font-family:monospace">Deep inside that Namespace this is how I would analyse an CallSite once it is proven to hold an indirect function call</span></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace"><span style="color:rgb(0,0,0)">void WeightedCallGraphInfo::AnalyseIndirectCallSite(CallSite &cs, ModuleAnalysisManager &MAM) {
</span><br>        Value *v = cs.getCalledValue();
<br>        Function &caller = *cs.getCaller();
<br>        Module &M = *caller.getParent();
<br>        FunctionAnalysisManager &FAM =  MAM.
<br>                getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
<br>        AliasAnalysis &AA = FAM.getResult<AAManager>(caller);
<br>        for (Function &f: M) {
<br>                if (f.isIntrinsic())
<br>                        continue;
<br>                AliasResult R = AA.alias(v, &f);
<br>                if (R == AliasResult::MustAlias){
<br>                        //What goes here doesn't matter to my question <br>                }
<br>        }</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">}</font><br></div><div><br></div><div><br></div><div>The problem is that R is always AliasResult::MayAlias regardlles of the analysis pipeline I have tried basicaa and the <span style="font-family:monospace,monospace">BP.buildDefaultAAPipeline() </span>via the pipeline setup shown above and bunch of other ones (through opt).</div><div><br></div><div>My concert is that I could be doing something wrong and not being the limitation of the alias analysis.</div><div><br></div><div>For example</div><div><br></div><div>I tested the analysis on simple .c module that looks like this </div><div><span style="font-family:monospace"><span style="color:rgb(0,0,0)">void foo(int x);
</span><br>
<br>void bar() {
<br>  foo();
<br>  bar();
<br>}
<br>
<br>void baz() {
<br>  foo();
<br>  bar();
<br>}
<br>
<br>int main(int argc, char **argv) {
<br>  foo(argc);
<br>  bar();
<br>  baz();
<br>  void (*bam)() = 0;
<br>  switch (argc%3) {
<br>   case 1: bam = bar; break;
<br>   case 2: bam = baz; break;
<br>  }
<br>  bam();
<br>  return 0;
<br>}<br>
<br></span></div><div>I placed the llvm IR on pastebin at [2] because it is too big.</div><div><br></div><div>The problem is that bam() and foo() and main() may alias while I was expecting to not alias relation, and bar() and baz() had may alias relation as well however I was expecting a MustAlias. So if anyone had clue about whether I am doing something wrong or this is the expected behavior, it will be great.</div><div><br></div><div>I have the source code for the whole pass (just in case anyone would have a doubt in how I did things) at [3].</div><div><br></div><div>[1] <a href="http://www.cs.sfu.ca/~wsumner/teaching/886/15/project1.html">http://www.cs.sfu.ca/~wsumner/teaching/886/15/project1.html</a></div><div>[2] <a href="https://pastebin.com/BGt787tb">https://pastebin.com/BGt787tb</a></div><div>[3] <a href="https://github.com/oddcoder/LLVM_Playground/tree/master/01_callgrapher">https://github.com/oddcoder/LLVM_Playground/tree/master/01_callgrapher</a></div><div><br></div><div><br></div><div><br></div><div>Thanks,</div><div>Ahmed</div></div></div></div></div>