Insert Instruction in basicblock llvm - llvm

In the following code, I am trying to insertnew global variables in .ll file using Module Pass:
Module::FunctionListType &FList= M.getFunctionList();
LLVMContext &Ctx= M.getContext();
int x=0;
std::string Cbb="BB";
GlobalVariable *bbcounter;
for (Module::FunctionListType::iterator fit=FList.begin();fit!=FList.end();fit++){
for (Function::iterator b = (*fit).begin(), be = (*fit).end(); b != be; ++b){
Cbb= "BB"+std::to_string(x);
const Twine &tw(Cbb);
b->setName (tw);
bbcounter=new GlobalVariable(M,Type::getInt64Ty(b->getContext()),false,GlobalValue::ExternalLinkage,0,Cbb);
assert(bbcounter&&"Error: unable to get basicblock counter");
x++;
}}
The following one is for inserting load/store if the new global variables:
for (Module::FunctionListType::iterator fit=FList.begin();fit!=FList.end();fit++)
{
Function::iterator b = (*fit).begin();
Function::iterator be = (*fit).end();
for ( ; b != be; ++b, git++){ //git is global variable
Instruction *InsertPos=b->getTerminator();
LoadInst* OldVal=new LoadInst( &(*git), Cbb);
OldVal->insertBefore (InsertPos);
Instruction * NewVal= BinaryOperator::Create(Instruction::Add, OldVal, ConstantInt::get(Type::getInt64Ty(b->getContext()), 1), Cbb);
NewVal->insertBefore (InsertPos);
StoreInst *SI=new StoreInst(NewVal, &*git);
SI->insertBefore (InsertPos);
}
This code after make and call opt command does not edit anything in .ll file. I there a problem in it? or should I write new file ?
Note: I tried to write a new file using removeFromParent() function, but it gives me errors. Also, cloning does not set right predecessors.

Related

Writing a LLVM transformation pass to inject delays at the beginning of each function

I am new to LLVM, I am trying to write an LLVM transformation pass that will inject a delay to the beginning of each called function at run time.
I found the following code that injects a printf statement to the beginning of each function.
How can i change the code accordingly to inject a delay instead of the printf? (I am using LLVM 10.)
Below is the code:
bool InjectFuncCall::runOnModule(Module &M) {
bool InsertedAtLeastOnePrintf = false;
auto &CTX = M.getContext();
PointerType *PrintfArgTy = PointerType::getUnqual(Type::getInt8Ty(CTX));
// STEP 1: Inject the declaration of printf
// ----------------------------------------
// Create (or _get_ in cases where it's already available) the following
// declaration in the IR module:
// declare i32 #printf(i8*, ...)
// It corresponds to the following C declaration:
// int printf(char *, ...)
FunctionType *PrintfTy = FunctionType::get(
IntegerType::getInt32Ty(CTX),
PrintfArgTy,
/*IsVarArgs=*/true);
FunctionCallee Printf = M.getOrInsertFunction("printf", PrintfTy);
// Set attributes as per inferLibFuncAttributes in BuildLibCalls.cpp
Function *PrintfF = dyn_cast<Function>(Printf.getCallee());
PrintfF->setDoesNotThrow();
PrintfF->addParamAttr(0, Attribute::NoCapture);
PrintfF->addParamAttr(0, Attribute::ReadOnly);
// STEP 2: Inject a global variable that will hold the printf format string
// ------------------------------------------------------------------------
llvm::Constant *PrintfFormatStr = llvm::ConstantDataArray::getString(
CTX, "(llvm-tutor) Hello from: %s\n(llvm-tutor) number of arguments: %d\n");
Constant *PrintfFormatStrVar =
M.getOrInsertGlobal("PrintfFormatStr", PrintfFormatStr->getType());
dyn_cast<GlobalVariable>(PrintfFormatStrVar)->setInitializer(PrintfFormatStr);
// STEP 3: For each function in the module, inject a call to printf
// ----------------------------------------------------------------
for (auto &F : M) {
if (F.isDeclaration())
continue;
// Get an IR builder. Sets the insertion point to the top of the function
IRBuilder<> Builder(&*F.getEntryBlock().getFirstInsertionPt());
// Inject a global variable that contains the function name
auto FuncName = Builder.CreateGlobalStringPtr(F.getName());
// Printf requires i8*, but PrintfFormatStrVar is an array: [n x i8]. Add
// a cast: [n x i8] -> i8*
llvm::Value *FormatStrPtr =
Builder.CreatePointerCast(PrintfFormatStrVar, PrintfArgTy, "formatStr");
// The following is visible only if you pass -debug on the command line
// *and* you have an assert build.
LLVM_DEBUG(dbgs() << " Injecting call to printf inside " << F.getName()
<< "\n");
// Finally, inject a call to printf
Builder.CreateCall(
Printf, {FormatStrPtr, FuncName, Builder.getInt32(F.arg_size())});
InsertedAtLeastOnePrintf = true;
}
return InsertedAtLeastOnePrintf;
}
Also it would be great if there are links for good LLVM tutorials for beginners.
You'll have to declare the delay function the same way you declared printf except you'll want to change the argument type from i8* to i32. For the tutorials you could check these out
https://anoopsarkar.github.io/compilers-class/llvm-practice.html\
https://www.usna.edu/Users/cs/wcbrown/courses/F19SI413/lab/l13/lab.html
https://osterlund.xyz/posts/2017-11-28-LLVM-pass.html

LLVM IR Array Move with c++ api

I have the following problem with llvm and c++: Given an array, I want to shift every entry of that array by one to the right, i.e., I want to implement the following c code:
int arr[5];
for(int i=1;i<5;++i){
arr[i] = arr[i-1];
}
I tried the following c++ code:
IntegerType *Int32Ty = IntegerType::getInt32Ty(M.getContext(););
GlobalVariable *arrVariable;
arrVariable = new GlobalVariable(M, PointerType::get(Int32Ty, 0), false,
GlobalValue::ExternalLinkage, 0, "__arr");
for(int i=0;i<ARRAY_LENGTH;++i){
Constant* fromIdx = Constant::getIntegerValue(Int32Ty, llvm::APInt(32, i-1));
Value *fromLocPtrIdx = IRB.CreateGEP(arrVariable, fromIdx);
Constant* toIdx = Constant::getIntegerValue(Int32Ty, llvm::APInt(32, i));
Value *toLocPtrIdx = IRB.CreateGEP(arrVariable, toIdx);
StoreInst *MoveStoreInst = IRB.CreateStore(fromLocPtrIdx,toLocPtrIdx);
}
where __arr is defined as:
__thread u32 __arr[ARRAY_LENGTH];
However, when compiling, this yields the following error message:
/usr/bin/ld: __arr: TLS definition in ../inject.o section .tbss mismatches non-TLS reference in /tmp/test-inject.o
What is the right way to move values in an arrays using the llvm c++ api?
You need to specify that your global variable is thread_local.
The way to do that is to add the thread-local mode to your global creation:
arrVariable = new GlobalVariable(M, PointerType::get(Int32Ty, 0), false,
GlobalValue::ExternalLinkage, 0, "__arr", nullptr, InitialExecTLSModel);
The exact mode depends on what your target is, but I think InitialExecTLSModel is a generally "good starting point".

LLVM storing Loop* in std::vector

I've stumbled into something very peculiar - I'm writing an LLVM module Pass. I iterate over all functions of the module and then all loops of every non-declaration function and I store pointers to loops in a std::vector. Here's the source:
virtual bool runOnModule(Module& Mod){
std::vector<Loop*> loops;
// first gather all loop info
for(Module::iterator f = Mod.begin(), fend = Mod.end(); f != fend; ++f){
if (!(*f).isDeclaration()){
LoopInfo& LI = getAnalysis<LoopInfo>(*f);
for(LoopInfo::iterator l = LI.begin(), lend = LI.end(); l != lend; ++l){
loops.push_back(*l);
}
}
}
for (auto& l: loops) errs () << *l << " ";
}
Now if I run this I get a runtime error - it can't print the loops, somehow I'm doing a null pointer dereference or sth. Any ideas?
You have to make sure that the LoopInfo pass actually runs before your pass. Here is a complete example - stanalone from opt:
class AnalyzeLoops : public FunctionPass {
public:
AnalyzeLoops()
: FunctionPass(ID) {}
void getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequired<LoopInfo>();
}
virtual bool runOnFunction(Function &F) {
LoopInfo &LI = getAnalysis<LoopInfo>();
for (LoopInfo::iterator L = LI.begin(), LE = LI.end(); L != LE; ++L) {
(*L)->dump();
}
return false;
}
static char ID;
};
In addition, when creating the passes, do:
PassManager PM;
PM.add(new LoopInfo());
PM.add(new AnalyzeLoops());
PM.run(*Mod);
I suspect that to make opt actually run LoopInfo before your pass, you should pass -loops too.
Also, note that I define getAnalysisUsage - this will make LLVM complain if LoopInfo didn't run before this pass, making the problem more obvious.
Note that LoopInfo is specifically a FunctionPass, and as an analysis it has to be used from another FunctionPass. The LoopInfo data structure doesn't really survive between different functions, and since it owns its data (those Loop* objects) they will be destroyed as well.
One thing you could do if you really need a ModulePass is just invoke LoopInfo manually and not as an analysis. When you iterate the functions in the module, for each function create a new LoopInfo object and use its runOnFunction method. Though even in this case, you have to make sure the LoopInfo that owns a given Loop* survives if you want to use the latter.
First of all LoopInfo should run just once before the for loop.
Secondly LoopInfo::iterator just includes top level loops of the Function. in order to visit all loops you also need to iterate over subloops of every loop. it can be implemented either as recursive function or by WorkList, like this`
virtual bool runOnFunction(Function &F) {
LoopInfo *loopinfo;
loopinfo = &getAnalysis<LoopInfo>();
std::vector<Loop*> allLoops;
for (LoopInfo::iterator Li = loopinfo->begin(), Le = loopinfo->end();
Li != Le; Li++) {
Loop *L = *Li;
allLoops.push_back(L);
dfsOnLoops(L, loopinfo, allLoops);
}
}
void dfsOnLoops(Loop *L, LoopInfo *loopinfo, std::vector<Loop*> LoopS) {
std::vector<Loop *> subloops = L->getSubLoops();
if (subloops.size()) {
// recursive on subloops
for (std::vector<Loop *>::iterator Li = subloops.begin();Li != subloops.end(); Li++){
LoopS.push_back(*Li);
dfsOnLoops(*Li, loopinfo, LoopS);
}
}
}
`
None of the answers really helped but I managed to solve the problem myself. Basically, each llvm pass can define a releaseMemory() method, read more here. The LoopInfo class had that method implemented and thus the analysis information would be lost every time we get out of scope from the call to getAnalysis. I simply removed the releaseMemory() method in Loopinfo.h and the memory was no longer released. Note that this triggered a big change in the codebase and even opt had to be rebuilt so doing this in general is probably a bad idea and this would definitely not be easily accepted as a change to llvm (I speculate, not sure).
I think the best way to solve this is to explicitly create LoopInfo objects and save them. Here is the Code for LLVM 3.5
using LoopInfoType=llvm::LoopInfoBase<llvm::BasicBlock, llvm::Loop>;
std::vector<llvm::Loop*> loopVec;
std::vector<LoopInfoType*> loopInfoVec;
for(llvm::Module::iterator F = M.begin(); F!= M.end(); F++){
//skip declrations
if(F->isDeclaration()){
continue;
}
//TODO that scope problem
llvm::DominatorTree DT = llvm::DominatorTree();
DT.recalculate(*F);
LoopInfoType *loopInfo = new LoopInfoType();
loopInfo->releaseMemory();
loopInfo->Analyze(DT);
loopInfoVec.push_back(loopInfo);
for(llvm::LoopInfo::iterator lit = loopInfo->begin(); lit != loopInfo->end(); lit++){
Loop * L = * lit;
loopVec.push_back(L);
//L->dump();
}
}//for all functions
cin.get();
for(auto loop : loopVec){
std::cout << "loop\n";
loop->dump();
for(llvm::Loop::block_iterator bit = loop->block_begin(); bit != loop->block_end(); bit++){
llvm::BasicBlock * B = * bit;
B->dump();
std::cout << "\n\n";
}
}

LLVM StoreInst and AllocaInst

I am trying to write a simple interpreter.
I am trying to generate LLVM IR for assignment operation. The code for the generation part looks like this
llvm::Value* codeGenSymTab(llvm::LLVMContext& context) {
printf("\n CodeGen SymTab \n");
Value *num = ConstantInt::get(Type::getInt64Ty(context), aTable.value, true);
Value *alloc = new AllocaInst(IntegerType::get(context, 32), aTable.variableName,entry);
StoreInst *ptr = new StoreInst(num,alloc,false,entry);
}
Here goes the SymTab definition:
struct SymTab {
char* variableName;
int value;
llvm::Value* (*codeGen)(llvm::LLVMContext& context);
};
When I try to execute the output file,I get the following error:
Assertion failed: (getOperand(0)->getType() == cast<PointerType>(getOperand(1)->getType())->getElementType() && "Ptr must be a pointer to Val type!"), function AssertOK, file Instructions.cpp, line 1084.
Abort trap: 6
Can you help me resolve it ?
Thanks
You try to store a value of type i64 into an address of type i32*, and these don't match.
You can fix this by using the same type - or preferably, the actual same object:
IntegerType *int_type = Type::getInt64Ty(context);
Value *num = ConstantInt::get(int_type, aTable.value, true);
Value *alloc = new AllocaInst(int_type, aTable.variableName, entry);
StoreInst *ptr = new StoreInst(num,alloc,false,entry);

LLVM IR Function with an array parameter

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