1 //===- ChangeAllocations.cpp - Modify %malloc & %free calls -----------------=//
3 // This file defines two passes that convert malloc and free instructions to
4 // calls to and from %malloc & %free function calls. The LowerAllocations
5 // transformation is a target dependant tranformation because it depends on the
6 // size of data types and alignment constraints.
8 //===----------------------------------------------------------------------===//
10 #include "llvm/Transforms/ChangeAllocations.h"
11 #include "llvm/Transforms/Utils/BasicBlockUtils.h"
12 #include "llvm/Module.h"
13 #include "llvm/Function.h"
14 #include "llvm/DerivedTypes.h"
15 #include "llvm/iMemory.h"
16 #include "llvm/iOther.h"
17 #include "llvm/Constants.h"
18 #include "llvm/Pass.h"
19 #include "llvm/Target/TargetData.h"
24 // LowerAllocations - Turn malloc and free instructions into %malloc and %free
27 class LowerAllocations : public BasicBlockPass {
28 Function *MallocFunc; // Functions in the module we are processing
29 Function *FreeFunc; // Initialized by doInitialization
31 const TargetData &DataLayout;
33 inline LowerAllocations(const TargetData &TD) : DataLayout(TD) {
34 MallocFunc = FreeFunc = 0;
37 const char *getPassName() const { return "Lower Allocations"; }
39 // doPassInitialization - For the lower allocations pass, this ensures that a
40 // module contains a declaration for a malloc and a free function.
42 bool doInitialization(Module *M);
44 // runOnBasicBlock - This method does the actual work of converting
45 // instructions over, assuming that the pass has already been initialized.
47 bool runOnBasicBlock(BasicBlock *BB);
50 // RaiseAllocations - Turn %malloc and %free calls into the appropriate
53 class RaiseAllocations : public BasicBlockPass {
54 Function *MallocFunc; // Functions in the module we are processing
55 Function *FreeFunc; // Initialized by doPassInitializationVirt
57 inline RaiseAllocations() : MallocFunc(0), FreeFunc(0) {}
59 const char *getPassName() const { return "Raise Allocations"; }
61 // doPassInitialization - For the raise allocations pass, this finds a
62 // declaration for malloc and free if they exist.
64 bool doInitialization(Module *M);
66 // runOnBasicBlock - This method does the actual work of converting
67 // instructions over, assuming that the pass has already been initialized.
69 bool runOnBasicBlock(BasicBlock *BB);
72 } // end anonymous namespace
74 // doInitialization - For the lower allocations pass, this ensures that a
75 // module contains a declaration for a malloc and a free function.
77 // This function is always successful.
79 bool LowerAllocations::doInitialization(Module *M) {
80 const FunctionType *MallocType =
81 FunctionType::get(PointerType::get(Type::SByteTy),
82 vector<const Type*>(1, Type::UIntTy), false);
83 const FunctionType *FreeType =
84 FunctionType::get(Type::VoidTy,
85 vector<const Type*>(1, PointerType::get(Type::SByteTy)),
88 MallocFunc = M->getOrInsertFunction("malloc", MallocType);
89 FreeFunc = M->getOrInsertFunction("free" , FreeType);
94 // runOnBasicBlock - This method does the actual work of converting
95 // instructions over, assuming that the pass has already been initialized.
97 bool LowerAllocations::runOnBasicBlock(BasicBlock *BB) {
99 assert(MallocFunc && FreeFunc && BB && "Pass not initialized!");
101 // Loop over all of the instructions, looking for malloc or free instructions
102 for (unsigned i = 0; i < BB->size(); ++i) {
103 BasicBlock::InstListType &BBIL = BB->getInstList();
104 if (MallocInst *MI = dyn_cast<MallocInst>(*(BBIL.begin()+i))) {
105 BBIL.remove(BBIL.begin()+i); // remove the malloc instr...
107 const Type *AllocTy = cast<PointerType>(MI->getType())->getElementType();
109 // Get the number of bytes to be allocated for one element of the
111 unsigned Size = DataLayout.getTypeSize(AllocTy);
113 // malloc(type) becomes sbyte *malloc(constint)
114 Value *MallocArg = ConstantUInt::get(Type::UIntTy, Size);
115 if (MI->getNumOperands() && Size == 1) {
116 MallocArg = MI->getOperand(0); // Operand * 1 = Operand
117 } else if (MI->getNumOperands()) {
118 // Multiply it by the array size if neccesary...
119 MallocArg = BinaryOperator::create(Instruction::Mul,MI->getOperand(0),
121 BBIL.insert(BBIL.begin()+i++, cast<Instruction>(MallocArg));
124 // Create the call to Malloc...
125 CallInst *MCall = new CallInst(MallocFunc,
126 vector<Value*>(1, MallocArg));
127 BBIL.insert(BBIL.begin()+i, MCall);
129 // Create a cast instruction to convert to the right type...
130 CastInst *MCast = new CastInst(MCall, MI->getType());
131 BBIL.insert(BBIL.begin()+i+1, MCast);
133 // Replace all uses of the old malloc inst with the cast inst
134 MI->replaceAllUsesWith(MCast);
135 delete MI; // Delete the malloc inst
137 } else if (FreeInst *FI = dyn_cast<FreeInst>(*(BBIL.begin()+i))) {
138 BBIL.remove(BB->getInstList().begin()+i);
140 // Cast the argument to free into a ubyte*...
141 CastInst *MCast = new CastInst(FI->getOperand(0),
142 PointerType::get(Type::UByteTy));
143 BBIL.insert(BBIL.begin()+i, MCast);
145 // Insert a call to the free function...
146 CallInst *FCall = new CallInst(FreeFunc,
147 vector<Value*>(1, MCast));
148 BBIL.insert(BBIL.begin()+i+1, FCall);
150 // Delete the old free instruction
159 bool RaiseAllocations::doInitialization(Module *M) {
160 // If the module has a symbol table, they might be referring to the malloc
161 // and free functions. If this is the case, grab the method pointers that
162 // the module is using.
164 // Lookup %malloc and %free in the symbol table, for later use. If they
165 // don't exist, or are not external, we do not worry about converting calls
166 // to that function into the appropriate instruction.
168 const FunctionType *MallocType = // Get the type for malloc
169 FunctionType::get(PointerType::get(Type::SByteTy),
170 vector<const Type*>(1, Type::UIntTy), false);
172 const FunctionType *FreeType = // Get the type for free
173 FunctionType::get(Type::VoidTy,
174 vector<const Type*>(1, PointerType::get(Type::SByteTy)),
177 MallocFunc = M->getFunction("malloc", MallocType);
178 FreeFunc = M->getFunction("free" , FreeType);
180 // Don't mess with locally defined versions of these functions...
181 if (MallocFunc && !MallocFunc->isExternal()) MallocFunc = 0;
182 if (FreeFunc && !FreeFunc->isExternal()) FreeFunc = 0;
186 // doOneCleanupPass - Do one pass over the input method, fixing stuff up.
188 bool RaiseAllocations::runOnBasicBlock(BasicBlock *BB) {
189 bool Changed = false;
190 BasicBlock::InstListType &BIL = BB->getInstList();
192 for (BasicBlock::iterator BI = BB->begin(); BI != BB->end();) {
193 Instruction *I = *BI;
195 if (CallInst *CI = dyn_cast<CallInst>(I)) {
196 if (CI->getCalledValue() == MallocFunc) { // Replace call to malloc?
197 const Type *PtrSByte = PointerType::get(Type::SByteTy);
198 MallocInst *MallocI = new MallocInst(PtrSByte, CI->getOperand(1),
201 ReplaceInstWithInst(BIL, BI, MallocI);
203 continue; // Skip the ++BI
204 } else if (CI->getCalledValue() == FreeFunc) { // Replace call to free?
205 ReplaceInstWithInst(BIL, BI, new FreeInst(CI->getOperand(1)));
207 continue; // Skip the ++BI
217 Pass *createLowerAllocationsPass(const TargetData &TD) {
218 return new LowerAllocations(TD);
220 Pass *createRaiseAllocationsPass() {
221 return new RaiseAllocations();