LLVM API Documentation

LowerAllocations.cpp

Go to the documentation of this file.
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