[LLVMdev] code generation goes into an infinite loop
Daniel Wilkerson
daniel.wilkerson at gmail.com
Sat Oct 3 15:06:23 PDT 2009
We seem to be creating an infinite loop in llvm while trying to
implement the simplest possible code generation. Specifically, we are
trying to emit code for the following program, as it is easily
testable from the command-line:
int main(int argc) { return argc; }
We got our code generator to build and link with llvm. When we run
it, it pauses when running the PrintModulePass and then exits with a
bus error. I suspect that this is an infinite loop leading to a stack
overflow.
While many kinds of errors we could fix by looking at other people's
examples or reading the docs, I suspect that this should be considered
to be a bug in the verifier pass: clearly we generated wrong LLVM
datastructures somehow and the verifier is not catching it before the
emitter falls off a cliff. Please comment.
Daniel
// modified from:
// llvm/docs/tutorial/JITTutorial1.html
// make an LLVM module
printf("%s:%d make module\n", __FILE__, __LINE__);
// Module* Mod = makeLLVMModule();
llvm::Module *mod = new llvm::Module("test");
// make a function object
printf("%s:%d make function\n", __FILE__, __LINE__);
// Constant* c = mod->getOrInsertFunction
// ("mul_add",
// /*ret type*/ IntegerType::get(32),
// /*args*/ IntegerType::get(32),
// IntegerType::get(32),
// IntegerType::get(32),
// /*varargs terminated with null*/ NULL);
llvm::Constant *c = mod->getOrInsertFunction
("main", // function name
llvm::IntegerType::get(32), // return type
llvm::IntegerType::get(32), // one argument (argc)
NULL // terminate list of varargs
);
llvm::Function *main_function = llvm::cast<llvm::Function>(c);
main_function->setCallingConv(llvm::CallingConv::C);
// make the body of the function
printf("%s:%d make body\n", __FILE__, __LINE__);
llvm::Function::arg_iterator args = main_function->arg_begin();
llvm::Value* arg1 = args++;
arg1->setName("argc");
printf("%s:%d make block\n", __FILE__, __LINE__);
llvm::BasicBlock *block = llvm::BasicBlock::Create("entry", main_function);
llvm::IRBuilder<> builder(block);
builder.CreateRet(arg1);
// verify the module
printf("%s:%d verify\n", __FILE__, __LINE__);
verifyModule(*mod, llvm::PrintMessageAction);
// render the module
printf("%s:%d render\n", __FILE__, __LINE__);
llvm::PassManager PM;
llvm::ModulePass *pmp = llvm::createPrintModulePass(0); // (&llvm::cout);
PM.add(pmp);
PM.run(*mod);
// delete the module
printf("%s:%d delete module\n", __FILE__, __LINE__);
delete mod;
More information about the llvm-dev
mailing list