LLVM API Documentation

IndMemRemoval.cpp

Go to the documentation of this file.
00001 //===-- IndMemRemoval.cpp - Remove indirect allocations and frees ----------===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file was developed by the LLVM research group and is distributed under
00006 // the University of Illinois Open Source License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This pass finds places where memory allocation functions may escape into
00011 // indirect land.  Some transforms are much easier (aka possible) only if free 
00012 // or malloc are not called indirectly.
00013 // Thus find places where the address of memory functions are taken and construct
00014 // bounce functions with direct calls of those functions.
00015 //
00016 //===----------------------------------------------------------------------===//
00017 
00018 #include "llvm/Transforms/IPO.h"
00019 #include "llvm/Pass.h"
00020 #include "llvm/Module.h"
00021 #include "llvm/Function.h"
00022 #include "llvm/Instructions.h"
00023 #include "llvm/Type.h"
00024 #include "llvm/Support/Debug.h"
00025 #include "llvm/ADT/Statistic.h"
00026 #include <fstream>
00027 #include <iostream>
00028 #include <set>
00029 using namespace llvm;
00030 
00031 namespace {
00032   Statistic<> NumBounceSites("indmemrem", "Number of sites modified");
00033   Statistic<> NumBounce  ("indmemrem", "Number of bounce functions created");
00034 
00035   class IndMemRemPass : public ModulePass {
00036 
00037   public:
00038     IndMemRemPass();
00039     virtual bool runOnModule(Module &M);
00040   };
00041   RegisterOpt<IndMemRemPass> X("indmemrem", "Indirect Malloc and Free Removal");
00042 } // end anonymous namespace
00043 
00044 
00045 IndMemRemPass::IndMemRemPass()
00046 {
00047 }
00048 
00049 bool IndMemRemPass::runOnModule(Module &M) {
00050   //in Theory, all direct calls of malloc and free should be promoted
00051   //to intrinsics.  Therefor, this goes through and finds where the
00052   //address of free or malloc are taken and replaces those with bounce
00053   //functions, ensuring that all malloc and free that might happen
00054   //happen through intrinsics.
00055   bool changed = false;
00056   if (Function* F = M.getNamedFunction("free")) {
00057     assert(F->isExternal() && "free not external?");
00058     if (!F->use_empty()) {
00059       Function* FN = new Function(F->getFunctionType(), 
00060           GlobalValue::LinkOnceLinkage, 
00061           "free_llvm_bounce", &M);
00062       BasicBlock* bb = new BasicBlock("entry",FN);
00063       Instruction* R = new ReturnInst(bb);
00064       new FreeInst(FN->arg_begin(), R);
00065       ++NumBounce;
00066       NumBounceSites += F->getNumUses();
00067       F->replaceAllUsesWith(FN);
00068       changed = true;
00069     }
00070   }
00071   if (Function* F = M.getNamedFunction("malloc")) {
00072     assert(F->isExternal() && "malloc not external?");
00073     if (!F->use_empty()) {
00074       Function* FN = new Function(F->getFunctionType(), 
00075           GlobalValue::LinkOnceLinkage, 
00076           "malloc_llvm_bounce", &M);
00077       BasicBlock* bb = new BasicBlock("entry",FN);
00078       Instruction* c = new CastInst(FN->arg_begin(), Type::UIntTy, "c", bb);
00079       Instruction* a = new MallocInst(Type::SByteTy, c, "m", bb);
00080       Instruction* R = new ReturnInst(a, bb);
00081       ++NumBounce;
00082       NumBounceSites += F->getNumUses();
00083       F->replaceAllUsesWith(FN);
00084       changed = true;
00085     }
00086   }
00087   return changed;
00088 }
00089 
00090 ModulePass *llvm::createIndMemRemPass() {
00091   return new IndMemRemPass();
00092 }