Mian M. Hamayun
2011-Aug-31 17:00 UTC
[LLVMdev] How to place call(s) to functions found in other llvm modules ???
Hello Everyone, I am trying to create two modules in LLVM, where first module contains the definition of a function, gcd in this example and another module contains a call to this function. My example is based on the following tutorial, with a few changes. http://llvm.org/releases/2.6/docs/tutorial/JITTutorial2.html When I execute the verifier pass on my modules, it complains that the 'GCDMain' module is malformed and aborts when I try to write this module as a bitcode file. Here is the output of my example. ---------------------------------------------------------------------- Referencing function in another module! %tmp = call i32 @gcd(i32 30, i32 50) Instruction does not dominate all uses! %tmp = call i32 @gcd(i32 30, i32 50) ret i32 %tmp Broken module found, verification continues. Referencing function in another module! %tmp = call i32 @gcd(i32 30, i32 50) Instruction does not dominate all uses! %tmp = call i32 @gcd(i32 30, i32 50) ret i32 %tmp Broken module found, verification continues. Broken module found, verification continues. ; ModuleID = 'GCD' define i32 @gcd(i32 %x, i32 %y) { entry: %tmp = icmp eq i32 %x, %y br i1 %tmp, label %return, label %cond_false return: ; preds = %entry ret i32 %x cond_false: ; preds = %entry %tmp2 = icmp ult i32 %x, %y br i1 %tmp2, label %cond_true, label %cond_false1 cond_true: ; preds = %cond_false %tmp3 = sub i32 %y, %x %tmp4 = call i32 @gcd(i32 %x, i32 %tmp3) ret i32 %tmp4 cond_false1: ; preds = %cond_false %tmp5 = sub i32 %x, %y %tmp6 = call i32 @gcd(i32 %tmp5, i32 %y) ret i32 %tmp6 } ; ModuleID = 'GCDMain' define i32 @main() { EntryBlock: %tmp = call i32 @gcd(i32 30, i32 50) ret i32 %tmp } ModuleMaker2: /home/hamayun/workspace/NaSiK/sw/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp:155: unsigned int llvm::ValueEnumerator::getValueID(const llvm::Value*) const: Assertion `I != ValueMap.end() && "Value not in slotcalculator!"' failed. Aborted ---------------------------------------------------------------------- And here is the source code of my example. ---------------------------------------------------------------------- Module* makeLLVMModule(LLVMContext& Context); Module* makeMainModule(LLVMContext& Context, Module &inMod); static tool_output_file *GetOutputStream(const char *FileName) { std::string error; tool_output_file *FDOut = new tool_output_file(FileName, error, raw_fd_ostream::F_Binary); if (!error.empty()) { errs() << error << '\n'; delete FDOut; return 0; } return FDOut; } int main(int argc, char**argv) { LLVMContext& Context = getGlobalContext(); Module* ModGCD = makeLLVMModule(Context); Module* ModMain = makeMainModule(Context, *ModGCD); OwningPtr<tool_output_file> OutGCD (GetOutputStream("gcd.bc")); if (!OutGCD) return 1; OwningPtr<tool_output_file> OutMain (GetOutputStream("maingcd.bc")); if (!OutMain) return 1; verifyModule(*ModGCD, PrintMessageAction); verifyModule(*ModMain, PrintMessageAction); PassManager PM; PM.add(createPrintModulePass(&outs())); PM.run(*ModGCD); PM.run(*ModMain); WriteBitcodeToFile(ModGCD, OutGCD->os()); WriteBitcodeToFile(ModMain, OutMain->os()); OutGCD->keep(); OutMain->keep(); delete ModGCD; delete ModMain; return 0; } Module* makeMainModule(LLVMContext& Context, Module &inMod) { // Module Construction Module* mod = new Module("GCDMain", Context); FunctionType *FT = FunctionType::get(Type::getInt32Ty(Context), std::vector<const llvm::Type*, std::allocator<const llvm::Type*> > (2, Type::getInt32Ty(Context)), /*not vararg*/false); Constant* c = inMod.getOrInsertFunction("gcd", FT); Function* gcd = cast<Function>(c); FunctionType *FT_Main = FunctionType::get(Type::getInt32Ty(Context), /*not vararg*/false); Function *F_Main = Function::Create(FT_Main, Function::ExternalLinkage, "main", mod); BasicBlock *BB = BasicBlock::Create(Context, "EntryBlock", F_Main); IRBuilder<> builder(BB); Value *Thirty = ConstantInt::get(Type::getInt32Ty(Context), 30); Value *Fifty = ConstantInt::get(Type::getInt32Ty(Context), 50); std::vector<Value*> args; args.push_back(Thirty); args.push_back(Fifty); Value *gcd_val = builder.CreateCall(gcd, args.begin(), args.end(), "tmp"); builder.CreateRet(gcd_val); return mod; } Module* makeLLVMModule(LLVMContext& Context) { // Module Construction Module* mod = new Module("GCD", Context); FunctionType *FT = FunctionType::get(Type::getInt32Ty(Context), std::vector<const llvm::Type*, std::allocator<const llvm::Type*> > (2, Type::getInt32Ty(Context)), /*not vararg*/false); Constant* c = mod->getOrInsertFunction("gcd", FT); Function* gcd = cast<Function>(c); gcd->setLinkage(Function::ExternalLinkage); gcd->setCallingConv(CallingConv::C); Function::arg_iterator args = gcd->arg_begin(); Value* x = args++; x->setName("x"); Value* y = args++; y->setName("y"); BasicBlock* entry = BasicBlock::Create(Context, "entry", gcd); BasicBlock* ret = BasicBlock::Create(Context, "return", gcd); BasicBlock* cond_false = BasicBlock::Create(Context, "cond_false", gcd); BasicBlock* cond_true = BasicBlock::Create(Context, "cond_true", gcd); BasicBlock* cond_false_2 = BasicBlock::Create(Context, "cond_false", gcd); IRBuilder<> builder(entry); Value* xEqualsY = builder.CreateICmpEQ(x, y, "tmp"); builder.CreateCondBr(xEqualsY, ret, cond_false); builder.SetInsertPoint(ret); builder.CreateRet(x); builder.SetInsertPoint(cond_false); Value* xLessThanY = builder.CreateICmpULT(x, y, "tmp"); builder.CreateCondBr(xLessThanY, cond_true, cond_false_2); builder.SetInsertPoint(cond_true); Value* yMinusX = builder.CreateSub(y, x, "tmp"); std::vector<Value*> args1; args1.push_back(x); args1.push_back(yMinusX); Value* recur_1 = builder.CreateCall(gcd, args1.begin(), args1.end(), "tmp"); builder.CreateRet(recur_1); builder.SetInsertPoint(cond_false_2); Value* xMinusY = builder.CreateSub(x, y, "tmp"); std::vector<Value*> args2; args2.push_back(xMinusY); args2.push_back(y); Value* recur_2 = builder.CreateCall(gcd, args2.begin(), args2.end(), "tmp"); builder.CreateRet(recur_2); return mod; } ---------------------------------------------------------------------- I am not sure why its happening or what I am missing ... :( I also tried to search on this topic, but couldn't find similar posts anywhere. Any pointers / suggestions will be highly appreciated. Thanks in advance. -- Hamayun -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 3781 bytes Desc: S/MIME Cryptographic Signature URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20110831/6f4d188c/attachment.bin>
Eli Friedman
2011-Aug-31 17:18 UTC
[LLVMdev] How to place call(s) to functions found in other llvm modules ???
On Wed, Aug 31, 2011 at 10:00 AM, Mian M. Hamayun <mian-muhammad.hamayun at imag.fr> wrote:> Hello Everyone, > > I am trying to create two modules in LLVM, where first module contains the > definition of a function, gcd in this example and another module contains a > call to this function.You can't reference a global in one module in another module. Either stick with one module, or add a declaration of the function in the second module and call that. -Eli
Mian M. Hamayun
2011-Aug-31 17:54 UTC
[LLVMdev] How to place call(s) to functions found in other llvm modules ???
Hi, I tried this as well, using the following line to add function declaration to the caller module. Function::Create(FT, Function::ExternalLinkage, "gcd", mod); Where "FT" is the same as before. And the output produced by the PrintModulePass becomes: ; ModuleID = 'GCDMain' declare i32 @gcd(i32, i32) define i32 @main() { EntryBlock: %tmp = call i32 @gcd(i32 30, i32 50) ret i32 %tmp } But it still fails to WriteBitcodeToFile, and produces the same error as before. I guess I might be missing some attribute, like "extern" in C ... Any Comments? Thanks again for your help, Hamayun On 08/31/2011 07:18 PM, Eli Friedman wrote:> On Wed, Aug 31, 2011 at 10:00 AM, Mian M. Hamayun > <mian-muhammad.hamayun at imag.fr> wrote: >> Hello Everyone, >> >> I am trying to create two modules in LLVM, where first module contains the >> definition of a function, gcd in this example and another module contains a >> call to this function. > > You can't reference a global in one module in another module. Either > stick with one module, or add a declaration of the function in the > second module and call that. > > -Eli >-------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 3781 bytes Desc: S/MIME Cryptographic Signature URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20110831/88b5b64c/attachment.bin>
Maybe Matching Threads
- [LLVMdev] How to place call(s) to functions found in other llvm modules ???
- [LLVMdev] How to place call(s) to functions found in other llvm modules ???
- [LLVMdev] How to place call(s) to functions found in other llvm modules ???
- [LLVMdev] LLVM JIT on a Baremetal x86 Machine !!!
- [LLVMdev] LLVM JIT on a Baremetal x86 Machine !!!