[LLVMdev] How to place call(s) to functions found in other llvm modules ???
Mian M. Hamayun
mian-muhammad.hamayun at imag.fr
Wed Aug 31 10:00:25 PDT 2011
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>
More information about the llvm-dev
mailing list