diff options
author | Chris Lattner <sabre@nondot.org> | 2002-01-22 00:13:51 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2002-01-22 00:13:51 +0000 |
commit | 5048c3b853b8be541479e300705a88375569c8b1 (patch) | |
tree | 06ad0297d913d6ca52869480e2ee7cf69bc57b97 /lib/Transforms/Utils/LowerAllocations.cpp | |
parent | 8445372636eaacad7dc34f12769a290675e351b9 (diff) |
Pull RaiseAllocations stuff out of the CleanGCC pass into it's own pass in
the ChangeAllocations.h header file.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@1522 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms/Utils/LowerAllocations.cpp')
-rw-r--r-- | lib/Transforms/Utils/LowerAllocations.cpp | 71 |
1 files changed, 66 insertions, 5 deletions
diff --git a/lib/Transforms/Utils/LowerAllocations.cpp b/lib/Transforms/Utils/LowerAllocations.cpp index 1acaea7d29..59323431af 100644 --- a/lib/Transforms/Utils/LowerAllocations.cpp +++ b/lib/Transforms/Utils/LowerAllocations.cpp @@ -1,9 +1,9 @@ -//===- LowerAllocations.cpp - Remove Malloc & Free Instructions -------------=// +//===- ChangeAllocations.cpp - Modify %malloc & %free calls -----------------=// // -// This file implements a pass that lowers malloc and free instructions to -// calls to %malloc & %free functions. This transformation is a target -// dependant tranformation because we depend on the size of data types and -// alignment constraints. +// This file defines two passes that convert malloc and free instructions to +// calls to and from %malloc & %free function calls. The LowerAllocations +// transformation is a target dependant tranformation because it depends on the +// size of data types and alignment constraints. // //===----------------------------------------------------------------------===// @@ -14,6 +14,7 @@ #include "llvm/iOther.h" #include "llvm/SymbolTable.h" #include "llvm/ConstantVals.h" +#include "TransformInternals.h" using std::vector; @@ -120,3 +121,63 @@ bool LowerAllocations::runOnBasicBlock(BasicBlock *BB) { return Changed; } +bool RaiseAllocations::doInitialization(Module *M) { + SymbolTable *ST = M->getSymbolTable(); + if (!ST) return false; + + // If the module has a symbol table, they might be referring to the malloc + // and free functions. If this is the case, grab the method pointers that + // the module is using. + // + // Lookup %malloc and %free in the symbol table, for later use. If they + // don't exist, or are not external, we do not worry about converting calls + // to that function into the appropriate instruction. + // + const PointerType *MallocType = // Get the type for malloc + PointerType::get(MethodType::get(PointerType::get(Type::SByteTy), + vector<const Type*>(1, Type::UIntTy), false)); + MallocMeth = cast_or_null<Method>(ST->lookup(MallocType, "malloc")); + if (MallocMeth && !MallocMeth->isExternal()) + MallocMeth = 0; // Don't mess with locally defined versions of the fn + + const PointerType *FreeType = // Get the type for free + PointerType::get(MethodType::get(Type::VoidTy, + vector<const Type*>(1, PointerType::get(Type::SByteTy)), false)); + FreeMeth = cast_or_null<Method>(ST->lookup(FreeType, "free")); + if (FreeMeth && !FreeMeth->isExternal()) + FreeMeth = 0; // Don't mess with locally defined versions of the fn + + return false; +} + +// doOneCleanupPass - Do one pass over the input method, fixing stuff up. +// +bool RaiseAllocations::runOnBasicBlock(BasicBlock *BB) { + bool Changed = false; + BasicBlock::InstListType &BIL = BB->getInstList(); + + for (BasicBlock::iterator BI = BB->begin(); BI != BB->end();) { + Instruction *I = *BI; + + if (CallInst *CI = dyn_cast<CallInst>(I)) { + if (CI->getCalledValue() == MallocMeth) { // Replace call to malloc? + const Type *PtrSByte = PointerType::get(Type::SByteTy); + MallocInst *MallocI = new MallocInst(PtrSByte, CI->getOperand(1), + CI->getName()); + CI->setName(""); + BI = BIL.insert(BI, MallocI)+1; + ReplaceInstWithInst(BIL, BI, new CastInst(MallocI, PtrSByte)); + Changed = true; + continue; // Skip the ++BI + } else if (CI->getCalledValue() == FreeMeth) { // Replace call to free? + ReplaceInstWithInst(BIL, BI, new FreeInst(CI->getOperand(1))); + Changed = true; + continue; // Skip the ++BI + } + } + + ++BI; + } + + return Changed; +} |