c++ - llvm function pass ReplaceInstWithInst malloc -
#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 understand llvm passes i'm kinda stuck.
i wanted start simple thing, replacing stack-based memory allocation alloca
heap-based memory allocation malloc
.
using gdb saw alloca
instruction doesn't have "a name" so, think, can't use getfunction utility.
something came mind searching alloca opcode , replacing malloc opcode.
but llvm docs not best doc i've ever seen don't know if can such thing.
can give me 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 on basic blocks of function (auto &bb : f) { // iterate on instructions of basic block (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()) << " " << i.getopcodename(); errs() << "\n"; } if(strcmp(s, "malloc") == 0){ errs().write_escaped(i.getname()) << " " << 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 above code doesn't work because 1) malloc , alloca both called "alloca" in llvm , 2) have same opcode (26)
you can iterate on function
's basicblock
s begin() , on bb's instruction
s in same way. alternatively, can make pass work on basicblock
level. when analysing instruction
use isa<insttype>
find out type.
i find strange didn't liked llvm docs. this manual, example, super useful me.
edit:
to see llvm representation of code working on use cppbackend. compile code clang -march=cpp
, produce c++ source, make code using llvm api. there see how every instruction created and, therefore, how differ.
another useful tool -emit-llvm
flag conjuction of -s
flag. running clang -emit-llvm -s
produce llvm ir assembly makes code.
regarding problem, think misunderstood llvm's alloca sematics. allocainst
corresponds to, int a=1
in c code. looking callinst
"alloca" , "malloc" functions.
Comments
Post a Comment