LLVM API Documentation
00001 //===- LowerAllocations.cpp - Reduce malloc & free insts to calls ---------===// 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 // The LowerAllocations transformation is a target-dependent tranformation 00011 // because it depends on the size of data types and alignment constraints. 00012 // 00013 //===----------------------------------------------------------------------===// 00014 00015 #include "llvm/Transforms/Scalar.h" 00016 #include "llvm/Module.h" 00017 #include "llvm/DerivedTypes.h" 00018 #include "llvm/Instructions.h" 00019 #include "llvm/Constants.h" 00020 #include "llvm/Pass.h" 00021 #include "llvm/ADT/Statistic.h" 00022 #include "llvm/Target/TargetData.h" 00023 using namespace llvm; 00024 00025 namespace { 00026 Statistic<> NumLowered("lowerallocs", "Number of allocations lowered"); 00027 00028 /// LowerAllocations - Turn malloc and free instructions into %malloc and 00029 /// %free calls. 00030 /// 00031 class LowerAllocations : public BasicBlockPass { 00032 Function *MallocFunc; // Functions in the module we are processing 00033 Function *FreeFunc; // Initialized by doInitialization 00034 bool LowerMallocArgToInteger; 00035 public: 00036 LowerAllocations(bool LowerToInt = false) 00037 : MallocFunc(0), FreeFunc(0), LowerMallocArgToInteger(LowerToInt) {} 00038 00039 virtual void getAnalysisUsage(AnalysisUsage &AU) const { 00040 AU.addRequired<TargetData>(); 00041 AU.setPreservesCFG(); 00042 } 00043 00044 /// doPassInitialization - For the lower allocations pass, this ensures that 00045 /// a module contains a declaration for a malloc and a free function. 00046 /// 00047 bool doInitialization(Module &M); 00048 00049 virtual bool doInitialization(Function &F) { 00050 return BasicBlockPass::doInitialization(F); 00051 } 00052 00053 /// runOnBasicBlock - This method does the actual work of converting 00054 /// instructions over, assuming that the pass has already been initialized. 00055 /// 00056 bool runOnBasicBlock(BasicBlock &BB); 00057 }; 00058 00059 RegisterOpt<LowerAllocations> 00060 X("lowerallocs", "Lower allocations from instructions to calls"); 00061 } 00062 00063 // createLowerAllocationsPass - Interface to this file... 00064 FunctionPass *llvm::createLowerAllocationsPass(bool LowerMallocArgToInteger) { 00065 return new LowerAllocations(LowerMallocArgToInteger); 00066 } 00067 00068 00069 // doInitialization - For the lower allocations pass, this ensures that a 00070 // module contains a declaration for a malloc and a free function. 00071 // 00072 // This function is always successful. 00073 // 00074 bool LowerAllocations::doInitialization(Module &M) { 00075 const Type *SBPTy = PointerType::get(Type::SByteTy); 00076 MallocFunc = M.getNamedFunction("malloc"); 00077 FreeFunc = M.getNamedFunction("free"); 00078 00079 if (MallocFunc == 0) { 00080 // Prototype malloc as "void* malloc(...)", because we don't know in 00081 // doInitialization whether size_t is int or long. 00082 FunctionType *FT = FunctionType::get(SBPTy,std::vector<const Type*>(),true); 00083 MallocFunc = M.getOrInsertFunction("malloc", FT); 00084 } 00085 if (FreeFunc == 0) 00086 FreeFunc = M.getOrInsertFunction("free" , Type::VoidTy, SBPTy, (Type *)0); 00087 00088 return true; 00089 } 00090 00091 // runOnBasicBlock - This method does the actual work of converting 00092 // instructions over, assuming that the pass has already been initialized. 00093 // 00094 bool LowerAllocations::runOnBasicBlock(BasicBlock &BB) { 00095 bool Changed = false; 00096 assert(MallocFunc && FreeFunc && "Pass not initialized!"); 00097 00098 BasicBlock::InstListType &BBIL = BB.getInstList(); 00099 00100 const TargetData &TD = getAnalysis<TargetData>(); 00101 const Type *IntPtrTy = TD.getIntPtrType(); 00102 00103 // Loop over all of the instructions, looking for malloc or free instructions 00104 for (BasicBlock::iterator I = BB.begin(), E = BB.end(); I != E; ++I) { 00105 if (MallocInst *MI = dyn_cast<MallocInst>(I)) { 00106 const Type *AllocTy = MI->getType()->getElementType(); 00107 00108 // malloc(type) becomes sbyte *malloc(size) 00109 Value *MallocArg; 00110 if (LowerMallocArgToInteger) 00111 MallocArg = ConstantUInt::get(Type::ULongTy, TD.getTypeSize(AllocTy)); 00112 else 00113 MallocArg = ConstantExpr::getSizeOf(AllocTy); 00114 MallocArg = ConstantExpr::getCast(cast<Constant>(MallocArg), IntPtrTy); 00115 00116 if (MI->isArrayAllocation()) { 00117 if (isa<ConstantInt>(MallocArg) && 00118 cast<ConstantInt>(MallocArg)->getRawValue() == 1) { 00119 MallocArg = MI->getOperand(0); // Operand * 1 = Operand 00120 } else if (Constant *CO = dyn_cast<Constant>(MI->getOperand(0))) { 00121 CO = ConstantExpr::getCast(CO, IntPtrTy); 00122 MallocArg = ConstantExpr::getMul(CO, cast<Constant>(MallocArg)); 00123 } else { 00124 Value *Scale = MI->getOperand(0); 00125 if (Scale->getType() != IntPtrTy) 00126 Scale = new CastInst(Scale, IntPtrTy, "", I); 00127 00128 // Multiply it by the array size if necessary... 00129 MallocArg = BinaryOperator::create(Instruction::Mul, Scale, 00130 MallocArg, "", I); 00131 } 00132 } 00133 00134 const FunctionType *MallocFTy = MallocFunc->getFunctionType(); 00135 std::vector<Value*> MallocArgs; 00136 00137 if (MallocFTy->getNumParams() > 0 || MallocFTy->isVarArg()) { 00138 if (MallocFTy->isVarArg()) { 00139 if (MallocArg->getType() != IntPtrTy) 00140 MallocArg = new CastInst(MallocArg, IntPtrTy, "", I); 00141 } else if (MallocFTy->getNumParams() > 0 && 00142 MallocFTy->getParamType(0) != Type::UIntTy) 00143 MallocArg = new CastInst(MallocArg, MallocFTy->getParamType(0), "",I); 00144 MallocArgs.push_back(MallocArg); 00145 } 00146 00147 // If malloc is prototyped to take extra arguments, pass nulls. 00148 for (unsigned i = 1; i < MallocFTy->getNumParams(); ++i) 00149 MallocArgs.push_back(Constant::getNullValue(MallocFTy->getParamType(i))); 00150 00151 // Create the call to Malloc... 00152 CallInst *MCall = new CallInst(MallocFunc, MallocArgs, "", I); 00153 MCall->setTailCall(); 00154 00155 // Create a cast instruction to convert to the right type... 00156 Value *MCast; 00157 if (MCall->getType() != Type::VoidTy) 00158 MCast = new CastInst(MCall, MI->getType(), "", I); 00159 else 00160 MCast = Constant::getNullValue(MI->getType()); 00161 00162 // Replace all uses of the old malloc inst with the cast inst 00163 MI->replaceAllUsesWith(MCast); 00164 I = --BBIL.erase(I); // remove and delete the malloc instr... 00165 Changed = true; 00166 ++NumLowered; 00167 } else if (FreeInst *FI = dyn_cast<FreeInst>(I)) { 00168 const FunctionType *FreeFTy = FreeFunc->getFunctionType(); 00169 std::vector<Value*> FreeArgs; 00170 00171 if (FreeFTy->getNumParams() > 0 || FreeFTy->isVarArg()) { 00172 Value *MCast = FI->getOperand(0); 00173 if (FreeFTy->getNumParams() > 0 && 00174 FreeFTy->getParamType(0) != MCast->getType()) 00175 MCast = new CastInst(MCast, FreeFTy->getParamType(0), "", I); 00176 FreeArgs.push_back(MCast); 00177 } 00178 00179 // If malloc is prototyped to take extra arguments, pass nulls. 00180 for (unsigned i = 1; i < FreeFTy->getNumParams(); ++i) 00181 FreeArgs.push_back(Constant::getNullValue(FreeFTy->getParamType(i))); 00182 00183 // Insert a call to the free function... 00184 (new CallInst(FreeFunc, FreeArgs, "", I))->setTailCall(); 00185 00186 // Delete the old free instruction 00187 I = --BBIL.erase(I); 00188 Changed = true; 00189 ++NumLowered; 00190 } 00191 } 00192 00193 return Changed; 00194 } 00195