blob: c6cb81f0f52a6f4defa60b62bc19c7dd4d67f549 [file] [log] [blame]
Chris Lattner4f0f0972002-01-22 00:13:51 +00001//===- ChangeAllocations.cpp - Modify %malloc & %free calls -----------------=//
Chris Lattner1bb5f8e2001-10-15 17:31:51 +00002//
Chris Lattner4f0f0972002-01-22 00:13:51 +00003// 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.
Chris Lattner1bb5f8e2001-10-15 17:31:51 +00007//
8//===----------------------------------------------------------------------===//
9
Chris Lattner3787ee62002-01-22 01:04:08 +000010#include "llvm/Transforms/ChangeAllocations.h"
Chris Lattner1bb5f8e2001-10-15 17:31:51 +000011#include "llvm/Target/TargetData.h"
Chris Lattnerd5d56782002-01-31 00:45:11 +000012#include "llvm/Module.h"
Chris Lattner06be1802002-04-09 19:08:28 +000013#include "llvm/Function.h"
Chris Lattner1bb5f8e2001-10-15 17:31:51 +000014#include "llvm/DerivedTypes.h"
15#include "llvm/iMemory.h"
16#include "llvm/iOther.h"
Chris Lattnerca142372002-04-28 19:55:58 +000017#include "llvm/Constants.h"
Chris Lattner04805fa2002-02-26 21:46:54 +000018#include "llvm/Pass.h"
Chris Lattner4f0f0972002-01-22 00:13:51 +000019#include "TransformInternals.h"
Chris Lattner7f74a562002-01-20 22:54:45 +000020using std::vector;
21
Chris Lattner04805fa2002-02-26 21:46:54 +000022namespace {
23
24// LowerAllocations - Turn malloc and free instructions into %malloc and %free
25// calls.
26//
27class LowerAllocations : public BasicBlockPass {
Chris Lattner57698e22002-03-26 18:01:55 +000028 Function *MallocFunc; // Functions in the module we are processing
29 Function *FreeFunc; // Initialized by doInitialization
Chris Lattner04805fa2002-02-26 21:46:54 +000030
31 const TargetData &DataLayout;
32public:
33 inline LowerAllocations(const TargetData &TD) : DataLayout(TD) {
Chris Lattner57698e22002-03-26 18:01:55 +000034 MallocFunc = FreeFunc = 0;
Chris Lattner04805fa2002-02-26 21:46:54 +000035 }
36
Chris Lattner37104aa2002-04-29 14:57:45 +000037 const char *getPassName() const { return "Lower Allocations"; }
38
Chris Lattner04805fa2002-02-26 21:46:54 +000039 // doPassInitialization - For the lower allocations pass, this ensures that a
40 // module contains a declaration for a malloc and a free function.
41 //
42 bool doInitialization(Module *M);
43
44 // runOnBasicBlock - This method does the actual work of converting
45 // instructions over, assuming that the pass has already been initialized.
46 //
47 bool runOnBasicBlock(BasicBlock *BB);
48};
49
50// RaiseAllocations - Turn %malloc and %free calls into the appropriate
51// instruction.
52//
53class RaiseAllocations : public BasicBlockPass {
Chris Lattner57698e22002-03-26 18:01:55 +000054 Function *MallocFunc; // Functions in the module we are processing
55 Function *FreeFunc; // Initialized by doPassInitializationVirt
Chris Lattner04805fa2002-02-26 21:46:54 +000056public:
Chris Lattner57698e22002-03-26 18:01:55 +000057 inline RaiseAllocations() : MallocFunc(0), FreeFunc(0) {}
Chris Lattner04805fa2002-02-26 21:46:54 +000058
Chris Lattner37104aa2002-04-29 14:57:45 +000059 const char *getPassName() const { return "Raise Allocations"; }
60
Chris Lattner04805fa2002-02-26 21:46:54 +000061 // doPassInitialization - For the raise allocations pass, this finds a
62 // declaration for malloc and free if they exist.
63 //
64 bool doInitialization(Module *M);
65
66 // runOnBasicBlock - This method does the actual work of converting
67 // instructions over, assuming that the pass has already been initialized.
68 //
69 bool runOnBasicBlock(BasicBlock *BB);
70};
71
72} // end anonymous namespace
Chris Lattner1bb5f8e2001-10-15 17:31:51 +000073
Chris Lattner0686e432002-01-21 07:31:50 +000074// doInitialization - For the lower allocations pass, this ensures that a
Chris Lattner1bb5f8e2001-10-15 17:31:51 +000075// module contains a declaration for a malloc and a free function.
76//
77// This function is always successful.
78//
Chris Lattner0686e432002-01-21 07:31:50 +000079bool LowerAllocations::doInitialization(Module *M) {
Chris Lattnerc13563d2002-03-29 03:38:05 +000080 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)),
86 false);
Chris Lattner1bb5f8e2001-10-15 17:31:51 +000087
Chris Lattnerc13563d2002-03-29 03:38:05 +000088 MallocFunc = M->getOrInsertFunction("malloc", MallocType);
89 FreeFunc = M->getOrInsertFunction("free" , FreeType);
Chris Lattner1bb5f8e2001-10-15 17:31:51 +000090
Chris Lattnerc13563d2002-03-29 03:38:05 +000091 return false;
Chris Lattner1bb5f8e2001-10-15 17:31:51 +000092}
93
Chris Lattnerd07471d2002-01-21 23:34:02 +000094// runOnBasicBlock - This method does the actual work of converting
Chris Lattner1bb5f8e2001-10-15 17:31:51 +000095// instructions over, assuming that the pass has already been initialized.
96//
Chris Lattnerd07471d2002-01-21 23:34:02 +000097bool LowerAllocations::runOnBasicBlock(BasicBlock *BB) {
Chris Lattner6fea0322001-10-18 05:27:33 +000098 bool Changed = false;
Chris Lattner57698e22002-03-26 18:01:55 +000099 assert(MallocFunc && FreeFunc && BB && "Pass not initialized!");
Chris Lattner1bb5f8e2001-10-15 17:31:51 +0000100
101 // Loop over all of the instructions, looking for malloc or free instructions
Chris Lattnerd07471d2002-01-21 23:34:02 +0000102 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...
Chris Lattner1bb5f8e2001-10-15 17:31:51 +0000106
Chris Lattnerd07471d2002-01-21 23:34:02 +0000107 const Type *AllocTy =cast<PointerType>(MI->getType())->getElementType();
108
109 // Get the number of bytes to be allocated for one element of the
110 // requested type...
111 unsigned Size = DataLayout.getTypeSize(AllocTy);
112
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),
120 MallocArg);
121 BBIL.insert(BBIL.begin()+i++, cast<Instruction>(MallocArg));
Chris Lattner1bb5f8e2001-10-15 17:31:51 +0000122 }
Chris Lattnerd07471d2002-01-21 23:34:02 +0000123
124 // Create the call to Malloc...
Chris Lattner57698e22002-03-26 18:01:55 +0000125 CallInst *MCall = new CallInst(MallocFunc,
Chris Lattnerd07471d2002-01-21 23:34:02 +0000126 vector<Value*>(1, MallocArg));
127 BBIL.insert(BBIL.begin()+i, MCall);
128
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);
132
133 // Replace all uses of the old malloc inst with the cast inst
134 MI->replaceAllUsesWith(MCast);
135 delete MI; // Delete the malloc inst
136 Changed = true;
137 } else if (FreeInst *FI = dyn_cast<FreeInst>(*(BBIL.begin()+i))) {
138 BBIL.remove(BB->getInstList().begin()+i);
139
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);
144
145 // Insert a call to the free function...
Chris Lattner57698e22002-03-26 18:01:55 +0000146 CallInst *FCall = new CallInst(FreeFunc,
Chris Lattnerd07471d2002-01-21 23:34:02 +0000147 vector<Value*>(1, MCast));
148 BBIL.insert(BBIL.begin()+i+1, FCall);
149
150 // Delete the old free instruction
151 delete FI;
152 Changed = true;
Chris Lattner1bb5f8e2001-10-15 17:31:51 +0000153 }
154 }
155
Chris Lattner6fea0322001-10-18 05:27:33 +0000156 return Changed;
Chris Lattner1bb5f8e2001-10-15 17:31:51 +0000157}
158
Chris Lattner4f0f0972002-01-22 00:13:51 +0000159bool RaiseAllocations::doInitialization(Module *M) {
Chris Lattner4f0f0972002-01-22 00:13:51 +0000160 // 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.
163 //
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.
167 //
Chris Lattnerc13563d2002-03-29 03:38:05 +0000168 const FunctionType *MallocType = // Get the type for malloc
169 FunctionType::get(PointerType::get(Type::SByteTy),
170 vector<const Type*>(1, Type::UIntTy), false);
Chris Lattner4f0f0972002-01-22 00:13:51 +0000171
Chris Lattnerc13563d2002-03-29 03:38:05 +0000172 const FunctionType *FreeType = // Get the type for free
173 FunctionType::get(Type::VoidTy,
174 vector<const Type*>(1, PointerType::get(Type::SByteTy)),
175 false);
Chris Lattner4f0f0972002-01-22 00:13:51 +0000176
Chris Lattnerc13563d2002-03-29 03:38:05 +0000177 MallocFunc = M->getFunction("malloc", MallocType);
178 FreeFunc = M->getFunction("free" , FreeType);
179
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;
Chris Lattner4f0f0972002-01-22 00:13:51 +0000183 return false;
184}
185
186// doOneCleanupPass - Do one pass over the input method, fixing stuff up.
187//
188bool RaiseAllocations::runOnBasicBlock(BasicBlock *BB) {
189 bool Changed = false;
190 BasicBlock::InstListType &BIL = BB->getInstList();
191
192 for (BasicBlock::iterator BI = BB->begin(); BI != BB->end();) {
193 Instruction *I = *BI;
194
195 if (CallInst *CI = dyn_cast<CallInst>(I)) {
Chris Lattner57698e22002-03-26 18:01:55 +0000196 if (CI->getCalledValue() == MallocFunc) { // Replace call to malloc?
Chris Lattner4f0f0972002-01-22 00:13:51 +0000197 const Type *PtrSByte = PointerType::get(Type::SByteTy);
198 MallocInst *MallocI = new MallocInst(PtrSByte, CI->getOperand(1),
199 CI->getName());
200 CI->setName("");
Chris Lattner70090072002-01-22 03:30:06 +0000201 ReplaceInstWithInst(BIL, BI, MallocI);
Chris Lattner4f0f0972002-01-22 00:13:51 +0000202 Changed = true;
203 continue; // Skip the ++BI
Chris Lattner57698e22002-03-26 18:01:55 +0000204 } else if (CI->getCalledValue() == FreeFunc) { // Replace call to free?
Chris Lattner4f0f0972002-01-22 00:13:51 +0000205 ReplaceInstWithInst(BIL, BI, new FreeInst(CI->getOperand(1)));
206 Changed = true;
207 continue; // Skip the ++BI
208 }
209 }
210
211 ++BI;
212 }
213
214 return Changed;
215}
Chris Lattner04805fa2002-02-26 21:46:54 +0000216
217Pass *createLowerAllocationsPass(const TargetData &TD) {
218 return new LowerAllocations(TD);
219}
220Pass *createRaiseAllocationsPass() {
221 return new RaiseAllocations();
222}