LLVM API Documentation
00001 //===-- IndMemRemoval.cpp - Remove indirect allocations and frees ----------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // 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 #define DEBUG_TYPE "indmemrem" 00019 #include "llvm/Transforms/IPO.h" 00020 #include "llvm/Pass.h" 00021 #include "llvm/Module.h" 00022 #include "llvm/Instructions.h" 00023 #include "llvm/Type.h" 00024 #include "llvm/DerivedTypes.h" 00025 #include "llvm/ADT/Statistic.h" 00026 #include "llvm/Support/Compiler.h" 00027 using namespace llvm; 00028 00029 STATISTIC(NumBounceSites, "Number of sites modified"); 00030 STATISTIC(NumBounce , "Number of bounce functions created"); 00031 00032 namespace { 00033 class VISIBILITY_HIDDEN IndMemRemPass : public ModulePass { 00034 public: 00035 static char ID; // Pass identification, replacement for typeid 00036 IndMemRemPass() : ModulePass(&ID) {} 00037 00038 virtual bool runOnModule(Module &M); 00039 }; 00040 } // end anonymous namespace 00041 00042 char IndMemRemPass::ID = 0; 00043 static RegisterPass<IndMemRemPass> 00044 X("indmemrem","Indirect Malloc and Free Removal"); 00045 00046 bool IndMemRemPass::runOnModule(Module &M) { 00047 // In theory, all direct calls of malloc and free should be promoted 00048 // to intrinsics. Therefore, this goes through and finds where the 00049 // address of free or malloc are taken and replaces those with bounce 00050 // functions, ensuring that all malloc and free that might happen 00051 // happen through intrinsics. 00052 bool changed = false; 00053 if (Function* F = M.getFunction("free")) { 00054 if (F->isDeclaration() && F->arg_size() == 1 && !F->use_empty()) { 00055 Function* FN = Function::Create(F->getFunctionType(), 00056 GlobalValue::LinkOnceLinkage, 00057 "free_llvm_bounce", &M); 00058 BasicBlock* bb = BasicBlock::Create("entry",FN); 00059 Instruction* R = ReturnInst::Create(bb); 00060 new FreeInst(FN->arg_begin(), R); 00061 ++NumBounce; 00062 NumBounceSites += F->getNumUses(); 00063 F->replaceAllUsesWith(FN); 00064 changed = true; 00065 } 00066 } 00067 if (Function* F = M.getFunction("malloc")) { 00068 if (F->isDeclaration() && F->arg_size() == 1 && !F->use_empty()) { 00069 Function* FN = Function::Create(F->getFunctionType(), 00070 GlobalValue::LinkOnceLinkage, 00071 "malloc_llvm_bounce", &M); 00072 FN->setDoesNotAlias(0); 00073 BasicBlock* bb = BasicBlock::Create("entry",FN); 00074 Instruction* c = CastInst::CreateIntegerCast( 00075 FN->arg_begin(), Type::Int32Ty, false, "c", bb); 00076 Instruction* a = new MallocInst(Type::Int8Ty, c, "m", bb); 00077 ReturnInst::Create(a, bb); 00078 ++NumBounce; 00079 NumBounceSites += F->getNumUses(); 00080 F->replaceAllUsesWith(FN); 00081 changed = true; 00082 } 00083 } 00084 return changed; 00085 } 00086 00087 ModulePass *llvm::createIndMemRemPass() { 00088 return new IndMemRemPass(); 00089 }