From 5048c3b853b8be541479e300705a88375569c8b1 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Tue, 22 Jan 2002 00:13:51 +0000 Subject: [PATCH] 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 --- include/llvm/Transforms/ChangeAllocations.h | 39 ++++++++--- include/llvm/Transforms/IPO.h | 5 -- lib/Transforms/IPO/DeadTypeElimination.cpp | 62 ------------------ lib/Transforms/Utils/LowerAllocations.cpp | 71 +++++++++++++++++++-- tools/gccas/gccas.cpp | 2 + tools/opt/opt.cpp | 5 +- 6 files changed, 103 insertions(+), 81 deletions(-) diff --git a/include/llvm/Transforms/ChangeAllocations.h b/include/llvm/Transforms/ChangeAllocations.h index 9adac5dd91d..f0a06859e90 100644 --- a/include/llvm/Transforms/ChangeAllocations.h +++ b/include/llvm/Transforms/ChangeAllocations.h @@ -1,21 +1,24 @@ -//===- llvm/Transforms/LowerAllocations.h - Remove Malloc & Free -*- C++ -*--=// +//===- llvm/Transforms/ChangeAllocations.h -----------------------*- C++ -*--=// // -// This file defines the interface to 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. // //===----------------------------------------------------------------------===// -#ifndef LLVM_TRANSFORMS_LOWERALLOCATIONS_H -#define LLVM_TRANSFORMS_LOWERALLOCATIONS_H +#ifndef LLVM_TRANSFORMS_CHANGEALLOCATIONS_H +#define LLVM_TRANSFORMS_CHANGEALLOCATIONS_H #include "llvm/Pass.h" class TargetData; +// LowerAllocations - Turn malloc and free instructions into %malloc and %free +// calls. +// class LowerAllocations : public BasicBlockPass { Method *MallocMeth; // Methods in the module we are processing - Method *FreeMeth; // Initialized by doPassInitializationVirt + Method *FreeMeth; // Initialized by doInitialization const TargetData &DataLayout; public: @@ -34,4 +37,24 @@ public: bool runOnBasicBlock(BasicBlock *BB); }; +// RaiseAllocations - Turn %malloc and %free calls into the appropriate +// instruction. +// +class RaiseAllocations : public BasicBlockPass { + Method *MallocMeth; // Methods in the module we are processing + Method *FreeMeth; // Initialized by doPassInitializationVirt +public: + inline RaiseAllocations() : MallocMeth(0), FreeMeth(0) {} + + // doPassInitialization - For the raise allocations pass, this finds a + // declaration for malloc and free if they exist. + // + bool doInitialization(Module *M); + + // runOnBasicBlock - This method does the actual work of converting + // instructions over, assuming that the pass has already been initialized. + // + bool runOnBasicBlock(BasicBlock *BB); +}; + #endif diff --git a/include/llvm/Transforms/IPO.h b/include/llvm/Transforms/IPO.h index 6bdba2241d3..1141d22490c 100644 --- a/include/llvm/Transforms/IPO.h +++ b/include/llvm/Transforms/IPO.h @@ -9,12 +9,9 @@ #include "llvm/Analysis/FindUsedTypes.h" class CleanupGCCOutput : public MethodPass { - Method *Malloc, *Free; // Pointers to external declarations, or null if none FindUsedTypes FUT; // Use FUT to eliminate type names that are never used public: - inline CleanupGCCOutput() : Malloc(0), Free(0) {} - // PatchUpMethodReferences - This is a part of the functionality exported by // the CleanupGCCOutput pass. This causes functions with different signatures // to be linked together if they have the same name. @@ -35,8 +32,6 @@ public: // doPassFinalization - Strip out type names that are unused by the program bool doFinalization(Module *M); -private: - bool doOneCleanupPass(Method *M); }; #endif diff --git a/lib/Transforms/IPO/DeadTypeElimination.cpp b/lib/Transforms/IPO/DeadTypeElimination.cpp index 696f4bd7d71..c170e151643 100644 --- a/lib/Transforms/IPO/DeadTypeElimination.cpp +++ b/lib/Transforms/IPO/DeadTypeElimination.cpp @@ -6,8 +6,6 @@ // // * Eliminate names for GCC types that we know can't be needed by the user. // * Eliminate names for types that are unused in the entire translation unit -// * Replace calls to 'sbyte *%malloc(uint)' and 'void %free(sbyte *)' with -// malloc and free instructions. // // Note: This code produces dead declarations, it is a good idea to run DCE // after this pass. @@ -242,30 +240,6 @@ bool CleanupGCCOutput::doInitialization(Module *M) { // Changed |= PatchUpMethodReferences(M); - - // 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(1, Type::UIntTy), false)); - Malloc = cast_or_null(ST->lookup(MallocType, "malloc")); - if (Malloc && !Malloc->isExternal()) - Malloc = 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(1, PointerType::get(Type::SByteTy)), false)); - Free = cast_or_null(ST->lookup(FreeType, "free")); - if (Free && !Free->isExternal()) - Free = 0; // Don't mess with locally defined versions of the fn - - // Check the symbol table for superfluous type entries... // // Grab the 'type' plane of the module symbol... @@ -292,41 +266,6 @@ bool CleanupGCCOutput::doInitialization(Module *M) { } -// doOneCleanupPass - Do one pass over the input method, fixing stuff up. -// -bool CleanupGCCOutput::doOneCleanupPass(Method *M) { - bool Changed = false; - for (Method::iterator MI = M->begin(), ME = M->end(); MI != ME; ++MI) { - BasicBlock *BB = *MI; - BasicBlock::InstListType &BIL = BB->getInstList(); - - for (BasicBlock::iterator BI = BB->begin(); BI != BB->end();) { - Instruction *I = *BI; - - if (CallInst *CI = dyn_cast(I)) { - if (CI->getCalledValue() == Malloc) { // Replace call to malloc? - 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() == Free) { // Replace call to free? - ReplaceInstWithInst(BIL, BI, new FreeInst(CI->getOperand(1))); - Changed = true; - continue; // Skip the ++BI - } - } - - ++BI; - } - } - - return Changed; -} - - // FixCastsAndPHIs - The LLVM GCC has a tendancy to intermix Cast instructions // in with the PHI nodes. These cast instructions are potentially there for two // different reasons: @@ -553,7 +492,6 @@ static bool fixLocalProblems(Method *M) { // bool CleanupGCCOutput::runOnMethod(Method *M) { bool Changed = fixLocalProblems(M); - while (doOneCleanupPass(M)) Changed = true; FUT.runOnMethod(M); return Changed; diff --git a/lib/Transforms/Utils/LowerAllocations.cpp b/lib/Transforms/Utils/LowerAllocations.cpp index 1acaea7d29c..59323431afc 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(1, Type::UIntTy), false)); + MallocMeth = cast_or_null(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(1, PointerType::get(Type::SByteTy)), false)); + FreeMeth = cast_or_null(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(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; +} diff --git a/tools/gccas/gccas.cpp b/tools/gccas/gccas.cpp index 24a5e87b1ba..211b4cf4592 100644 --- a/tools/gccas/gccas.cpp +++ b/tools/gccas/gccas.cpp @@ -12,6 +12,7 @@ #include "llvm/Transforms/CleanupGCCOutput.h" #include "llvm/Transforms/LevelChange.h" #include "llvm/Transforms/ConstantMerge.h" +#include "llvm/Transforms/LowerAllocations.h" #include "llvm/Transforms/Scalar/DCE.h" #include "llvm/Transforms/Scalar/IndVarSimplify.h" #include "llvm/Transforms/Scalar/InstructionCombining.h" @@ -65,6 +66,7 @@ int main(int argc, char **argv) { // PassManager Passes; Passes.add(new DeadCodeElimination()); // Remove Dead code/vars + Passes.add(new RaiseAllocations()); // call %malloc -> malloc inst Passes.add(new CleanupGCCOutput()); // Fix gccisms Passes.add(new InductionVariableSimplify()); // Simplify indvars Passes.add(new RaisePointerReferences()); // Eliminate casts diff --git a/tools/opt/opt.cpp b/tools/opt/opt.cpp index 36de3bfbf73..60c8683b65a 100644 --- a/tools/opt/opt.cpp +++ b/tools/opt/opt.cpp @@ -15,6 +15,7 @@ #include "llvm/Transforms/LevelChange.h" #include "llvm/Transforms/MethodInlining.h" #include "llvm/Transforms/SymbolStripping.h" +#include "llvm/Transforms/LowerAllocations.h" #include "llvm/Transforms/IPO/SimpleStructMutation.h" #include "llvm/Transforms/IPO/GlobalDCE.h" #include "llvm/Transforms/Scalar/DCE.h" @@ -34,7 +35,7 @@ enum Opts { dce, constprop, inlining, constmerge, strip, mstrip, // Miscellaneous Transformations - trace, tracem, print, cleangcc, + trace, tracem, print, raiseallocs, cleangcc, // More powerful optimizations indvars, instcombine, sccp, adce, raise, @@ -61,6 +62,7 @@ struct { { trace , new InsertTraceCode(true, true) }, { tracem , new InsertTraceCode(false, true) }, { print , new PrintMethodPass("Current Method: \n",&cerr) }, + { raiseallocs, new RaiseAllocations() }, { cleangcc , new CleanupGCCOutput() }, { globaldce , new GlobalDCE() }, { swapstructs, new SimpleStructMutation(SimpleStructMutation::SwapElements) }, @@ -88,6 +90,7 @@ cl::EnumList OptimizationList(cl::NoFlags, clEnumVal(swapstructs, "Swap structure types around"), clEnumVal(sortstructs, "Sort structure elements"), + clEnumVal(raiseallocs, "Raise allocations from calls to instructions"), clEnumVal(cleangcc , "Cleanup GCC Output"), clEnumVal(raise , "Raise to Higher Level"), clEnumVal(trace , "Insert BB & Method trace code"),