LLVM API Documentation
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 }