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