[LLVMbugs] Re: [LLVMdev] Tarjan+function_ptrs == trouble ?
Chris Lattner
sabre at nondot.org
Thu Dec 5 23:00:07 PST 2002
> if you take the time to print out the function each non-looping node iter
> traverses, it never reaches main...
Ok, first note that the CallGraph class does really stupid (but correct)
things for function pointers, so you're not going to see anything
remarkably nice here... Make sure to read the CallGraph.h comments to
understand exactly what is going on.
Despite that, I can verify that the SCC iterator seems to not be doing the
right thing. On the testcase (below), and with the pass below, I get the
following:
$ opt -load /localhome/lattner/llvm/lib/Debug/libtest.so -test < test.o > /dev/null
New SCC
Node: __main
New SCC
Node: func_one
New SCC
Node: func_two
New SCC
Node: func_three
Which doesn't visit main. Vikram, could you look into this if you get a
chance?
-Chris
------------------- Pass code ----------------------------
#include "llvm/Analysis/CallGraph.h"
#include "llvm/Function.h"
#include "llvm/Pass.h"
#include "Support/TarjanSCCIterator.h"
struct Test : public Pass {
virtual bool run(Module &F) {
typedef TarjanSCC_iterator<CallGraph*> MyTarjan;
CallGraph& callGraph = getAnalysis<CallGraph>();
for (MyTarjan I = tarj_begin(&callGraph), E = tarj_end(&callGraph); I != E; ++I) {
SCC<CallGraph*> *S = *I;
assert(S);
std::cerr << "New SCC\n";
for (unsigned i = 0, e = S->size(); i != e; ++i)
if (Function *F = (*S)[i]->getFunction())
std::cerr << " Node: " << F->getName() << "\n";
else
std::cerr << " Indirect node\n";
}
return false;
}
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesAll();
AU.addRequired<CallGraph>();
};
};
RegisterOpt<Test> Z("test", "test");
-------------------- Testcase ------------------------
#include <stdlib.h>
#include <stdio.h>
//#define WORKS
int * a_global;
int a_predicate = 1;
int another_pred =0;
int func_one()
{
return 1;
}
int func_two()
{
return 2;
}
int func_three()
{
return 3;
}
int main()
{
int (*func_ptr)();
if(a_predicate)
func_ptr = func_one;
else if(another_pred)
func_ptr = func_two;
else
func_ptr = func_three;
#ifdef WORKS
return func_one();
#else
return func_ptr();
#endif
}
More information about the llvm-bugs
mailing list