I follow 《 Getting Started with LLVM Core Libraries》 to write a custom LLVM IR generator, which generates a bitcode file. The bitcode file can be parsed with llvm-dis
. llvm 3.4 used in the book is outdated, I used llvm 3.9.1 instead. After struggling several compilication error, the project is compiled successfully Finally. The code (omit header files for shorter code) works finally is below:
int main()
{
LLVMContext context;
Module *mod = new Module("sum.ll",context);
SmallVector<Type*,2> FuncTyArgs;
FuncTyArgs.push_back(IntegerType::get(mod->getContext(),32));
FuncTyArgs.push_back(IntegerType::get(mod->getContext(),32));
FunctionType *FuncTy = FunctionType::get(IntegerType::get(mod->getContext(),32),
FuncTyArgs,
false);
Function *funcSum = Function::Create(FuncTy,
GlobalValue::ExternalLinkage,
"sum",
mod
);
funcSum->setCallingConv(CallingConv::C);
Function::arg_iterator args = funcSum->arg_begin();
Argument *arg_a = &(*args);
args++;
Value *int32_a = arg_a;
int32_a->setName("a");
Value *int32_b = &(*args);
int32_b->setName("b");
BasicBlock *labelEntry = BasicBlock::Create(mod->getContext(),
"entry",
funcSum,
0);
AllocaInst *ptrA = new AllocaInst(IntegerType::get(mod->getContext(),32),
"a.addr",labelEntry);
ptrA->setAlignment(4);
AllocaInst *ptrB = new AllocaInst(IntegerType::get(mod->getContext(),32),
"b.addr",labelEntry);
ptrB->setAlignment(4);
StoreInst *st0 = new StoreInst(int32_a, ptrA, false,
labelEntry);
st0->setAlignment(4);
StoreInst *st1 = new StoreInst(int32_b, ptrB, false,
labelEntry);
st1->setAlignment(4);
LoadInst *ld0 = new LoadInst(ptrA, "", false,
labelEntry);
ld0->setAlignment(4);
LoadInst *ld1 = new LoadInst(ptrB, "", false,
labelEntry);
ld1->setAlignment(4);
BinaryOperator *addRes =
BinaryOperator::Create(Instruction::Add, ld0, ld1,
"add", labelEntry);
ReturnInst::Create(mod->getContext(),addRes,labelEntry);
std::string error_str;
raw_string_ostream error_stream(error_str);
bool fail = verifyModule(*mod,&error_stream);
if(!fail)
{
std::cout <<"Module is valid.\n";
}else{
std::cerr << "Module is invalid: " << error_str << std::endl;
return 1;
}
std::error_code EC;
std::unique_ptr<tool_output_file> Out(new tool_output_file("./sum.bc",
EC,sys::fs::F_None));
if (EC)
{
errs() << "Error open file:"<<EC.message() << "\n";
return 1;
}
raw_fd_ostream file("sum.bc", EC, sys::fs::F_None);
WriteBitcodeToFile(mod,file);
Out->keep();
return 0;
}
if I move code related to IR build, I can compile it successfully. But an segment fault occurs in running-time.
$ ./getsumll [13:32:22]
[1] 2283352 segmentation fault ./getsumll
How strange? I don’t modify any code, just encapsulate them into a new function(It‘s also the way used in the book). the new code is below
Module* makeLLVMModule(){
LLVMContext context;
Module *mod = new Module("sum.ll",context);
SmallVector<Type*,2> FuncTyArgs;
FuncTyArgs.push_back(IntegerType::get(mod->getContext(),32));
FuncTyArgs.push_back(IntegerType::get(mod->getContext(),32));
FunctionType *FuncTy = FunctionType::get(IntegerType::get(mod->getContext(),32),
FuncTyArgs,
false);
Function *funcSum = Function::Create(FuncTy,
GlobalValue::ExternalLinkage,
"sum",
mod
);
funcSum->setCallingConv(CallingConv::C);
Function::arg_iterator args = funcSum->arg_begin();
Argument *arg_a = &(*args);
args++;
Value *int32_a = arg_a;
int32_a->setName("a");
Value *int32_b = &(*args);
int32_b->setName("b");
BasicBlock *labelEntry = BasicBlock::Create(mod->getContext(),
"entry",
funcSum,
0);
AllocaInst *ptrA = new AllocaInst(IntegerType::get(mod->getContext(),32),
"a.addr",labelEntry);
ptrA->setAlignment(4);
AllocaInst *ptrB = new AllocaInst(IntegerType::get(mod->getContext(),32),
"b.addr",labelEntry);
ptrB->setAlignment(4);
StoreInst *st0 = new StoreInst(int32_a, ptrA, false,
labelEntry);
st0->setAlignment(4);
StoreInst *st1 = new StoreInst(int32_b, ptrB, false,
labelEntry);
st1->setAlignment(4);
LoadInst *ld0 = new LoadInst(ptrA, "", false,
labelEntry);
ld0->setAlignment(4);
LoadInst *ld1 = new LoadInst(ptrB, "", false,
labelEntry);
ld1->setAlignment(4);
BinaryOperator *addRes =
BinaryOperator::Create(Instruction::Add, ld0, ld1,
"add", labelEntry);
ReturnInst::Create(mod->getContext(),addRes,labelEntry);
return mod;
}
int main()
{
Module *mod = makeLLVMModule();//get return value from MakeLLVMModule
std::string error_str;
raw_string_ostream error_stream(error_str);
bool fail = verifyModule(*mod,&error_stream);
if(!fail)
{
std::cout <<"Module is valid.\n";
}else{
std::cerr << "Module is invalid: " << error_str << std::endl;
return 1;
}
std::error_code EC;
std::unique_ptr<tool_output_file> Out(new tool_output_file("./sum.bc",
EC,sys::fs::F_None));
if (EC)
{
errs() << "Error open file:"<<EC.message() << "\n";
return 1;
}
raw_fd_ostream file("sum.bc", EC, sys::fs::F_None);
WriteBitcodeToFile(mod,file);
Out->keep();
return 0;
}
Any help will be appreciated!