Reputation: 1779
#include "llvm/Pass.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Function.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/IR/LegacyPassManager.h"
#include "llvm/IR/InstrTypes.h"
#include "llvm/Transforms/IPO/PassManagerBuilder.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
using namespace llvm;
namespace {
struct replacepass : public FunctionPass {
static char ID;
ReplacePass() : FunctionPass(ID) {}
virtual bool runOnFunction(Function &F) {
AllocaInst* instToReplace = ???
BasicBlock::iterator ii(instToReplace);
ReplaceInstWithInst(instToReplace->getParent()->getInstList(), ii, new AllocaInst(Type::Int32Ty, 0, instToReplace));
return true;
}
};
}
char ReplacePass::ID = 0;
static void registerReplacePass(const PassManagerBuilder &, legacy::PassManagerBase &PM) {
PM.add(new ReplacePass());
}
static RegisterStandardPasses
RegisterMyPass(PassManagerBuilder::EP_EarlyAsPossible, registerReplacePass);
Hi,
I'm trying to understand the LLVM passes but I'm kinda stuck.
I wanted to start with a simple thing, like replacing stack-based memory allocation alloca
with heap-based memory allocation malloc
.
Using GDB I saw that the alloca
instruction doesn't have "a name" so, I think, I can't use the getFunction utility.
Something that came into my mind is searching for the alloca opcode and replacing it with the malloc opcode.
But the LLVM docs is not the best doc I've ever seen so I don't really know if I can do such a thing.
Can you give me some suggestions, please?
EDIT:
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <alloca.h>
using namespace ::std;
void func() {
int *p = (int *)alloca(20);
char *s = (char *)alloca(150);
}
int main (void) {
cout << "Hello, LLVM\n";
char *arr = (char *)malloc(10);
func();
free (arr)
return 0;
}
EDIT 2:
#include "llvm/Pass.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Function.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/IR/LegacyPassManager.h"
#include "llvm/IR/InstrTypes.h"
#include "llvm/Transforms/IPO/PassManagerBuilder.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include <string.h>
using namespace llvm;
namespace {
struct ReplacePass : public FunctionPass {
static char ID;
ReplacePass() : FunctionPass(ID) {}
virtual bool runOnFunction(Function &F) {
// iterate over the basic blocks of a function
for (auto &BB : F) {
// iterate over the instructions of a basic block
for (auto &I : BB) {
if (AllocaInst *CI = dyn_cast<AllocaInst>(&I)) {
if (!((I.getName()).empty()))
{
const char *s = I.getOpcodeName();
if(strcmp(s, "alloca") == 0){
errs().write_escaped(I.getName()) << " is an " << I.getOpcodeName();
errs() << "\n";
}
if(strcmp(s, "malloc") == 0){
errs().write_escaped(I.getName()) << " is a " << I.getOpcodeName();
errs() << "\n";
}
}
}
}
}
return false;
}
};
}
char ReplacePass::ID = 0;
static void registerReplacePass(const PassManagerBuilder &, legacy::PassManagerBase &PM) {
PM.add(new ReplacePass());
}
static RegisterStandardPasses
RegisterMyPass(PassManagerBuilder::EP_EarlyAsPossible, registerReplacePass);
I wrote the above code but it doesn't work because 1) malloc and alloca are both called "alloca" in LLVM and 2) they have the same opcode (26)
Upvotes: 0
Views: 2277
Reputation: 34401
You can iterate on Function
's BasicBlock
s with begin() and on BB's Instruction
s in the same way. Alternatively, you can make your pass to work on BasicBlock
level. When analysing Instruction
use isa<InstType>
to find out its type.
I also find it strange you didn't liked LLVM docs. This manual, for example, was super useful to me.
EDIT:
To see LLVM representation of the code you are working on use CppBackend. Compile your code with clang -march=cpp
and it will produce a C++ source, that make up your code using LLVM API. There you would see how every instruction is created and, therefore, how they differ.
Another useful tool is -emit-llvm
flag with conjuction of -S
flag. Running clang -emit-llvm -S
would produce you an LLVM IR assembly that makes up your code.
Regarding your problem, i think you are misunderstood LLVM's alloca sematics. The AllocaInst
corresponds to, roughly int a=1
in C code. What you are looking for is CallInst
to "alloca" and "malloc" functions.
Upvotes: 1