I want to make a function in LLVM which is an adapter with only a function call foo(idx, mn). The function prototype of foo is void foo(unsigned char, const char*).
// adapter Function with only a function call foo(idx, mn)
llvm::Function* createCallFun(llvm::Module* M, llvm::Function* exit_f) {
llvm::LLVMContext& Ctx = M->getContext();
llvm::Function* foo_f = foo_prototype(Ctx, M);
llvm::Constant* c = M->getOrInsertFunction("__call_fun", FunctionType::getVoidTy(Ctx), llvm::Type::getInt32Ty(Ctx), llvm::Type::getInt32Ty(Ctx), NULL);
llvm::Function* call_fun_f = llvm::cast<llvm::Function>(c);
llvm::BasicBlock* entry = llvm::BasicBlock::Create(llvm::getGlobalContext(), "entry", call_fun_f);
llvm::IRBuilder<> builder(entry);
llvm::Function::arg_iterator args = call_fun_f->arg_begin();
llvm::Value* idx = &*args++;
idx->setName("idx");
llvm::Value* mn = &*args++;
mn->setName("mn");
llvm::Value* greater = builder.CreateICmpSGE(idx, mn, "tmp");
std::vector<llvm::Value*> fun_args;
fun_args.push_back(greater);
fun_args.push_back(err_msg);
builder.CreateCall(foo_f, fun_args);
return call_fun_f;
}
Then I got this error:
lib/IR/Instructions.cpp:245: void llvm::CallInst::init(llvm::FunctionType*, llvm::Value*, llvm::ArrayRef, llvm::ArrayRef >, const llvm::Twine&): Assertion `(i >= FTy->getNumParams() || FTy->getParamType(i) == Args[i]->getType()) && "Calling a function with a bad signature!"' failed.
It seems the first argument of foo has a type mismatch. How can I cast the Value greater to unsigned char type?
I fixed this error by cast greater with CreateZExt.
llvm::Value *castuchar =
builder.CreateZExt(greater, llvm::Type::getInt8Ty(Ctx), "tmp1");
Related
I want to pass an array to LLVM IR Function, and get value by index. The code as follows, but it dont't work.
Function *FooF =
Function::Create(FunctionType::get(Type::getInt32Ty(Context), {ArrayType::getInt32PtrTy(Context), Type::getInt32Ty(Context)}, false),
Function::ExternalLinkage, "foo", M);
// Add a basic block to the FooF function.
BasicBlock *BB = BasicBlock::Create(Context, "EntryBlock", FooF);
IRBuilder<> builder(BB);
// Get pointer to array
Value *arg1 = FooF->arg_begin();
// Get index
Value *index = arg1+1;
// Get first_element
Value *first_element = builder.CreateExtractElement(arg1, index);
builder.CreateRet(first_element);
// Now we create the JIT.
ExecutionEngine* EE = EngineBuilder(std::move(Owner)).create();
using FunctionPtr = int(*)(int32_t *, int);
FunctionPtr func = reinterpret_cast<FunctionPtr>(EE->getFunctionAddress("foo")) ;
int32_t array[3] = {1,2,3};
int first = func(array, 0);
}
I just started with LLVM. I am using C++ to create a compiler for Pascal-like language. Given that print functions are system calls, how do I map from my language writeln(5) to the system function printf ("%d",5)? I thought that code below should do it.
NamedValues.clear();
vector<Type *> Doubles(1, Type::getInt32Ty(TheContext));
FunctionType * FT = FunctionType::get(Type::getInt32Ty(TheContext), Doubles, false);
Function * function = Function::Create(FT, Function::ExternalLinkage, "writeln", TheModule.get());
// create function body
BasicBlock * BB = BasicBlock::Create(TheContext, "entry", function);
Builder.SetInsertPoint(BB);
// get param
Function::arg_iterator AI = function->arg_begin();
Value * val = AI;
AI->setName("val");
// get format string
string format = "%d";
Constant * ConstStr = ConstantDataArray::getString(TheContext, format.c_str());
ConstStr = new GlobalVariable(*TheModule, ConstStr->getType(), true, GlobalValue::InternalLinkage, ConstStr, format);
Constant * Idxs[] = {ConstantInt::get(Type::getInt32Ty(TheContext), 0), 0};
Idxs[1] = Idxs[0];
// make params
vector<Type *> params;
params.push_back(PointerType::getUnqual(Type::getInt8Ty(TheContext)));
// get printf function
FunctionCallee PrintF = TheModule->getOrInsertFunction("printf", FunctionType::get(Type::getVoidTy(TheContext), params, true));
// call
/*
* CallInst *CreateCall(FunctionCallee Callee, ArrayRef<Value *> Args = None,
const Twine &Name = "", MDNode *FPMathTag = nullptr)
*/
Builder.CreateCall(PrintF.getFunctionType(), ConstantExpr::getGetElementPtr(ConstStr->getType(), ConstStr, Idxs), val);
Builder.CreateRet(Builder.getInt32(0));
main_loop();
Error I got:
Assertion failed: (Ty == cast<PointerType>(C->getType()->getScalarType())->getElementType()), function getGetElementPtr, file /Users/ustynov/Documents/Study/HOMEWORKS/semestralwork/llvm/lib/IR/Constants.cpp, line 2012.
I'm trying to use the LLVM C++ bindings to write a pass which generates the following IR
%1 = call i64 #time(i64* null) #3
#time here is the C standard library time() function.
Here's the code I've written
void Pass::Insert(BasicBlock *bb, Type *timety, Module *m) {
Type *timetype[1];
timetype[0] = timety;
ArrayRef<Type *> timeTypeAref(timetype, 1);
Value *args[1];
args[0] = ConstantInt::get(timety, 0, false);
ArrayRef<Value *> argsRef(args, 1);
FunctionType *signature = FunctionType::get(timety, false);
Function *timeFunc =
Function::Create(signature, Function::ExternalLinkage, "time", m);
IRBuilder<> Builder(&*(bb->getFirstInsertionPt()));
AllocaInst *a1 = Builder.CreateAlloca(timety, nullptr, Twine("a1"));
CallInst *c1 = Builder.CreateCall(timeFunc, args, Twine("time"));
}
This compiles, but results in the following error when run
Incorrect number of arguments passed to called function!
%time = call i64 #time(i64 0)
As I understand this, I need to pass an int64 pointer which deferences to nullptr, but I'm unable to figure out how to do that.
LLVM provides a ConstantPointerNull class which does exactly what I want - it returns a null pointer of the required type.
All that needs to be changed is the line beginning with args[0] = ... to
args[0] = ConstantPointerNull::get(PointerType::get(timety, 0));.
I am working on an example from the LLVM Essentials book. The section is called Emitting if-else condition IR, and I keep getting the following error.
Assertion failed: (getOperand(0)->getType() == getOperand(1)->getType()
&& "Both operands to ICmp instruction are not of the same type!"),
function AssertOK,
file /usr/local/Cellar/llvm/3.6.2/include/llvm/IR/Instructions.h, line
997. Abort trap: 6
I've spent hours trying to figure this out, but I'm at my wit's end. I'm sure it's something minor, but I have no idea. The code I am using is below.
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Verifier.h"
#include <vector>
#include <iostream>
#include <typeinfo>
using namespace llvm;
static LLVMContext &Context = getGlobalContext();
static Module *ModuleOb = new Module("my compiler", Context);
static std::vector<std::string> FunArgs;
typedef SmallVector<BasicBlock *, 16> BBList;
typedef SmallVector<Value *, 16> ValList;
Function *createFunc(IRBuilder<> &Builder, std::string Name) {
std::vector<Type *> Integers(FunArgs.size(), Type::getInt32Ty(Context));
FunctionType *funcType =
llvm::FunctionType::get(Builder.getInt32Ty(), Integers, false);
Function *fooFunc = llvm::Function::Create(
funcType, llvm::Function::ExternalLinkage, Name, ModuleOb);
return fooFunc;
}
void setFuncArgs(Function *fooFunc, std::vector<std::string> FunArgs) {
unsigned Idx = 0;
Function::arg_iterator AI, AE;
for (AI = fooFunc->arg_begin(), AE = fooFunc->arg_end(); AI != AE;
++AI, ++Idx)
AI->setName(FunArgs[Idx]);
}
BasicBlock *createBB(Function *fooFunc, std::string Name) {
return BasicBlock::Create(Context, Name, fooFunc);
}
GlobalVariable *createGlob(IRBuilder<> &Builder, std::string Name) {
ModuleOb->getOrInsertGlobal(Name, Builder.getInt32Ty());
GlobalVariable *gVar = ModuleOb->getNamedGlobal(Name);
gVar->setLinkage(GlobalValue::CommonLinkage);
gVar->setAlignment(4);
return gVar;
}
Value *createArith(IRBuilder<> &Builder, Value *L, Value *R) {
return Builder.CreateMul(L, R, "multmp");
}
Value *createIfElse(IRBuilder<> &Builder, BBList List, ValList VL) {
Value *Condtn = VL[0];
Value *Arg1 = VL[1];
BasicBlock *ThenBB = List[0];
BasicBlock *ElseBB = List[1];
BasicBlock *MergeBB = List[2];
Builder.CreateCondBr(Condtn, ThenBB, ElseBB);
Builder.SetInsertPoint(ThenBB);
Value *ThenVal = Builder.CreateAdd(Arg1, Builder.getInt32(1), "thenaddtmp");
Builder.CreateBr(MergeBB);
Builder.SetInsertPoint(ElseBB);
Value *ElseVal = Builder.CreateAdd(Arg1, Builder.getInt32(2), "elseaddtmp");
Builder.CreateBr(MergeBB);
unsigned PhiBBSize = List.size() - 1;
Builder.SetInsertPoint(MergeBB);
PHINode *Phi = Builder.CreatePHI(Type::getInt32Ty(getGlobalContext()), PhiBBSize, "iftmp");
Phi->addIncoming(ThenVal, ThenBB);
Phi->addIncoming(ElseVal, ElseBB);
return Phi;
}
int main(int argc, char *argv[]) {
FunArgs.push_back("a");
FunArgs.push_back("b");
static IRBuilder<> Builder(Context);
GlobalVariable *gVar = createGlob(Builder, "x");
Function *fooFunc = createFunc(Builder, "foo");
setFuncArgs(fooFunc, FunArgs);
BasicBlock *entry = createBB(fooFunc, "entry");
Builder.SetInsertPoint(entry);
Value *Arg1 = fooFunc->arg_begin();
Value *constant = Builder.getInt32(16);
Value *val = createArith(Builder, Arg1, constant);
Value *val2 = Builder.getInt32(100);
Value *Compare = Builder.CreateICmpULT(val, val2, "cmptmp");
Value *Condtn = Builder.CreateICmpNE(Compare, Builder.getInt32(0), "ifcond");
ValList VL;
VL.push_back(Condtn);
VL.push_back(Arg1);
BasicBlock *ThenBB = createBB(fooFunc, "then");
BasicBlock *ElseBB = createBB(fooFunc, "else");
BasicBlock *MergeBB = createBB(fooFunc, "ifcont");
BBList List;
List.push_back(ThenBB);
List.push_back(ElseBB);
List.push_back(MergeBB);
Value *v = createIfElse(Builder, List, VL);
Builder.CreateRet(v);
verifyFunction(*fooFunc);
ModuleOb->dump();
return 0;
}
I know the issue is occurring at this location. I've tried to dynamically cast both to the same type, but still not compiling.
Value *Condtn = Builder.CreateICmpNE(Compare, Builder.getInt32(0), "ifcond");
The problem is with these two lines:
Value *Compare = Builder.CreateICmpULT(val, val2, "cmptmp");
Value *Condtn = Builder.CreateICmpNE(Compare, Builder.getInt32(0), "ifcond");
The first icmp instruction evaluates to a value of type i1, and you're trying to compare that to a value of type i32.
Your best bet would be to avoid the second icmp altogether, as it's superfluous (it will evaluate to the same value as Compare). Just use Compare as your condition.
Otherwise, you'd have to make sure the types match -- in this case you can just use Builder.getInt1(false) instead of Builder.getInt32(0). More generally you might use Builder.CreateIntCast to insert trunc or zext or sext instructions as needed.
2 Questions:
1. Do i really need to pass parameter to modify/modify_key via member?
2. Why do i have this compilation error
To see the entire code with the error, you can look at http://coliru.stacked-crooked.com/a/d6241361318e1925
the error is
MultiIndex4.h: In member function 'uint32_t CrMultiParameterMultiIndex::ModifyKeyBy(SearchingKey&, ModifyKeyType&) [with SearchingTagType = IMEI_tag, ModifyingTagType = IMEI_tag, SearchingKey = uint32_t, ModifyKeyType = uint32_t]':
MultiIndex4.h:183: instantiated from here
MultiIndex4.h:119: error: no matching function for call to 'boost::multi_index::multi_index_container<UsersKey, UsersKey_indices, std::allocator<UsersKey> >::modify_key(boost::multi_index::detail::bidir_node_iterator<boost::multi_index::detail::ordered_index_node<boost::multi_index::detail::index_node_base<UsersKey, std::allocator<UsersKey> > > >&, boost::function<void ()(uint32_t&)>&)'
*** Errors occurred during this build ***
I have a class CrMultiParameterMultiIndex that hold a multi-index that have 2 indexes.
I tried to create a template function that search only according a part of the key and modify only a part of the key.
This class have a helper function
template <typename TagType,typename SearchingKey>
typename GlobalHash::index<TagType>::type::iterator GetIteratorBy(SearchingKey & key){
return m_pGlobalHash->get<TagType>().find(key) ;
}
and modify function that use it
template <typename SearchingTagType,typename ModifyingTagType,typename SearchingKey,typename ModifyKeyType> uint32_t ModifyKeyBy(SearchingKey & key,ModifyKeyType & pi_Modifykey)
{
uint32_t hRes = 1;
//search for entry by TagType
typedef typename GlobalHash::index<SearchingTagType>::type IndexType;
typename IndexType::iterator it = GetIteratorBy<SearchingTagType>(key);
//entry found
if( it != m_pGlobalHash->get<SearchingTagType>().end() )
{
//Set parameter to modify
hRes = SetParameterKeys<ModifyingTagType>(pi_Modifykey);
if(hRes == 1)
{
//get iteraror to modify
typedef typename GlobalHash::index<ModifyingTagType>::type ModifyIndexType;
typename ModifyIndexType::iterator itToModify = m_pGlobalHash->get<ModifyingTagType>().iterator_to(*it);
boost::function<void( ModifyKeyType &)> f = boost::bind(&CrMultiParameterMultiIndex::ModifyKey<ModifyingTagType, ModifyKeyType >, this, _1);
//modify key failed
if(m_pGlobalHash->modify_key(itToModify , f)==false)
hRes = 0;
}
}
//entry not found
else
hRes = 0;
return hRes;
}
this compile
uint64_t nFromImsi = 1;
uint64_t nToImsi = 1;
m_multiParam.ModifyKeyBy<IMSI_tag,IMSI_tag>( nFromImsi,nToImsi)
but not this
uint32_t nFromImsi = 1;
uint32_t nToImsi = 1;
m_multiParam.ModifyKeyBy<IMEI_tag,IMEI_tag>( nFromImsi,nToImsi)
Why? and how can it compile
and here are the modifiers
template <> inline void CrMultiParameterMultiIndex::ModifyKey<IMEI_tag>( uint32_t & po_Key){po_Key = m_ParameterKeys.IMEI;}
template <> inline void CrMultiParameterMultiIndex::ModifyKey<IMSI_tag>(uint64_t & po_Key){po_Key = m_ParameterKeys.IMSI;}
David,
The problem with
if(m_pGlobalHash->modify_key(itToModify , f)==false)
lies in the fact that m_pGlobalHashis a view to index #0 (order_by_IMSI) and does not accept iterators to view #1 (order_by_IMEI). You can either project iterators or select the appropriate index:
if(m_pGlobalHash->get<ModifyingTagType>().modify_key(itToModify , f)==false)