#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)