LLVM IR Function with an array parameter - llvm

I want to generate LLVM IR code from two basic c++ functions which are like below.
int newFun2(int x){
int z = x + x;
return z;
}
int newFun(int *y){
int first = y[3]; //How to define it using the LLVM API?
int num = newFun2(first);
return num;
}
My problem is to get an index of the array parameter using the LLVM API. Any ideas ?
Thank you so much
EDITTED
This is my code using the API:
llvm::LLVMContext &context = llvm::getGlobalContext();
llvm::Module *module = new llvm::Module("AST", context);
llvm::IRBuilder<> builder(context);
//newFun2
llvm::FunctionType *newFunc2Type = llvm::FunctionType::get(builder.getInt32Ty(), builder.getInt32Ty(), false);
llvm::Function *newFunc2 = llvm::Function::Create(newFunc2Type, llvm::Function::ExternalLinkage, "newFun2", module);
llvm::Function::arg_iterator argsFun2 = newFunc2->arg_begin();
llvm::Value* x = argsFun2++;
x->setName("x");
llvm::BasicBlock* block = llvm::BasicBlock::Create(context, "entry", newFunc2);
llvm::IRBuilder<> builder2(block);
llvm::Value* tmp = builder2.CreateBinOp(llvm::Instruction::Add,
x, x, "tmp");
builder2.CreateRet(tmp);
//newFun
llvm::FunctionType *newFuncType = llvm::FunctionType::get(builder.getInt32Ty(), builder.getInt32Ty()->getPointerTo(), false);
llvm::Function *newFunc = llvm::Function::Create(newFuncType, llvm::Function::ExternalLinkage, "newFun", module);
llvm::BasicBlock* block2 = llvm::BasicBlock::Create(context, "entry", newFunc);
llvm::IRBuilder<> builder3(block2);
module->dump();
And this is the LLVM IR that is generated :
; ModuleID = 'AST'
define i32 #newFun2(i32 %x) {
entry:
%tmp = add i32 %x, %x
ret i32 %tmp
}
define i32 #newFun(i32*) {
entry:
}
I am stuck on the body of newFun because of the array access.

I think that you first need to understand how the IR should look like. It can be done by peering into the language specification or by using Clang to compile the C code into IR and taking a look at the result.
In any case, the way to access an array element at a given index is either with extractvalue (which only accepts constant indices) or with a gep. Both of these have corresponding constructors / factory methods and IRBuilder methods to construct them, for example
builder.CreateExtractValue(y, 3);
Creating a gep is a little more complicated; I recommend taking a look at the gep guide.
However, a good way to see how to call the LLVM API to create the desired IR is to use llc (one of the LLVM command-line tools) to generate a source file with those calls itself from an IR file, see these two related questions:
Possible to auto-generate llvm c++ api code from LLVM-IR?
Generate LLVM C++ API code as backend

Related

C++ api to convert llvm module to llvm bitcode?

I have this C++ code that creates an llvm module:
Module* makeLLVMModule() {
// Module Construction
Module* mod = new Module("test", getGlobalContext());
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);
Function* mul_add = cast<Function>(c);
mul_add->setCallingConv(CallingConv::C);
Function::arg_iterator args = mul_add->arg_begin();
Value* x = args++;
x->setName("x");
Value* y = args++;
y->setName("y");
Value* z = args++;
z->setName("z");
BasicBlock* block = BasicBlock::Create(getGlobalContext(), "entry", mul_add);
IRBuilder<> builder(block);
Value* tmp = builder.CreateBinOp(Instruction::Mul,
x, y, "tmp");
Value* tmp2 = builder.CreateBinOp(Instruction::Add,
tmp, z, "tmp2");
builder.CreateRet(tmp2);
return mod;
Is there an LLVM C++ api that can output this module (mod) as a bitcode file (IRfile). I want to be able to create my own llvm modules in one C++ program and "save them into bitcode" then deserialise them (using the parseIRfile) into an llvm module once more to be used by another C++ program

LLVM IR C++ API create anonymous global variable

How can I create an anonymous global variable in LLVM IR C++ API?
I can create a named global variable as follows:
GlobalVariable *createGlobalVariable(
Module *module,
Type *type,
std::string name
) {
module->getOrInsertGlobal(name, type);
return module->getNamedGlobal(name);
}
For example:
auto context = new LLVMContext();
auto module = new Module("Module", *context);
auto type = IntegerType::getInt32Ty(*context);
auto globalVariable = createGlobalVariable(
module,
type,
"globalVariableName"
);
auto constantInt = ConstantInt::getIntegerValue(
type,
APInt(32, 42)
);
globalVariable->setInitializer(constantInt);
module->dump();
It will generate:
; ModuleID = 'Module'
source_filename = "Module"
#globalVariableName = global i32 42
How can I create an anonymous global variable?
I would like to generate somethings like:
; ModuleID = 'Module'
source_filename = "Module"
#0 = global i32 42
#0 is a unique identifiers
In comment, #IlCapitano said that Pass "" as name
I try
auto context = new LLVMContext();
auto module = new Module("Module", *context);
auto type = IntegerType::getInt32Ty(*context);
auto constant = module->getOrInsertGlobal("", type);
module->dump();
It generates:
; ModuleID = 'Module'
source_filename = "Module"
#0 = external global i32
But if I set initializer, will be Segmentation fault
auto constant = module->getOrInsertGlobal("", type);
auto anonymousGlobalVariable = module->getNamedGlobal(constant->getName());
anonymousGlobalVariable->setInitializer(constantInt);
// -> Segmentation fault
The correct way is creating GlobalVariable by using constructor:
auto context = new LLVMContext();
auto module = new Module("Module", *context);
auto type = IntegerType::getInt32Ty(*context);
auto constantInt = ConstantInt::getIntegerValue(type, APInt(32, 42));
auto anonymousGlobalVariable = new GlobalVariable(
*module,
type,
false,
GlobalValue::CommonLinkage,
constantInt,
""
);
module->dump();
Nice
; ModuleID = 'Module'
source_filename = "Module"
#0 = common global i32 42
I'm kinda new to the llvm c++ api, but using the llvm toolchain, we can determine how c++ static global variables are represented in llvm ir (assuming your intention is to generate unique identifiers among multiple translation units (i.e. fix name collisions when linking multiple llvm ir files together)).
Given non-static.cpp:
int x = 0;
clang -S -emit-llvm non-static.cpp emits this for our global x:
[...]
#x = dso_local global i32 0, align 4
[...]
Given static.cpp:
static int x = 0;
int main() {
return x; // refer to `x` so llvm doesn't optimize it away
}
clang -S -emit-llvm static.cpp emits this for our global x:
[...]
#_ZL1x = internal global i32 0, align 4
[...]
Note the presence of the internal linkage type.
To set this modifier using the llvm c++ api, you have to call one of GlobalVariable's constructors and pass llvm::GlobalValue::LinkageTypes::InternalLinkage to the Linkage parameter.

getting Data stored in an LLVM variable

I am building a lifter that translates assembly code into LLVM IR. I was wondering if there is a possible way to check the data stored inside an LLVM variable. For example in my code below. I am creating a dummy LLVM function. Inside my function, I have just one basic block where I allocate memory for a single variable SRC and then I store an immediate value of 31 inside that allocated memory. The last step is I loaded from that memory into a variable called loaded.
Is there a way to check that the value of the %loaded variable is in fact 31 ?.
int main()
{
llvm::LLVMContext context;
llvm::Type* type = llvm::Type::getVoidTy(context);
Module* modu = new Module("test", context);
modu->getOrInsertFunction("dummy",type);
Function* dummy = modu->getFunction("dummy");
BasicBlock* block = BasicBlock::Create(context, "entry", dummy);
IRBuilder<> builder(block);
llvm::Value* SRC = builder.CreateAlloca(Type::getInt32Ty(context), nullptr);
llvm::Value* s = builder.CreateStore(llvm::ConstantInt::get(context, llvm::APInt(/*nbits*/32, 31, true)), SRC, /*isVolatile=*/false);
llvm::Value* loaded = builder.CreateLoad(SRC, "loaded");
builder.CreateRetVoid();
PassManager <llvm::Module>PM;
llvm::AnalysisManager <llvm::Module>AM;
verifyFunction(*(modu->getFunction("dummy")), &llvm::errs());
verifyModule(*modu, &llvm::errs());
PassBuilder PB;
PB.registerModuleAnalyses(AM);
PM.addPass(PrintModulePass());
PM.run(*modu, AM);
The output of my code looks like this:
; ModuleID = 'test'
source_filename = "test"
define void #dummy() {
entry:
%0 = alloca i32, align 4
store i32 31, i32* %0, align 4
%loaded = load i32, i32* %0, align 4
ret void
}
You can insert a call to printf and compile this IR into a native executable. Running it will print out the variable value.
Alternatively, you can run lli on this IR under debugger and break on load handler.

LLVM: Creating a CallInst with a null pointer operand

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));.

LLVM. How to access to struct fields based on their names?

I have little example code in C++:
struct RecordTest
{
int value1;
int value2;
};
void test()
{
RecordTest rt;
rt.value1 = 15;
rt.value2 = 75;
}
and LLVM 3.4 IR for it:
%struct.RecordTest = type { i32, i32 }
; Function Attrs: nounwind
define void #_Z4testv() #0 {
entry:
%rt = alloca %struct.RecordTest, align 4
%value1 = getelementptr inbounds %struct.RecordTest* %rt, i32 0, i32 0
store i32 15, i32* %value1, align 4
%value2 = getelementptr inbounds %struct.RecordTest* %rt, i32 0, i32 1
store i32 75, i32* %value2, align 4
ret void
}
and a pretty easy question: How can I access to RecordTest fields (when I parsing .cpp), without their indexes, with only names (value1 and value2)?
I know only one way (from llc -march=cpp) - with indexes:
AllocaInst* ptr_rt = new AllocaInst(StructTy_struct_RecordTest, "rt", label_entry);
ptr_rt->setAlignment(4);
std::vector<Value*> ptr_value1_indices;
ptr_value1_indices.push_back(const_int32_6);
ptr_value1_indices.push_back(const_int32_6);
Instruction* ptr_value1 = GetElementPtrInst::Create(ptr_rt, ptr_value1_indices, "value1", label_entry);
StoreInst* void_9 = new StoreInst(const_int32_7, ptr_value1, false, label_entry);
void_9->setAlignment(4);
std::vector<Value*> ptr_value2_indices;
ptr_value2_indices.push_back(const_int32_6);
ptr_value2_indices.push_back(const_int32_5);
Instruction* ptr_value2 = GetElementPtrInst::Create(ptr_rt, ptr_value2_indices, "value2", label_entry);
StoreInst* void_10 = new StoreInst(const_int32_8, ptr_value2, false, label_entry);
void_10->setAlignment(4);
So, can I translate from C++ to LLVM IR, if I don't know the indexes of the fields (const_int32_5 and const_int32_6 in code above) ?
UPD================================
So, we can't access to field names. And if we need it (and we do, if we parse .cpp),
we can write something like this:
// It can be some kind of singletone
static std::map<std::string, std::vector<std::string>> mymap;
// Some function, where we first time meet RecordTest
std::vector<std::string> fieldNames;
fieldNames.push_back("value1");
fieldNames.push_back("value2");
mymap["RecordTest"] = fieldNames;
// Some function, where we need to access to RecordTest field
std::vector<std::string> fieldNamesAgain = mymap.find("RecordTest")->second;
std::string fieldName = "value1";
int idxValue1 = -1;
for (int i = 0, e = fieldNamesAgain.size(); i < e; i++) // little ugly search
{
if (fieldName == fieldNamesAgain[i])
{
// we get field index, and now we can build code
// as in example above (llc -march=cpp)
idxValue1 = i;
break;
}
}
Is this right ?
You cannot access the fields of the struct by name, only by index. This information is just normally not there when you compile with Clang.
There is one exception to this, and this is if you compiled with debug information. In that case, you'll have ample data about the type; specifically, you'll get the order of the fields, along with a metadata entry for each field which contains its name (and other useful stuff, such as its offset from the beginning of the type).
Read more about this on the Source Level Debugging guide - and particularly, see this section about struct encoding, with its very nice example.
Take a look at DebugInfo.h for classes to help on querying debug info, though I think you're going to have to do some manually digging anyway.