blob: 80eab61b7587a863554fccfe058681b3e260ae30 [file] [log] [blame]
Chris Lattnerade686e2002-05-07 19:02:48 +00001//===- LowerAllocations.cpp - Reduce malloc & free insts to calls ---------===//
Chris Lattner1bffea02001-10-15 17:31:51 +00002//
Chris Lattnerade686e2002-05-07 19:02:48 +00003// The LowerAllocations transformation is a target dependant tranformation
4// because it depends on the size of data types and alignment constraints.
Chris Lattner1bffea02001-10-15 17:31:51 +00005//
6//===----------------------------------------------------------------------===//
7
Chris Lattnerd7db8632002-01-22 01:04:08 +00008#include "llvm/Transforms/ChangeAllocations.h"
Chris Lattner793c6b82002-01-31 00:45:11 +00009#include "llvm/Module.h"
Chris Lattner0ac54292002-04-09 19:08:28 +000010#include "llvm/Function.h"
Chris Lattnerade686e2002-05-07 19:02:48 +000011#include "llvm/BasicBlock.h"
Chris Lattner1bffea02001-10-15 17:31:51 +000012#include "llvm/DerivedTypes.h"
13#include "llvm/iMemory.h"
14#include "llvm/iOther.h"
Chris Lattner497c60c2002-05-07 18:12:18 +000015#include "llvm/Constants.h"
Chris Lattnerbd0ef772002-02-26 21:46:54 +000016#include "llvm/Pass.h"
Chris Lattner497c60c2002-05-07 18:12:18 +000017#include "llvm/Target/TargetData.h"
Chris Lattner3dec1f22002-05-10 15:38:35 +000018#include "Support/StatisticReporter.h"
19
20static Statistic<> NumLowered("lowerallocs\t- Number of allocations lowered");
Chris Lattner697954c2002-01-20 22:54:45 +000021using std::vector;
22
Chris Lattnerbd0ef772002-02-26 21:46:54 +000023namespace {
24
25// LowerAllocations - Turn malloc and free instructions into %malloc and %free
26// calls.
27//
28class LowerAllocations : public BasicBlockPass {
Chris Lattner79df7c02002-03-26 18:01:55 +000029 Function *MallocFunc; // Functions in the module we are processing
30 Function *FreeFunc; // Initialized by doInitialization
Chris Lattnerbd0ef772002-02-26 21:46:54 +000031
32 const TargetData &DataLayout;
33public:
34 inline LowerAllocations(const TargetData &TD) : DataLayout(TD) {
Chris Lattner79df7c02002-03-26 18:01:55 +000035 MallocFunc = FreeFunc = 0;
Chris Lattnerbd0ef772002-02-26 21:46:54 +000036 }
37
Chris Lattner96c466b2002-04-29 14:57:45 +000038 const char *getPassName() const { return "Lower Allocations"; }
39
Chris Lattnerbd0ef772002-02-26 21:46:54 +000040 // doPassInitialization - For the lower allocations pass, this ensures that a
41 // module contains a declaration for a malloc and a free function.
42 //
43 bool doInitialization(Module *M);
44
45 // runOnBasicBlock - This method does the actual work of converting
46 // instructions over, assuming that the pass has already been initialized.
47 //
48 bool runOnBasicBlock(BasicBlock *BB);
49};
50
Chris Lattnerade686e2002-05-07 19:02:48 +000051}
Chris Lattnerbd0ef772002-02-26 21:46:54 +000052
Chris Lattnerade686e2002-05-07 19:02:48 +000053// createLowerAllocationsPass - Interface to this file...
54Pass *createLowerAllocationsPass(const TargetData &TD) {
55 return new LowerAllocations(TD);
56}
Chris Lattner96c466b2002-04-29 14:57:45 +000057
Chris Lattner1bffea02001-10-15 17:31:51 +000058
Chris Lattnerf4de63f2002-01-21 07:31:50 +000059// doInitialization - For the lower allocations pass, this ensures that a
Chris Lattner1bffea02001-10-15 17:31:51 +000060// module contains a declaration for a malloc and a free function.
61//
62// This function is always successful.
63//
Chris Lattnerf4de63f2002-01-21 07:31:50 +000064bool LowerAllocations::doInitialization(Module *M) {
Chris Lattnerbe591a72002-03-29 03:38:05 +000065 const FunctionType *MallocType =
66 FunctionType::get(PointerType::get(Type::SByteTy),
67 vector<const Type*>(1, Type::UIntTy), false);
68 const FunctionType *FreeType =
69 FunctionType::get(Type::VoidTy,
70 vector<const Type*>(1, PointerType::get(Type::SByteTy)),
71 false);
Chris Lattner1bffea02001-10-15 17:31:51 +000072
Chris Lattnerbe591a72002-03-29 03:38:05 +000073 MallocFunc = M->getOrInsertFunction("malloc", MallocType);
74 FreeFunc = M->getOrInsertFunction("free" , FreeType);
Chris Lattner1bffea02001-10-15 17:31:51 +000075
Chris Lattnerade686e2002-05-07 19:02:48 +000076 return true;
Chris Lattner1bffea02001-10-15 17:31:51 +000077}
78
Chris Lattner84453722002-01-21 23:34:02 +000079// runOnBasicBlock - This method does the actual work of converting
Chris Lattner1bffea02001-10-15 17:31:51 +000080// instructions over, assuming that the pass has already been initialized.
81//
Chris Lattner84453722002-01-21 23:34:02 +000082bool LowerAllocations::runOnBasicBlock(BasicBlock *BB) {
Chris Lattner42c9c2c2001-10-18 05:27:33 +000083 bool Changed = false;
Chris Lattner79df7c02002-03-26 18:01:55 +000084 assert(MallocFunc && FreeFunc && BB && "Pass not initialized!");
Chris Lattner1bffea02001-10-15 17:31:51 +000085
86 // Loop over all of the instructions, looking for malloc or free instructions
Chris Lattner3dec1f22002-05-10 15:38:35 +000087 for (unsigned i = 0; i != BB->size(); ++i) {
Chris Lattner84453722002-01-21 23:34:02 +000088 BasicBlock::InstListType &BBIL = BB->getInstList();
89 if (MallocInst *MI = dyn_cast<MallocInst>(*(BBIL.begin()+i))) {
90 BBIL.remove(BBIL.begin()+i); // remove the malloc instr...
Chris Lattner1bffea02001-10-15 17:31:51 +000091
Chris Lattner497c60c2002-05-07 18:12:18 +000092 const Type *AllocTy = cast<PointerType>(MI->getType())->getElementType();
Chris Lattner84453722002-01-21 23:34:02 +000093
94 // Get the number of bytes to be allocated for one element of the
95 // requested type...
96 unsigned Size = DataLayout.getTypeSize(AllocTy);
97
98 // malloc(type) becomes sbyte *malloc(constint)
99 Value *MallocArg = ConstantUInt::get(Type::UIntTy, Size);
100 if (MI->getNumOperands() && Size == 1) {
101 MallocArg = MI->getOperand(0); // Operand * 1 = Operand
102 } else if (MI->getNumOperands()) {
103 // Multiply it by the array size if neccesary...
104 MallocArg = BinaryOperator::create(Instruction::Mul,MI->getOperand(0),
105 MallocArg);
106 BBIL.insert(BBIL.begin()+i++, cast<Instruction>(MallocArg));
Chris Lattner1bffea02001-10-15 17:31:51 +0000107 }
Chris Lattner84453722002-01-21 23:34:02 +0000108
109 // Create the call to Malloc...
Chris Lattner79df7c02002-03-26 18:01:55 +0000110 CallInst *MCall = new CallInst(MallocFunc,
Chris Lattner84453722002-01-21 23:34:02 +0000111 vector<Value*>(1, MallocArg));
112 BBIL.insert(BBIL.begin()+i, MCall);
113
114 // Create a cast instruction to convert to the right type...
115 CastInst *MCast = new CastInst(MCall, MI->getType());
116 BBIL.insert(BBIL.begin()+i+1, MCast);
117
118 // Replace all uses of the old malloc inst with the cast inst
119 MI->replaceAllUsesWith(MCast);
120 delete MI; // Delete the malloc inst
121 Changed = true;
Chris Lattner3dec1f22002-05-10 15:38:35 +0000122 ++NumLowered;
Chris Lattner84453722002-01-21 23:34:02 +0000123 } else if (FreeInst *FI = dyn_cast<FreeInst>(*(BBIL.begin()+i))) {
124 BBIL.remove(BB->getInstList().begin()+i);
125
126 // Cast the argument to free into a ubyte*...
127 CastInst *MCast = new CastInst(FI->getOperand(0),
128 PointerType::get(Type::UByteTy));
129 BBIL.insert(BBIL.begin()+i, MCast);
130
131 // Insert a call to the free function...
Chris Lattner79df7c02002-03-26 18:01:55 +0000132 CallInst *FCall = new CallInst(FreeFunc,
Chris Lattner84453722002-01-21 23:34:02 +0000133 vector<Value*>(1, MCast));
134 BBIL.insert(BBIL.begin()+i+1, FCall);
135
136 // Delete the old free instruction
137 delete FI;
138 Changed = true;
Chris Lattner3dec1f22002-05-10 15:38:35 +0000139 ++NumLowered;
Chris Lattner1bffea02001-10-15 17:31:51 +0000140 }
141 }
142
Chris Lattner42c9c2c2001-10-18 05:27:33 +0000143 return Changed;
Chris Lattner1bffea02001-10-15 17:31:51 +0000144}