diff options
Diffstat (limited to 'lib/Transforms')
-rw-r--r-- | lib/Transforms/IPO/CMakeLists.txt | 1 | ||||
-rw-r--r-- | lib/Transforms/IPO/GlobalOpt.cpp | 5 | ||||
-rw-r--r-- | lib/Transforms/IPO/IPO.cpp | 2 | ||||
-rw-r--r-- | lib/Transforms/IPO/RaiseAllocations.cpp | 173 | ||||
-rw-r--r-- | lib/Transforms/Scalar/DeadStoreElimination.cpp | 14 | ||||
-rw-r--r-- | lib/Transforms/Scalar/InstructionCombining.cpp | 40 | ||||
-rw-r--r-- | lib/Transforms/Scalar/SCCP.cpp | 5 | ||||
-rw-r--r-- | lib/Transforms/Utils/Local.cpp | 3 | ||||
-rw-r--r-- | lib/Transforms/Utils/LowerAllocations.cpp | 6 |
9 files changed, 59 insertions, 190 deletions
diff --git a/lib/Transforms/IPO/CMakeLists.txt b/lib/Transforms/IPO/CMakeLists.txt index 5c28801555..92bef3bb75 100644 --- a/lib/Transforms/IPO/CMakeLists.txt +++ b/lib/Transforms/IPO/CMakeLists.txt @@ -19,7 +19,6 @@ add_llvm_library(LLVMipo PartialInlining.cpp PartialSpecialization.cpp PruneEH.cpp - RaiseAllocations.cpp StripDeadPrototypes.cpp StripSymbols.cpp StructRetPromotion.cpp diff --git a/lib/Transforms/IPO/GlobalOpt.cpp b/lib/Transforms/IPO/GlobalOpt.cpp index 9ced2e89a7..0bc086f432 100644 --- a/lib/Transforms/IPO/GlobalOpt.cpp +++ b/lib/Transforms/IPO/GlobalOpt.cpp @@ -1364,10 +1364,11 @@ static GlobalVariable *PerformHeapAllocSRoA(GlobalVariable *GV, OrigBB->getParent()); BasicBlock *NextBlock = BasicBlock::Create(Context, "next", OrigBB->getParent()); - BranchInst::Create(FreeBlock, NextBlock, Cmp, NullPtrBlock); + Instruction *BI = BranchInst::Create(FreeBlock, NextBlock, + Cmp, NullPtrBlock); // Fill in FreeBlock. - new FreeInst(GVVal, FreeBlock); + CallInst::CreateFree(GVVal, BI); new StoreInst(Constant::getNullValue(GVVal->getType()), FieldGlobals[i], FreeBlock); BranchInst::Create(NextBlock, FreeBlock); diff --git a/lib/Transforms/IPO/IPO.cpp b/lib/Transforms/IPO/IPO.cpp index 43066076ca..83e8624fe0 100644 --- a/lib/Transforms/IPO/IPO.cpp +++ b/lib/Transforms/IPO/IPO.cpp @@ -63,7 +63,7 @@ void LLVMAddPruneEHPass(LLVMPassManagerRef PM) { } void LLVMAddRaiseAllocationsPass(LLVMPassManagerRef PM) { - unwrap(PM)->add(createRaiseAllocationsPass()); + // FIXME: Remove in LLVM 3.0. } void LLVMAddStripDeadPrototypesPass(LLVMPassManagerRef PM) { diff --git a/lib/Transforms/IPO/RaiseAllocations.cpp b/lib/Transforms/IPO/RaiseAllocations.cpp deleted file mode 100644 index deb4405754..0000000000 --- a/lib/Transforms/IPO/RaiseAllocations.cpp +++ /dev/null @@ -1,173 +0,0 @@ -//===- RaiseAllocations.cpp - Convert @free calls to insts ------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines the RaiseAllocations pass which convert free calls to free -// instructions. -// -//===----------------------------------------------------------------------===// - -#define DEBUG_TYPE "raiseallocs" -#include "llvm/Transforms/IPO.h" -#include "llvm/Constants.h" -#include "llvm/DerivedTypes.h" -#include "llvm/LLVMContext.h" -#include "llvm/Module.h" -#include "llvm/Instructions.h" -#include "llvm/Pass.h" -#include "llvm/Support/CallSite.h" -#include "llvm/Support/Compiler.h" -#include "llvm/ADT/Statistic.h" -#include <algorithm> -using namespace llvm; - -STATISTIC(NumRaised, "Number of allocations raised"); - -namespace { - // RaiseAllocations - Turn @free calls into the appropriate - // instruction. - // - class VISIBILITY_HIDDEN RaiseAllocations : public ModulePass { - Function *FreeFunc; // Functions in the module we are processing - // Initialized by doPassInitializationVirt - public: - static char ID; // Pass identification, replacement for typeid - RaiseAllocations() - : ModulePass(&ID), FreeFunc(0) {} - - // doPassInitialization - For the raise allocations pass, this finds a - // declaration for free if it exists. - // - void doInitialization(Module &M); - - // run - This method does the actual work of converting instructions over. - // - bool runOnModule(Module &M); - }; -} // end anonymous namespace - -char RaiseAllocations::ID = 0; -static RegisterPass<RaiseAllocations> -X("raiseallocs", "Raise allocations from calls to instructions"); - -// createRaiseAllocationsPass - The interface to this file... -ModulePass *llvm::createRaiseAllocationsPass() { - return new RaiseAllocations(); -} - - -// If the module has a symbol table, they might be referring to the free -// function. If this is the case, grab the method pointers that the module is -// using. -// -// Lookup @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. -// -void RaiseAllocations::doInitialization(Module &M) { - // Get free prototype if it exists! - FreeFunc = M.getFunction("free"); - if (FreeFunc) { - const FunctionType* TyWeHave = FreeFunc->getFunctionType(); - - // Get the expected prototype for void free(i8*) - const FunctionType *Free1Type = - FunctionType::get(Type::getVoidTy(M.getContext()), - std::vector<const Type*>(1, PointerType::getUnqual( - Type::getInt8Ty(M.getContext()))), - false); - - if (TyWeHave != Free1Type) { - // Check to see if the prototype was forgotten, giving us - // void (...) * free - // This handles the common forward declaration of: 'void free();' - const FunctionType* Free2Type = - FunctionType::get(Type::getVoidTy(M.getContext()), true); - - if (TyWeHave != Free2Type) { - // One last try, check to see if we can find free as - // int (...)* free. This handles the case where NOTHING was declared. - const FunctionType* Free3Type = - FunctionType::get(Type::getInt32Ty(M.getContext()), true); - - if (TyWeHave != Free3Type) { - // Give up. - FreeFunc = 0; - } - } - } - } - - // Don't mess with locally defined versions of these functions... - if (FreeFunc && !FreeFunc->isDeclaration()) FreeFunc = 0; -} - -// run - Transform calls into instructions... -// -bool RaiseAllocations::runOnModule(Module &M) { - // Find the free prototype... - doInitialization(M); - - bool Changed = false; - - // Process all free calls... - if (FreeFunc) { - std::vector<User*> Users(FreeFunc->use_begin(), FreeFunc->use_end()); - std::vector<Value*> EqPointers; // Values equal to FreeFunc - - while (!Users.empty()) { - User *U = Users.back(); - Users.pop_back(); - - if (Instruction *I = dyn_cast<Instruction>(U)) { - if (isa<InvokeInst>(I)) - continue; - CallSite CS = CallSite::get(I); - if (CS.getInstruction() && !CS.arg_empty() && - (CS.getCalledFunction() == FreeFunc || - std::find(EqPointers.begin(), EqPointers.end(), - CS.getCalledValue()) != EqPointers.end())) { - - // If no prototype was provided for free, we may need to cast the - // source pointer. This should be really uncommon, but it's necessary - // just in case we are dealing with weird code like this: - // free((long)ptr); - // - Value *Source = *CS.arg_begin(); - if (!isa<PointerType>(Source->getType())) - Source = new IntToPtrInst(Source, - Type::getInt8PtrTy(M.getContext()), - "FreePtrCast", I); - new FreeInst(Source, I); - - // If the old instruction was an invoke, add an unconditional branch - // before the invoke, which will become the new terminator. - if (InvokeInst *II = dyn_cast<InvokeInst>(I)) - BranchInst::Create(II->getNormalDest(), I); - - // Delete the old call site - if (I->getType() != Type::getVoidTy(M.getContext())) - I->replaceAllUsesWith(UndefValue::get(I->getType())); - I->eraseFromParent(); - Changed = true; - ++NumRaised; - } - } else if (GlobalValue *GV = dyn_cast<GlobalValue>(U)) { - Users.insert(Users.end(), GV->use_begin(), GV->use_end()); - EqPointers.push_back(GV); - } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(U)) { - if (CE->isCast()) { - Users.insert(Users.end(), CE->use_begin(), CE->use_end()); - EqPointers.push_back(CE); - } - } - } - } - - return Changed; -} diff --git a/lib/Transforms/Scalar/DeadStoreElimination.cpp b/lib/Transforms/Scalar/DeadStoreElimination.cpp index a7b3e7524f..f55d8b2acc 100644 --- a/lib/Transforms/Scalar/DeadStoreElimination.cpp +++ b/lib/Transforms/Scalar/DeadStoreElimination.cpp @@ -26,6 +26,7 @@ #include "llvm/ADT/Statistic.h" #include "llvm/Analysis/AliasAnalysis.h" #include "llvm/Analysis/Dominators.h" +#include "llvm/Analysis/MallocHelper.h" #include "llvm/Analysis/MemoryDependenceAnalysis.h" #include "llvm/Target/TargetData.h" #include "llvm/Transforms/Utils/Local.h" @@ -49,7 +50,7 @@ namespace { } bool runOnBasicBlock(BasicBlock &BB); - bool handleFreeWithNonTrivialDependency(FreeInst *F, MemDepResult Dep); + bool handleFreeWithNonTrivialDependency(Instruction *F, MemDepResult Dep); bool handleEndBlock(BasicBlock &BB); bool RemoveUndeadPointers(Value* Ptr, uint64_t killPointerSize, BasicBlock::iterator& BBI, @@ -88,7 +89,7 @@ bool DSE::runOnBasicBlock(BasicBlock &BB) { Instruction *Inst = BBI++; // If we find a store or a free, get its memory dependence. - if (!isa<StoreInst>(Inst) && !isa<FreeInst>(Inst)) + if (!isa<StoreInst>(Inst) && !isa<FreeInst>(Inst) && !isFreeCall(Inst)) continue; // Don't molest volatile stores or do queries that will return "clobber". @@ -103,8 +104,8 @@ bool DSE::runOnBasicBlock(BasicBlock &BB) { if (InstDep.isNonLocal()) continue; // Handle frees whose dependencies are non-trivial. - if (FreeInst *FI = dyn_cast<FreeInst>(Inst)) { - MadeChange |= handleFreeWithNonTrivialDependency(FI, InstDep); + if (isa<FreeInst>(Inst) || isFreeCall(Inst)) { + MadeChange |= handleFreeWithNonTrivialDependency(Inst, InstDep); continue; } @@ -165,7 +166,7 @@ bool DSE::runOnBasicBlock(BasicBlock &BB) { /// handleFreeWithNonTrivialDependency - Handle frees of entire structures whose /// dependency is a store to a field of that structure. -bool DSE::handleFreeWithNonTrivialDependency(FreeInst *F, MemDepResult Dep) { +bool DSE::handleFreeWithNonTrivialDependency(Instruction *F, MemDepResult Dep) { AliasAnalysis &AA = getAnalysis<AliasAnalysis>(); StoreInst *Dependency = dyn_cast_or_null<StoreInst>(Dep.getInst()); @@ -175,7 +176,8 @@ bool DSE::handleFreeWithNonTrivialDependency(FreeInst *F, MemDepResult Dep) { Value *DepPointer = Dependency->getPointerOperand()->getUnderlyingObject(); // Check for aliasing. - if (AA.alias(F->getPointerOperand(), 1, DepPointer, 1) != + Value* FreeVal = isa<FreeInst>(F) ? F->getOperand(0) : F->getOperand(1); + if (AA.alias(FreeVal, 1, DepPointer, 1) != AliasAnalysis::MustAlias) return false; diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp index 21554c108d..be4f775731 100644 --- a/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/lib/Transforms/Scalar/InstructionCombining.cpp @@ -286,6 +286,7 @@ namespace { Instruction *visitGetElementPtrInst(GetElementPtrInst &GEP); Instruction *visitAllocaInst(AllocaInst &AI); Instruction *visitFreeInst(FreeInst &FI); + Instruction *visitFree(Instruction &FI); Instruction *visitLoadInst(LoadInst &LI); Instruction *visitStoreInst(StoreInst &SI); Instruction *visitBranchInst(BranchInst &BI); @@ -9747,6 +9748,9 @@ Instruction *InstCombiner::SimplifyMemSet(MemSetInst *MI) { /// the heavy lifting. /// Instruction *InstCombiner::visitCallInst(CallInst &CI) { + if (isFreeCall(&CI)) + return visitFree(CI); + // If the caller function is nounwind, mark the call as nounwind, even if the // callee isn't. if (CI.getParent()->getParent()->doesNotThrow() && @@ -11337,6 +11341,42 @@ Instruction *InstCombiner::visitFreeInst(FreeInst &FI) { return 0; } +Instruction *InstCombiner::visitFree(Instruction &FI) { + Value *Op = FI.getOperand(1); + + // free undef -> unreachable. + if (isa<UndefValue>(Op)) { + // Insert a new store to null because we cannot modify the CFG here. + new StoreInst(ConstantInt::getTrue(*Context), + UndefValue::get(Type::getInt1PtrTy(*Context)), &FI); + return EraseInstFromFunction(FI); + } + + // If we have 'free null' delete the instruction. This can happen in stl code + // when lots of inlining happens. + if (isa<ConstantPointerNull>(Op)) + return EraseInstFromFunction(FI); + + // FIXME: Bring back free (gep X, 0,0,0,0) into free(X) transform + + if (isMalloc(Op)) { + if (CallInst* CI = extractMallocCallFromBitCast(Op)) { + if (Op->hasOneUse() && CI->hasOneUse()) { + EraseInstFromFunction(FI); + EraseInstFromFunction(*CI); + return EraseInstFromFunction(*cast<Instruction>(Op)); + } + } else { + // Op is a call to malloc + if (Op->hasOneUse()) { + EraseInstFromFunction(FI); + return EraseInstFromFunction(*cast<Instruction>(Op)); + } + } + } + + return 0; +} /// InstCombineLoadCast - Fold 'load (cast P)' -> cast (load P)' when possible. static Instruction *InstCombineLoadCast(InstCombiner &IC, LoadInst &LI, diff --git a/lib/Transforms/Scalar/SCCP.cpp b/lib/Transforms/Scalar/SCCP.cpp index e3dd54e8bc..1bb5f4ae7f 100644 --- a/lib/Transforms/Scalar/SCCP.cpp +++ b/lib/Transforms/Scalar/SCCP.cpp @@ -30,6 +30,7 @@ #include "llvm/LLVMContext.h" #include "llvm/Pass.h" #include "llvm/Analysis/ConstantFolding.h" +#include "llvm/Analysis/MallocHelper.h" #include "llvm/Analysis/ValueTracking.h" #include "llvm/Transforms/Utils/Local.h" #include "llvm/Support/CallSite.h" @@ -400,7 +401,9 @@ private: void visitStoreInst (Instruction &I); void visitLoadInst (LoadInst &I); void visitGetElementPtrInst(GetElementPtrInst &I); - void visitCallInst (CallInst &I) { + void visitCallInst (CallInst &I) { + if (isFreeCall(&I)) + return; visitCallSite(CallSite::get(&I)); } void visitInvokeInst (InvokeInst &II) { diff --git a/lib/Transforms/Utils/Local.cpp b/lib/Transforms/Utils/Local.cpp index b62261119c..940f5a9ec4 100644 --- a/lib/Transforms/Utils/Local.cpp +++ b/lib/Transforms/Utils/Local.cpp @@ -24,6 +24,7 @@ #include "llvm/ADT/SmallPtrSet.h" #include "llvm/Analysis/ConstantFolding.h" #include "llvm/Analysis/DebugInfo.h" +#include "llvm/Analysis/MallocHelper.h" #include "llvm/Analysis/ProfileInfo.h" #include "llvm/Target/TargetData.h" #include "llvm/Support/GetElementPtrTypeIterator.h" @@ -59,7 +60,7 @@ bool llvm::isSafeToLoadUnconditionally(Value *V, Instruction *ScanFrom) { // If we see a free or a call which may write to memory (i.e. which might do // a free) the pointer could be marked invalid. - if (isa<FreeInst>(BBI) || + if (isa<FreeInst>(BBI) || isFreeCall(BBI) || (isa<CallInst>(BBI) && BBI->mayWriteToMemory() && !isa<DbgInfoIntrinsic>(BBI))) return false; diff --git a/lib/Transforms/Utils/LowerAllocations.cpp b/lib/Transforms/Utils/LowerAllocations.cpp index 9c9113daa9..f64a30f5e8 100644 --- a/lib/Transforms/Utils/LowerAllocations.cpp +++ b/lib/Transforms/Utils/LowerAllocations.cpp @@ -102,12 +102,8 @@ bool LowerAllocations::runOnBasicBlock(BasicBlock &BB) { // Loop over all of the instructions, looking for free instructions for (BasicBlock::iterator I = BB.begin(), E = BB.end(); I != E; ++I) { if (FreeInst *FI = dyn_cast<FreeInst>(I)) { - Value *PtrCast = - new BitCastInst(FI->getOperand(0), - Type::getInt8PtrTy(BB.getContext()), "", I); - // Insert a call to the free function... - CallInst::Create(FreeFunc, PtrCast, "", I)->setTailCall(); + CallInst::CreateFree(FI->getOperand(0), I); // Delete the old free instruction I = --BBIL.erase(I); |