LLVM API Documentation
00001 //===- RaiseAllocations.cpp - Convert %malloc & %free calls to insts ------===// 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 file defines the RaiseAllocations pass which convert malloc and free 00011 // calls to malloc and free instructions. 00012 // 00013 //===----------------------------------------------------------------------===// 00014 00015 #include "llvm/Transforms/IPO.h" 00016 #include "llvm/Constants.h" 00017 #include "llvm/DerivedTypes.h" 00018 #include "llvm/Module.h" 00019 #include "llvm/Instructions.h" 00020 #include "llvm/Pass.h" 00021 #include "llvm/Support/CallSite.h" 00022 #include "llvm/ADT/Statistic.h" 00023 using namespace llvm; 00024 00025 namespace { 00026 Statistic<> NumRaised("raiseallocs", "Number of allocations raised"); 00027 00028 // RaiseAllocations - Turn %malloc and %free calls into the appropriate 00029 // instruction. 00030 // 00031 class RaiseAllocations : public ModulePass { 00032 Function *MallocFunc; // Functions in the module we are processing 00033 Function *FreeFunc; // Initialized by doPassInitializationVirt 00034 public: 00035 RaiseAllocations() : MallocFunc(0), FreeFunc(0) {} 00036 00037 // doPassInitialization - For the raise allocations pass, this finds a 00038 // declaration for malloc and free if they exist. 00039 // 00040 void doInitialization(Module &M); 00041 00042 // run - This method does the actual work of converting instructions over. 00043 // 00044 bool runOnModule(Module &M); 00045 }; 00046 00047 RegisterOpt<RaiseAllocations> 00048 X("raiseallocs", "Raise allocations from calls to instructions"); 00049 } // end anonymous namespace 00050 00051 00052 // createRaiseAllocationsPass - The interface to this file... 00053 ModulePass *llvm::createRaiseAllocationsPass() { 00054 return new RaiseAllocations(); 00055 } 00056 00057 00058 // If the module has a symbol table, they might be referring to the malloc and 00059 // free functions. If this is the case, grab the method pointers that the 00060 // module is using. 00061 // 00062 // Lookup %malloc and %free in the symbol table, for later use. If they don't 00063 // exist, or are not external, we do not worry about converting calls to that 00064 // function into the appropriate instruction. 00065 // 00066 void RaiseAllocations::doInitialization(Module &M) { 00067 const FunctionType *MallocType = // Get the type for malloc 00068 FunctionType::get(PointerType::get(Type::SByteTy), 00069 std::vector<const Type*>(1, Type::ULongTy), false); 00070 00071 const FunctionType *FreeType = // Get the type for free 00072 FunctionType::get(Type::VoidTy, 00073 std::vector<const Type*>(1, PointerType::get(Type::SByteTy)), 00074 false); 00075 00076 // Get Malloc and free prototypes if they exist! 00077 MallocFunc = M.getFunction("malloc", MallocType); 00078 FreeFunc = M.getFunction("free" , FreeType); 00079 00080 // Check to see if the prototype is wrong, giving us sbyte*(uint) * malloc 00081 // This handles the common declaration of: 'void *malloc(unsigned);' 00082 if (MallocFunc == 0) { 00083 MallocType = FunctionType::get(PointerType::get(Type::SByteTy), 00084 std::vector<const Type*>(1, Type::UIntTy), false); 00085 MallocFunc = M.getFunction("malloc", MallocType); 00086 } 00087 00088 // Check to see if the prototype is missing, giving us sbyte*(...) * malloc 00089 // This handles the common declaration of: 'void *malloc();' 00090 if (MallocFunc == 0) { 00091 MallocType = FunctionType::get(PointerType::get(Type::SByteTy), 00092 std::vector<const Type*>(), true); 00093 MallocFunc = M.getFunction("malloc", MallocType); 00094 } 00095 00096 // Check to see if the prototype was forgotten, giving us void (...) * free 00097 // This handles the common forward declaration of: 'void free();' 00098 if (FreeFunc == 0) { 00099 FreeType = FunctionType::get(Type::VoidTy, std::vector<const Type*>(),true); 00100 FreeFunc = M.getFunction("free", FreeType); 00101 } 00102 00103 // One last try, check to see if we can find free as 'int (...)* free'. This 00104 // handles the case where NOTHING was declared. 00105 if (FreeFunc == 0) { 00106 FreeType = FunctionType::get(Type::IntTy, std::vector<const Type*>(),true); 00107 FreeFunc = M.getFunction("free", FreeType); 00108 } 00109 00110 // Don't mess with locally defined versions of these functions... 00111 if (MallocFunc && !MallocFunc->isExternal()) MallocFunc = 0; 00112 if (FreeFunc && !FreeFunc->isExternal()) FreeFunc = 0; 00113 } 00114 00115 // run - Transform calls into instructions... 00116 // 00117 bool RaiseAllocations::runOnModule(Module &M) { 00118 // Find the malloc/free prototypes... 00119 doInitialization(M); 00120 00121 bool Changed = false; 00122 00123 // First, process all of the malloc calls... 00124 if (MallocFunc) { 00125 std::vector<User*> Users(MallocFunc->use_begin(), MallocFunc->use_end()); 00126 std::vector<Value*> EqPointers; // Values equal to MallocFunc 00127 while (!Users.empty()) { 00128 User *U = Users.back(); 00129 Users.pop_back(); 00130 00131 if (Instruction *I = dyn_cast<Instruction>(U)) { 00132 CallSite CS = CallSite::get(I); 00133 if (CS.getInstruction() && CS.arg_begin() != CS.arg_end() && 00134 (CS.getCalledFunction() == MallocFunc || 00135 std::find(EqPointers.begin(), EqPointers.end(), 00136 CS.getCalledValue()) != EqPointers.end())) { 00137 00138 Value *Source = *CS.arg_begin(); 00139 00140 // If no prototype was provided for malloc, we may need to cast the 00141 // source size. 00142 if (Source->getType() != Type::UIntTy) 00143 Source = new CastInst(Source, Type::UIntTy, "MallocAmtCast", I); 00144 00145 std::string Name(I->getName()); I->setName(""); 00146 MallocInst *MI = new MallocInst(Type::SByteTy, Source, Name, I); 00147 I->replaceAllUsesWith(MI); 00148 00149 // If the old instruction was an invoke, add an unconditional branch 00150 // before the invoke, which will become the new terminator. 00151 if (InvokeInst *II = dyn_cast<InvokeInst>(I)) 00152 new BranchInst(II->getNormalDest(), I); 00153 00154 // Delete the old call site 00155 MI->getParent()->getInstList().erase(I); 00156 Changed = true; 00157 ++NumRaised; 00158 } 00159 } else if (GlobalValue *GV = dyn_cast<GlobalValue>(U)) { 00160 Users.insert(Users.end(), GV->use_begin(), GV->use_end()); 00161 EqPointers.push_back(GV); 00162 } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(U)) { 00163 if (CE->getOpcode() == Instruction::Cast) { 00164 Users.insert(Users.end(), CE->use_begin(), CE->use_end()); 00165 EqPointers.push_back(CE); 00166 } 00167 } 00168 } 00169 } 00170 00171 // Next, process all free calls... 00172 if (FreeFunc) { 00173 std::vector<User*> Users(FreeFunc->use_begin(), FreeFunc->use_end()); 00174 std::vector<Value*> EqPointers; // Values equal to FreeFunc 00175 00176 while (!Users.empty()) { 00177 User *U = Users.back(); 00178 Users.pop_back(); 00179 00180 if (Instruction *I = dyn_cast<Instruction>(U)) { 00181 CallSite CS = CallSite::get(I); 00182 if (CS.getInstruction() && CS.arg_begin() != CS.arg_end() && 00183 (CS.getCalledFunction() == FreeFunc || 00184 std::find(EqPointers.begin(), EqPointers.end(), 00185 CS.getCalledValue()) != EqPointers.end())) { 00186 00187 // If no prototype was provided for free, we may need to cast the 00188 // source pointer. This should be really uncommon, but it's necessary 00189 // just in case we are dealing with weird code like this: 00190 // free((long)ptr); 00191 // 00192 Value *Source = *CS.arg_begin(); 00193 if (!isa<PointerType>(Source->getType())) 00194 Source = new CastInst(Source, PointerType::get(Type::SByteTy), 00195 "FreePtrCast", I); 00196 new FreeInst(Source, I); 00197 00198 // If the old instruction was an invoke, add an unconditional branch 00199 // before the invoke, which will become the new terminator. 00200 if (InvokeInst *II = dyn_cast<InvokeInst>(I)) 00201 new BranchInst(II->getNormalDest(), I); 00202 00203 // Delete the old call site 00204 if (I->getType() != Type::VoidTy) 00205 I->replaceAllUsesWith(UndefValue::get(I->getType())); 00206 I->eraseFromParent(); 00207 Changed = true; 00208 ++NumRaised; 00209 } 00210 } else if (GlobalValue *GV = dyn_cast<GlobalValue>(U)) { 00211 Users.insert(Users.end(), GV->use_begin(), GV->use_end()); 00212 EqPointers.push_back(GV); 00213 } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(U)) { 00214 if (CE->getOpcode() == Instruction::Cast) { 00215 Users.insert(Users.end(), CE->use_begin(), CE->use_end()); 00216 EqPointers.push_back(CE); 00217 } 00218 } 00219 } 00220 } 00221 00222 return Changed; 00223 }