blob: 003be33182a8c36614649e70e09983febe70e546 [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 //
Chris Lattner7e708292002-06-25 16:13:24 +000043 bool doInitialization(Module &M);
Chris Lattnerbd0ef772002-02-26 21:46:54 +000044
45 // runOnBasicBlock - This method does the actual work of converting
46 // instructions over, assuming that the pass has already been initialized.
47 //
Chris Lattner7e708292002-06-25 16:13:24 +000048 bool runOnBasicBlock(BasicBlock &BB);
Chris Lattnerbd0ef772002-02-26 21:46:54 +000049};
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 Lattner7e708292002-06-25 16:13:24 +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 Lattner7e708292002-06-25 16:13:24 +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 Lattner7e708292002-06-25 16:13:24 +000082bool LowerAllocations::runOnBasicBlock(BasicBlock &BB) {
Chris Lattner42c9c2c2001-10-18 05:27:33 +000083 bool Changed = false;
Chris Lattner7e708292002-06-25 16:13:24 +000084 assert(MallocFunc && FreeFunc && "Pass not initialized!");
85
86 BasicBlock::InstListType &BBIL = BB.getInstList();
Chris Lattner1bffea02001-10-15 17:31:51 +000087
88 // Loop over all of the instructions, looking for malloc or free instructions
Chris Lattner7e708292002-06-25 16:13:24 +000089 for (BasicBlock::iterator I = BB.begin(), E = BB.end(); I != E; ++I) {
90 if (MallocInst *MI = dyn_cast<MallocInst>(&*I)) {
91 BBIL.remove(I); // remove the malloc instr...
92
93 const Type *AllocTy = MI->getType()->getElementType();
Chris Lattner84453722002-01-21 23:34:02 +000094
95 // Get the number of bytes to be allocated for one element of the
96 // requested type...
97 unsigned Size = DataLayout.getTypeSize(AllocTy);
98
99 // malloc(type) becomes sbyte *malloc(constint)
100 Value *MallocArg = ConstantUInt::get(Type::UIntTy, Size);
101 if (MI->getNumOperands() && Size == 1) {
102 MallocArg = MI->getOperand(0); // Operand * 1 = Operand
103 } else if (MI->getNumOperands()) {
104 // Multiply it by the array size if neccesary...
105 MallocArg = BinaryOperator::create(Instruction::Mul,MI->getOperand(0),
106 MallocArg);
Chris Lattner7e708292002-06-25 16:13:24 +0000107 I = ++BBIL.insert(I, cast<Instruction>(MallocArg));
Chris Lattner1bffea02001-10-15 17:31:51 +0000108 }
Chris Lattner84453722002-01-21 23:34:02 +0000109
110 // Create the call to Malloc...
Chris Lattner79df7c02002-03-26 18:01:55 +0000111 CallInst *MCall = new CallInst(MallocFunc,
Chris Lattner84453722002-01-21 23:34:02 +0000112 vector<Value*>(1, MallocArg));
Chris Lattner7e708292002-06-25 16:13:24 +0000113 I = BBIL.insert(I, MCall);
Chris Lattner84453722002-01-21 23:34:02 +0000114
115 // Create a cast instruction to convert to the right type...
116 CastInst *MCast = new CastInst(MCall, MI->getType());
Chris Lattner7e708292002-06-25 16:13:24 +0000117 I = BBIL.insert(++I, MCast);
Chris Lattner84453722002-01-21 23:34:02 +0000118
119 // Replace all uses of the old malloc inst with the cast inst
120 MI->replaceAllUsesWith(MCast);
121 delete MI; // Delete the malloc inst
122 Changed = true;
Chris Lattner3dec1f22002-05-10 15:38:35 +0000123 ++NumLowered;
Chris Lattner7e708292002-06-25 16:13:24 +0000124 } else if (FreeInst *FI = dyn_cast<FreeInst>(&*I)) {
125 BBIL.remove(I);
Chris Lattner84453722002-01-21 23:34:02 +0000126
127 // Cast the argument to free into a ubyte*...
128 CastInst *MCast = new CastInst(FI->getOperand(0),
129 PointerType::get(Type::UByteTy));
Chris Lattner7e708292002-06-25 16:13:24 +0000130 I = ++BBIL.insert(I, MCast);
Chris Lattner84453722002-01-21 23:34:02 +0000131
132 // Insert a call to the free function...
Chris Lattner7e708292002-06-25 16:13:24 +0000133 CallInst *FCall = new CallInst(FreeFunc, vector<Value*>(1, MCast));
134 I = BBIL.insert(I, FCall);
Chris Lattner84453722002-01-21 23:34:02 +0000135
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}