LowerAllocations is really a BasicBlock pass. Make it so.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@1521 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner 2002-01-21 23:34:02 +00:00
parent 59b6b8e0b3
commit 8445372636
2 changed files with 57 additions and 62 deletions

View File

@ -13,7 +13,7 @@
#include "llvm/Pass.h"
class TargetData;
class LowerAllocations : public MethodPass {
class LowerAllocations : public BasicBlockPass {
Method *MallocMeth; // Methods in the module we are processing
Method *FreeMeth; // Initialized by doPassInitializationVirt
@ -26,14 +26,12 @@ public:
// doPassInitialization - For the lower allocations pass, this ensures that a
// module contains a declaration for a malloc and a free function.
//
// This function is always successful.
//
bool doInitialization(Module *M);
// doPerMethodWork - This method does the actual work of converting
// runOnBasicBlock - This method does the actual work of converting
// instructions over, assuming that the pass has already been initialized.
//
bool runOnMethod(Method *M);
bool runOnBasicBlock(BasicBlock *BB);
};
#endif

View File

@ -1,4 +1,4 @@
//===- llvm/Transforms/LowerAllocations.h - Remove Malloc & Free Insts ------=//
//===- LowerAllocations.cpp - Remove Malloc & Free Instructions -------------=//
//
// This file implements a pass that lowers malloc and free instructions to
// calls to %malloc & %free functions. This transformation is a target
@ -52,71 +52,68 @@ bool LowerAllocations::doInitialization(Module *M) {
Changed = true;
}
return Changed; // Always successful
return Changed;
}
// runOnMethod - This method does the actual work of converting
// runOnBasicBlock - This method does the actual work of converting
// instructions over, assuming that the pass has already been initialized.
//
bool LowerAllocations::runOnMethod(Method *M) {
bool LowerAllocations::runOnBasicBlock(BasicBlock *BB) {
bool Changed = false;
assert(MallocMeth && FreeMeth && M && "Pass not initialized!");
assert(MallocMeth && FreeMeth && BB && "Pass not initialized!");
// Loop over all of the instructions, looking for malloc or free instructions
for (Method::iterator BBI = M->begin(), BBE = M->end(); BBI != BBE; ++BBI) {
BasicBlock *BB = *BBI;
for (unsigned i = 0; i < BB->size(); ++i) {
BasicBlock::InstListType &BBIL = BB->getInstList();
if (MallocInst *MI = dyn_cast<MallocInst>(*(BBIL.begin()+i))) {
BBIL.remove(BBIL.begin()+i); // remove the malloc instr...
for (unsigned i = 0; i < BB->size(); ++i) {
BasicBlock::InstListType &BBIL = BB->getInstList();
if (MallocInst *MI = dyn_cast<MallocInst>(*(BBIL.begin()+i))) {
BBIL.remove(BBIL.begin()+i); // remove the malloc instr...
const Type *AllocTy =cast<PointerType>(MI->getType())->getElementType();
// Get the number of bytes to be allocated for one element of the
// requested type...
unsigned Size = DataLayout.getTypeSize(AllocTy);
// malloc(type) becomes sbyte *malloc(constint)
Value *MallocArg = ConstantUInt::get(Type::UIntTy, Size);
if (MI->getNumOperands() && Size == 1) {
MallocArg = MI->getOperand(0); // Operand * 1 = Operand
} else if (MI->getNumOperands()) {
// Multiply it by the array size if neccesary...
MallocArg = BinaryOperator::create(Instruction::Mul,MI->getOperand(0),
MallocArg);
BBIL.insert(BBIL.begin()+i++, cast<Instruction>(MallocArg));
}
// Create the call to Malloc...
CallInst *MCall = new CallInst(MallocMeth,
vector<Value*>(1, MallocArg));
BBIL.insert(BBIL.begin()+i, MCall);
// Create a cast instruction to convert to the right type...
CastInst *MCast = new CastInst(MCall, MI->getType());
BBIL.insert(BBIL.begin()+i+1, MCast);
// Replace all uses of the old malloc inst with the cast inst
MI->replaceAllUsesWith(MCast);
delete MI; // Delete the malloc inst
Changed = true;
} else if (FreeInst *FI = dyn_cast<FreeInst>(*(BBIL.begin()+i))) {
BBIL.remove(BB->getInstList().begin()+i);
// Cast the argument to free into a ubyte*...
CastInst *MCast = new CastInst(FI->getOperand(0),
PointerType::get(Type::UByteTy));
BBIL.insert(BBIL.begin()+i, MCast);
// Insert a call to the free function...
CallInst *FCall = new CallInst(FreeMeth,
vector<Value*>(1, MCast));
BBIL.insert(BBIL.begin()+i+1, FCall);
// Delete the old free instruction
delete FI;
Changed = true;
const Type *AllocTy =cast<PointerType>(MI->getType())->getElementType();
// Get the number of bytes to be allocated for one element of the
// requested type...
unsigned Size = DataLayout.getTypeSize(AllocTy);
// malloc(type) becomes sbyte *malloc(constint)
Value *MallocArg = ConstantUInt::get(Type::UIntTy, Size);
if (MI->getNumOperands() && Size == 1) {
MallocArg = MI->getOperand(0); // Operand * 1 = Operand
} else if (MI->getNumOperands()) {
// Multiply it by the array size if neccesary...
MallocArg = BinaryOperator::create(Instruction::Mul,MI->getOperand(0),
MallocArg);
BBIL.insert(BBIL.begin()+i++, cast<Instruction>(MallocArg));
}
// Create the call to Malloc...
CallInst *MCall = new CallInst(MallocMeth,
vector<Value*>(1, MallocArg));
BBIL.insert(BBIL.begin()+i, MCall);
// Create a cast instruction to convert to the right type...
CastInst *MCast = new CastInst(MCall, MI->getType());
BBIL.insert(BBIL.begin()+i+1, MCast);
// Replace all uses of the old malloc inst with the cast inst
MI->replaceAllUsesWith(MCast);
delete MI; // Delete the malloc inst
Changed = true;
} else if (FreeInst *FI = dyn_cast<FreeInst>(*(BBIL.begin()+i))) {
BBIL.remove(BB->getInstList().begin()+i);
// Cast the argument to free into a ubyte*...
CastInst *MCast = new CastInst(FI->getOperand(0),
PointerType::get(Type::UByteTy));
BBIL.insert(BBIL.begin()+i, MCast);
// Insert a call to the free function...
CallInst *FCall = new CallInst(FreeMeth,
vector<Value*>(1, MCast));
BBIL.insert(BBIL.begin()+i+1, FCall);
// Delete the old free instruction
delete FI;
Changed = true;
}
}