From 673c036bc783b64070cbbe90a593992619a83415 Mon Sep 17 00:00:00 2001 From: Victor Hernandez Date: Mon, 26 Oct 2009 23:43:48 +0000 Subject: [PATCH] Remove FreeInst. Remove LowerAllocations pass. Update some more passes to treate free calls just like they were treating FreeInst. llvm-svn: 85176 --- examples/BrainF/BrainF.cpp | 4 +- include/llvm-c/Core.h | 1 - include/llvm/Analysis/AliasSetTracker.h | 3 - include/llvm/Analysis/MallocHelper.h | 5 +- include/llvm/InstrTypes.h | 1 - include/llvm/Instruction.def | 69 +++++------ include/llvm/Instructions.h | 29 ----- include/llvm/LinkAllPasses.h | 1 - include/llvm/Support/IRBuilder.h | 3 - include/llvm/Support/InstVisitor.h | 1 - include/llvm/Transforms/Scalar.h | 9 -- lib/Analysis/AliasSetTracker.cpp | 33 +++-- lib/Analysis/CaptureTracking.cpp | 7 +- lib/Analysis/IPA/Andersens.cpp | 3 +- lib/Analysis/IPA/GlobalsModRef.cpp | 4 +- lib/Analysis/InlineCost.cpp | 4 - lib/Analysis/InstCount.cpp | 4 +- lib/Analysis/MallocHelper.cpp | 9 +- lib/Analysis/MemoryDependenceAnalysis.cpp | 13 +- lib/AsmParser/LLLexer.cpp | 5 +- lib/Bitcode/Writer/BitcodeWriter.cpp | 5 - .../SelectionDAG/SelectionDAGBuild.cpp | 20 --- lib/CodeGen/SelectionDAG/SelectionDAGBuild.h | 2 - lib/ExecutionEngine/Interpreter/Execution.cpp | 8 -- lib/ExecutionEngine/Interpreter/Interpreter.h | 1 - lib/Target/CBackend/CBackend.cpp | 6 - lib/Target/CppBackend/CPPBackend.cpp | 5 - lib/Target/MSIL/MSILWriter.cpp | 4 - .../Scalar/DeadStoreElimination.cpp | 7 +- .../Scalar/InstructionCombining.cpp | 57 +-------- lib/Transforms/Scalar/SCCP.cpp | 1 - lib/Transforms/Utils/CMakeLists.txt | 1 - lib/Transforms/Utils/Local.cpp | 5 +- lib/Transforms/Utils/LowerAllocations.cpp | 116 ------------------ lib/Transforms/Utils/LowerInvoke.cpp | 1 - lib/Transforms/Utils/LowerSwitch.cpp | 1 - lib/Transforms/Utils/Mem2Reg.cpp | 1 - lib/VMCore/Core.cpp | 3 +- lib/VMCore/Instruction.cpp | 48 +++++++- lib/VMCore/Instructions.cpp | 32 ----- 40 files changed, 131 insertions(+), 401 deletions(-) delete mode 100644 lib/Transforms/Utils/LowerAllocations.cpp diff --git a/examples/BrainF/BrainF.cpp b/examples/BrainF/BrainF.cpp index c64b87f2f39..f17a950036d 100644 --- a/examples/BrainF/BrainF.cpp +++ b/examples/BrainF/BrainF.cpp @@ -117,8 +117,8 @@ void BrainF::header(LLVMContext& C) { //brainf.end: endbb = BasicBlock::Create(C, label, brainf_func); - //free i8 *%arr - new FreeInst(ptr_arr, endbb); + //call free(i8 *%arr) + endbb->getInstList().push_back(CallInst::CreateFree(ptr_arr, endbb)); //ret void ReturnInst::Create(C, endbb); diff --git a/include/llvm-c/Core.h b/include/llvm-c/Core.h index 89e15458434..7cb5bc371b7 100644 --- a/include/llvm-c/Core.h +++ b/include/llvm-c/Core.h @@ -470,7 +470,6 @@ void LLVMDisposeTypeHandle(LLVMTypeHandleRef TypeHandle); macro(UIToFPInst) \ macro(ZExtInst) \ macro(ExtractValueInst) \ - macro(FreeInst) \ macro(LoadInst) \ macro(VAArgInst) diff --git a/include/llvm/Analysis/AliasSetTracker.h b/include/llvm/Analysis/AliasSetTracker.h index 239f30f9384..42a377e1416 100644 --- a/include/llvm/Analysis/AliasSetTracker.h +++ b/include/llvm/Analysis/AliasSetTracker.h @@ -29,7 +29,6 @@ namespace llvm { class AliasAnalysis; class LoadInst; class StoreInst; -class FreeInst; class VAArgInst; class AliasSetTracker; class AliasSet; @@ -298,7 +297,6 @@ public: bool add(Value *Ptr, unsigned Size); // Add a location bool add(LoadInst *LI); bool add(StoreInst *SI); - bool add(FreeInst *FI); bool add(VAArgInst *VAAI); bool add(CallSite CS); // Call/Invoke instructions bool add(CallInst *CI) { return add(CallSite(CI)); } @@ -313,7 +311,6 @@ public: bool remove(Value *Ptr, unsigned Size); // Remove a location bool remove(LoadInst *LI); bool remove(StoreInst *SI); - bool remove(FreeInst *FI); bool remove(VAArgInst *VAAI); bool remove(CallSite CS); bool remove(CallInst *CI) { return remove(CallSite(CI)); } diff --git a/include/llvm/Analysis/MallocHelper.h b/include/llvm/Analysis/MallocHelper.h index be307c02aed..22cf1b58bb2 100644 --- a/include/llvm/Analysis/MallocHelper.h +++ b/include/llvm/Analysis/MallocHelper.h @@ -1,4 +1,4 @@ -//===- llvm/Analysis/MallocHelper.h ---- Identify malloc calls --*- C++ -*-===// +//===- llvm/Analysis/MallocFreeHelper.h - Identify malloc/free --*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -8,7 +8,8 @@ //===----------------------------------------------------------------------===// // // This family of functions identifies calls to malloc, bitcasts of malloc -// calls, and the types and array sizes associated with them. +// calls, and the types and array sizes associated with them. It also +// identifies calls to the free builtin. // //===----------------------------------------------------------------------===// diff --git a/include/llvm/InstrTypes.h b/include/llvm/InstrTypes.h index 6b84857c89e..e83acba82e8 100644 --- a/include/llvm/InstrTypes.h +++ b/include/llvm/InstrTypes.h @@ -117,7 +117,6 @@ public: static inline bool classof(const UnaryInstruction *) { return true; } static inline bool classof(const Instruction *I) { return I->getOpcode() == Instruction::Alloca || - I->getOpcode() == Instruction::Free || I->getOpcode() == Instruction::Load || I->getOpcode() == Instruction::VAArg || I->getOpcode() == Instruction::ExtractValue || diff --git a/include/llvm/Instruction.def b/include/llvm/Instruction.def index 5c8fe3eaccd..ec86b35364e 100644 --- a/include/llvm/Instruction.def +++ b/include/llvm/Instruction.def @@ -128,48 +128,47 @@ HANDLE_BINARY_INST(24, Xor , BinaryOperator) // Memory operators... FIRST_MEMORY_INST(25) -HANDLE_MEMORY_INST(25, Free , FreeInst ) // Heap management instructions -HANDLE_MEMORY_INST(26, Alloca, AllocaInst) // Stack management -HANDLE_MEMORY_INST(27, Load , LoadInst ) // Memory manipulation instrs -HANDLE_MEMORY_INST(28, Store , StoreInst ) -HANDLE_MEMORY_INST(29, GetElementPtr, GetElementPtrInst) - LAST_MEMORY_INST(29) +HANDLE_MEMORY_INST(25, Alloca, AllocaInst) // Stack management +HANDLE_MEMORY_INST(26, Load , LoadInst ) // Memory manipulation instrs +HANDLE_MEMORY_INST(27, Store , StoreInst ) +HANDLE_MEMORY_INST(28, GetElementPtr, GetElementPtrInst) + LAST_MEMORY_INST(28) // Cast operators ... // NOTE: The order matters here because CastInst::isEliminableCastPair // NOTE: (see Instructions.cpp) encodes a table based on this ordering. - FIRST_CAST_INST(30) -HANDLE_CAST_INST(30, Trunc , TruncInst ) // Truncate integers -HANDLE_CAST_INST(31, ZExt , ZExtInst ) // Zero extend integers -HANDLE_CAST_INST(32, SExt , SExtInst ) // Sign extend integers -HANDLE_CAST_INST(33, FPToUI , FPToUIInst ) // floating point -> UInt -HANDLE_CAST_INST(34, FPToSI , FPToSIInst ) // floating point -> SInt -HANDLE_CAST_INST(35, UIToFP , UIToFPInst ) // UInt -> floating point -HANDLE_CAST_INST(36, SIToFP , SIToFPInst ) // SInt -> floating point -HANDLE_CAST_INST(37, FPTrunc , FPTruncInst ) // Truncate floating point -HANDLE_CAST_INST(38, FPExt , FPExtInst ) // Extend floating point -HANDLE_CAST_INST(39, PtrToInt, PtrToIntInst) // Pointer -> Integer -HANDLE_CAST_INST(40, IntToPtr, IntToPtrInst) // Integer -> Pointer -HANDLE_CAST_INST(41, BitCast , BitCastInst ) // Type cast - LAST_CAST_INST(41) + FIRST_CAST_INST(29) +HANDLE_CAST_INST(29, Trunc , TruncInst ) // Truncate integers +HANDLE_CAST_INST(30, ZExt , ZExtInst ) // Zero extend integers +HANDLE_CAST_INST(31, SExt , SExtInst ) // Sign extend integers +HANDLE_CAST_INST(32, FPToUI , FPToUIInst ) // floating point -> UInt +HANDLE_CAST_INST(33, FPToSI , FPToSIInst ) // floating point -> SInt +HANDLE_CAST_INST(34, UIToFP , UIToFPInst ) // UInt -> floating point +HANDLE_CAST_INST(35, SIToFP , SIToFPInst ) // SInt -> floating point +HANDLE_CAST_INST(36, FPTrunc , FPTruncInst ) // Truncate floating point +HANDLE_CAST_INST(37, FPExt , FPExtInst ) // Extend floating point +HANDLE_CAST_INST(38, PtrToInt, PtrToIntInst) // Pointer -> Integer +HANDLE_CAST_INST(39, IntToPtr, IntToPtrInst) // Integer -> Pointer +HANDLE_CAST_INST(40, BitCast , BitCastInst ) // Type cast + LAST_CAST_INST(40) // Other operators... - FIRST_OTHER_INST(42) -HANDLE_OTHER_INST(42, ICmp , ICmpInst ) // Integer comparison instruction -HANDLE_OTHER_INST(43, FCmp , FCmpInst ) // Floating point comparison instr. -HANDLE_OTHER_INST(44, PHI , PHINode ) // PHI node instruction -HANDLE_OTHER_INST(45, Call , CallInst ) // Call a function -HANDLE_OTHER_INST(46, Select , SelectInst ) // select instruction -HANDLE_OTHER_INST(47, UserOp1, Instruction) // May be used internally in a pass -HANDLE_OTHER_INST(48, UserOp2, Instruction) // Internal to passes only -HANDLE_OTHER_INST(49, VAArg , VAArgInst ) // vaarg instruction -HANDLE_OTHER_INST(50, ExtractElement, ExtractElementInst)// extract from vector -HANDLE_OTHER_INST(51, InsertElement, InsertElementInst) // insert into vector -HANDLE_OTHER_INST(52, ShuffleVector, ShuffleVectorInst) // shuffle two vectors. -HANDLE_OTHER_INST(53, ExtractValue, ExtractValueInst)// extract from aggregate -HANDLE_OTHER_INST(54, InsertValue, InsertValueInst) // insert into aggregate + FIRST_OTHER_INST(41) +HANDLE_OTHER_INST(41, ICmp , ICmpInst ) // Integer comparison instruction +HANDLE_OTHER_INST(42, FCmp , FCmpInst ) // Floating point comparison instr. +HANDLE_OTHER_INST(43, PHI , PHINode ) // PHI node instruction +HANDLE_OTHER_INST(44, Call , CallInst ) // Call a function +HANDLE_OTHER_INST(45, Select , SelectInst ) // select instruction +HANDLE_OTHER_INST(46, UserOp1, Instruction) // May be used internally in a pass +HANDLE_OTHER_INST(47, UserOp2, Instruction) // Internal to passes only +HANDLE_OTHER_INST(48, VAArg , VAArgInst ) // vaarg instruction +HANDLE_OTHER_INST(49, ExtractElement, ExtractElementInst)// extract from vector +HANDLE_OTHER_INST(50, InsertElement, InsertElementInst) // insert into vector +HANDLE_OTHER_INST(51, ShuffleVector, ShuffleVectorInst) // shuffle two vectors. +HANDLE_OTHER_INST(52, ExtractValue, ExtractValueInst)// extract from aggregate +HANDLE_OTHER_INST(53, InsertValue, InsertValueInst) // insert into aggregate - LAST_OTHER_INST(54) + LAST_OTHER_INST(53) #undef FIRST_TERM_INST #undef HANDLE_TERM_INST diff --git a/include/llvm/Instructions.h b/include/llvm/Instructions.h index 1e2c93fe870..7cb6786acac 100644 --- a/include/llvm/Instructions.h +++ b/include/llvm/Instructions.h @@ -103,35 +103,6 @@ public: }; -//===----------------------------------------------------------------------===// -// FreeInst Class -//===----------------------------------------------------------------------===// - -/// FreeInst - an instruction to deallocate memory -/// -class FreeInst : public UnaryInstruction { - void AssertOK(); -public: - explicit FreeInst(Value *Ptr, Instruction *InsertBefore = 0); - FreeInst(Value *Ptr, BasicBlock *InsertAfter); - - virtual FreeInst *clone() const; - - // Accessor methods for consistency with other memory operations - Value *getPointerOperand() { return getOperand(0); } - const Value *getPointerOperand() const { return getOperand(0); } - - // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const FreeInst *) { return true; } - static inline bool classof(const Instruction *I) { - return (I->getOpcode() == Instruction::Free); - } - static inline bool classof(const Value *V) { - return isa(V) && classof(cast(V)); - } -}; - - //===----------------------------------------------------------------------===// // LoadInst Class //===----------------------------------------------------------------------===// diff --git a/include/llvm/LinkAllPasses.h b/include/llvm/LinkAllPasses.h index bc5722e82e9..28538b72b86 100644 --- a/include/llvm/LinkAllPasses.h +++ b/include/llvm/LinkAllPasses.h @@ -91,7 +91,6 @@ namespace { (void) llvm::createLoopUnswitchPass(); (void) llvm::createLoopRotatePass(); (void) llvm::createLoopIndexSplitPass(); - (void) llvm::createLowerAllocationsPass(); (void) llvm::createLowerInvokePass(); (void) llvm::createLowerSetJmpPass(); (void) llvm::createLowerSwitchPass(); diff --git a/include/llvm/Support/IRBuilder.h b/include/llvm/Support/IRBuilder.h index 83df9edc0c4..84bfd09b001 100644 --- a/include/llvm/Support/IRBuilder.h +++ b/include/llvm/Support/IRBuilder.h @@ -433,9 +433,6 @@ public: const Twine &Name = "") { return Insert(new AllocaInst(Ty, ArraySize), Name); } - FreeInst *CreateFree(Value *Ptr) { - return Insert(new FreeInst(Ptr)); - } // Provided to resolve 'CreateLoad(Ptr, "...")' correctly, instead of // converting the string to 'bool' for the isVolatile parameter. LoadInst *CreateLoad(Value *Ptr, const char *Name) { diff --git a/include/llvm/Support/InstVisitor.h b/include/llvm/Support/InstVisitor.h index 1e34e6633d2..ae35a3c281a 100644 --- a/include/llvm/Support/InstVisitor.h +++ b/include/llvm/Support/InstVisitor.h @@ -166,7 +166,6 @@ public: RetTy visitICmpInst(ICmpInst &I) { DELEGATE(CmpInst);} RetTy visitFCmpInst(FCmpInst &I) { DELEGATE(CmpInst);} RetTy visitAllocaInst(AllocaInst &I) { DELEGATE(Instruction); } - RetTy visitFreeInst(FreeInst &I) { DELEGATE(Instruction); } RetTy visitLoadInst(LoadInst &I) { DELEGATE(Instruction); } RetTy visitStoreInst(StoreInst &I) { DELEGATE(Instruction); } RetTy visitGetElementPtrInst(GetElementPtrInst &I){ DELEGATE(Instruction); } diff --git a/include/llvm/Transforms/Scalar.h b/include/llvm/Transforms/Scalar.h index c5378994fdc..f700c49d55e 100644 --- a/include/llvm/Transforms/Scalar.h +++ b/include/llvm/Transforms/Scalar.h @@ -223,15 +223,6 @@ extern const PassInfo *const BreakCriticalEdgesID; Pass *createLoopSimplifyPass(); extern const PassInfo *const LoopSimplifyID; -//===----------------------------------------------------------------------===// -// -// LowerAllocations - Turn free instructions into @free calls. -// -// AU.addRequiredID(LowerAllocationsID); -// -Pass *createLowerAllocationsPass(); -extern const PassInfo *const LowerAllocationsID; - //===----------------------------------------------------------------------===// // // TailCallElimination - This pass eliminates call instructions to the current diff --git a/lib/Analysis/AliasSetTracker.cpp b/lib/Analysis/AliasSetTracker.cpp index 081f47854a4..5b1b7d18142 100644 --- a/lib/Analysis/AliasSetTracker.cpp +++ b/lib/Analysis/AliasSetTracker.cpp @@ -13,6 +13,7 @@ #include "llvm/Analysis/AliasSetTracker.h" #include "llvm/Analysis/AliasAnalysis.h" +#include "llvm/Analysis/MallocHelper.h" #include "llvm/Instructions.h" #include "llvm/IntrinsicInst.h" #include "llvm/Pass.h" @@ -296,12 +297,6 @@ bool AliasSetTracker::add(StoreInst *SI) { return NewPtr; } -bool AliasSetTracker::add(FreeInst *FI) { - bool NewPtr; - addPointer(FI->getOperand(0), ~0, AliasSet::Mods, NewPtr); - return NewPtr; -} - bool AliasSetTracker::add(VAArgInst *VAAI) { bool NewPtr; addPointer(VAAI->getOperand(0), ~0, AliasSet::ModRef, NewPtr); @@ -310,6 +305,13 @@ bool AliasSetTracker::add(VAArgInst *VAAI) { bool AliasSetTracker::add(CallSite CS) { + Instruction* Inst = CS.getInstruction(); + if (isFreeCall(Inst)) { + bool NewPtr; + addPointer(Inst->getOperand(1), ~0, AliasSet::Mods, NewPtr); + return NewPtr; + } + if (isa(CS.getInstruction())) return true; // Ignore DbgInfo Intrinsics. if (AA.doesNotAccessMemory(CS)) @@ -337,8 +339,6 @@ bool AliasSetTracker::add(Instruction *I) { return add(CI); else if (InvokeInst *II = dyn_cast(I)) return add(II); - else if (FreeInst *FI = dyn_cast(I)) - return add(FI); else if (VAArgInst *VAAI = dyn_cast(I)) return add(VAAI); return true; @@ -427,13 +427,6 @@ bool AliasSetTracker::remove(StoreInst *SI) { return true; } -bool AliasSetTracker::remove(FreeInst *FI) { - AliasSet *AS = findAliasSetForPointer(FI->getOperand(0), ~0); - if (!AS) return false; - remove(*AS); - return true; -} - bool AliasSetTracker::remove(VAArgInst *VAAI) { AliasSet *AS = findAliasSetForPointer(VAAI->getOperand(0), ~0); if (!AS) return false; @@ -442,6 +435,14 @@ bool AliasSetTracker::remove(VAArgInst *VAAI) { } bool AliasSetTracker::remove(CallSite CS) { + Instruction* Inst = CS.getInstruction(); + if (isFreeCall(Inst)) { + AliasSet *AS = findAliasSetForPointer(Inst->getOperand(1), ~0); + if (!AS) return false; + remove(*AS); + return true; + } + if (AA.doesNotAccessMemory(CS)) return false; // doesn't alias anything @@ -459,8 +460,6 @@ bool AliasSetTracker::remove(Instruction *I) { return remove(SI); else if (CallInst *CI = dyn_cast(I)) return remove(CI); - else if (FreeInst *FI = dyn_cast(I)) - return remove(FI); else if (VAArgInst *VAAI = dyn_cast(I)) return remove(VAAI); return true; diff --git a/lib/Analysis/CaptureTracking.cpp b/lib/Analysis/CaptureTracking.cpp index b30ac719ae0..649b760b706 100644 --- a/lib/Analysis/CaptureTracking.cpp +++ b/lib/Analysis/CaptureTracking.cpp @@ -17,6 +17,7 @@ //===----------------------------------------------------------------------===// #include "llvm/Analysis/CaptureTracking.h" +#include "llvm/Analysis/MallocHelper.h" #include "llvm/Instructions.h" #include "llvm/Value.h" #include "llvm/ADT/SmallSet.h" @@ -48,6 +49,9 @@ bool llvm::PointerMayBeCaptured(const Value *V, bool ReturnCaptures) { switch (I->getOpcode()) { case Instruction::Call: + if (isFreeCall(I)) + // Freeing a pointer does not cause it to be captured. + break; case Instruction::Invoke: { CallSite CS = CallSite::get(I); // Not captured if the callee is readonly, doesn't return a copy through @@ -73,9 +77,6 @@ bool llvm::PointerMayBeCaptured(const Value *V, bool ReturnCaptures) { // captured. break; } - case Instruction::Free: - // Freeing a pointer does not cause it to be captured. - break; case Instruction::Load: // Loading from a pointer does not cause it to be captured. break; diff --git a/lib/Analysis/IPA/Andersens.cpp b/lib/Analysis/IPA/Andersens.cpp index 637234251ea..78ec06f21ca 100644 --- a/lib/Analysis/IPA/Andersens.cpp +++ b/lib/Analysis/IPA/Andersens.cpp @@ -1016,7 +1016,7 @@ bool Andersens::AnalyzeUsesOfFunction(Value *V) { } } else if (GetElementPtrInst *GEP = dyn_cast(*UI)) { if (AnalyzeUsesOfFunction(GEP)) return true; - } else if (isa(*UI) || isFreeCall(*UI)) { + } else if (isFreeCall(*UI)) { return false; } else if (CallInst *CI = dyn_cast(*UI)) { // Make sure that this is just the function being called, not that it is @@ -1156,7 +1156,6 @@ void Andersens::visitInstruction(Instruction &I) { case Instruction::Switch: case Instruction::Unwind: case Instruction::Unreachable: - case Instruction::Free: case Instruction::ICmp: case Instruction::FCmp: return; diff --git a/lib/Analysis/IPA/GlobalsModRef.cpp b/lib/Analysis/IPA/GlobalsModRef.cpp index 01090f11cb2..011b0ef6e1d 100644 --- a/lib/Analysis/IPA/GlobalsModRef.cpp +++ b/lib/Analysis/IPA/GlobalsModRef.cpp @@ -238,7 +238,7 @@ bool GlobalsModRef::AnalyzeUsesOfPointer(Value *V, } else if (BitCastInst *BCI = dyn_cast(*UI)) { if (AnalyzeUsesOfPointer(BCI, Readers, Writers, OkayStoreDest)) return true; - } else if (isa(*UI) || isFreeCall(*UI)) { + } else if (isFreeCall(*UI)) { Writers.push_back(cast(*UI)->getParent()->getParent()); } else if (CallInst *CI = dyn_cast(*UI)) { // Make sure that this is just the function being called, not that it is @@ -437,7 +437,7 @@ void GlobalsModRef::AnalyzeCallGraph(CallGraph &CG, Module &M) { if (cast(*II).isVolatile()) // Treat volatile stores as reading memory somewhere. FunctionEffect |= Ref; - } else if (isMalloc(&cast(*II)) || isa(*II) || + } else if (isMalloc(&cast(*II)) || isFreeCall(&cast(*II))) { FunctionEffect |= ModRef; } diff --git a/lib/Analysis/InlineCost.cpp b/lib/Analysis/InlineCost.cpp index 4f010b658ef..febdd9101c8 100644 --- a/lib/Analysis/InlineCost.cpp +++ b/lib/Analysis/InlineCost.cpp @@ -130,10 +130,6 @@ void CodeMetrics::analyzeBasicBlock(const BasicBlock *BB) { NumInsts += InlineConstants::CallPenalty; } - // These, too, are calls. - if (isa(II)) - NumInsts += InlineConstants::CallPenalty; - if (const AllocaInst *AI = dyn_cast(II)) { if (!AI->isStaticAlloca()) this->usesDynamicAlloca = true; diff --git a/lib/Analysis/InstCount.cpp b/lib/Analysis/InstCount.cpp index c4f3b682119..a4b041f02a3 100644 --- a/lib/Analysis/InstCount.cpp +++ b/lib/Analysis/InstCount.cpp @@ -74,11 +74,11 @@ FunctionPass *llvm::createInstCountPass() { return new InstCount(); } bool InstCount::runOnFunction(Function &F) { unsigned StartMemInsts = NumGetElementPtrInst + NumLoadInst + NumStoreInst + NumCallInst + - NumInvokeInst + NumAllocaInst + NumFreeInst; + NumInvokeInst + NumAllocaInst; visit(F); unsigned EndMemInsts = NumGetElementPtrInst + NumLoadInst + NumStoreInst + NumCallInst + - NumInvokeInst + NumAllocaInst + NumFreeInst; + NumInvokeInst + NumAllocaInst; TotalMemInst += EndMemInsts-StartMemInsts; return false; } diff --git a/lib/Analysis/MallocHelper.cpp b/lib/Analysis/MallocHelper.cpp index 511de9d6a51..70afa88ac6c 100644 --- a/lib/Analysis/MallocHelper.cpp +++ b/lib/Analysis/MallocHelper.cpp @@ -1,4 +1,4 @@ -//===-- MallocHelper.cpp - Functions to identify malloc calls -------------===// +//===-- MallocFreeHelper.cpp - Identify calls to malloc and free builtins -===// // // The LLVM Compiler Infrastructure // @@ -8,7 +8,8 @@ //===----------------------------------------------------------------------===// // // This family of functions identifies calls to malloc, bitcasts of malloc -// calls, and the types and array sizes associated with them. +// calls, and the types and array sizes associated with them. It also +// identifies calls to the free builtin. // //===----------------------------------------------------------------------===// @@ -264,6 +265,10 @@ Value* llvm::getMallocArraySize(CallInst* CI, LLVMContext &Context, return BO->getOperand(0); } +//===----------------------------------------------------------------------===// +// free Call Utility Functions. +// + /// isFreeCall - Returns true if the the value is a call to the builtin free() bool llvm::isFreeCall(const Value* I) { const CallInst *CI = dyn_cast(I); diff --git a/lib/Analysis/MemoryDependenceAnalysis.cpp b/lib/Analysis/MemoryDependenceAnalysis.cpp index ce7674003fe..7b3fe64a4af 100644 --- a/lib/Analysis/MemoryDependenceAnalysis.cpp +++ b/lib/Analysis/MemoryDependenceAnalysis.cpp @@ -113,10 +113,9 @@ getCallSiteDependencyFrom(CallSite CS, bool isReadOnlyCall, } else if (VAArgInst *V = dyn_cast(Inst)) { Pointer = V->getOperand(0); PointerSize = AA->getTypeStoreSize(V->getType()); - } else if (FreeInst *F = dyn_cast(Inst)) { - Pointer = F->getPointerOperand(); - - // FreeInsts erase the entire structure + } else if (isFreeCall(Inst)) { + Pointer = Inst->getOperand(1); + // calls to free() erase the entire structure PointerSize = ~0ULL; } else if (isFreeCall(Inst)) { Pointer = Inst->getOperand(0); @@ -319,7 +318,7 @@ MemDepResult MemoryDependenceAnalysis::getDependency(Instruction *QueryInst) { MemSize = AA->getTypeStoreSize(LI->getType()); } } else if (isFreeCall(QueryInst)) { - MemPtr = QueryInst->getOperand(0); + MemPtr = QueryInst->getOperand(1); // calls to free() erase the entire structure, not just a field. MemSize = ~0UL; } else if (isa(QueryInst) || isa(QueryInst)) { @@ -327,10 +326,6 @@ MemDepResult MemoryDependenceAnalysis::getDependency(Instruction *QueryInst) { bool isReadOnly = AA->onlyReadsMemory(QueryCS); LocalCache = getCallSiteDependencyFrom(QueryCS, isReadOnly, ScanPos, QueryParent); - } else if (FreeInst *FI = dyn_cast(QueryInst)) { - MemPtr = FI->getPointerOperand(); - // FreeInsts erase the entire structure, not just a field. - MemSize = ~0UL; } else { // Non-memory instruction. LocalCache = MemDepResult::getClobber(--BasicBlock::iterator(ScanPos)); diff --git a/lib/AsmParser/LLLexer.cpp b/lib/AsmParser/LLLexer.cpp index f6cea8887c9..4fb7ea9e29f 100644 --- a/lib/AsmParser/LLLexer.cpp +++ b/lib/AsmParser/LLLexer.cpp @@ -606,6 +606,10 @@ lltok::Kind LLLexer::LexIdentifier() { // FIXME: Remove in LLVM 3.0. // Autoupgrade malloc instruction. return lltok::kw_malloc; + } else if (Len == 4 && !memcmp(StartChar, "free", 4)) { + // FIXME: Remove in LLVM 3.0. + // Autoupgrade malloc instruction. + return lltok::kw_free; } // Keywords for instructions. @@ -646,7 +650,6 @@ lltok::Kind LLLexer::LexIdentifier() { INSTKEYWORD(unreachable, Unreachable); INSTKEYWORD(alloca, Alloca); - INSTKEYWORD(free, Free); INSTKEYWORD(load, Load); INSTKEYWORD(store, Store); INSTKEYWORD(getelementptr, GetElementPtr); diff --git a/lib/Bitcode/Writer/BitcodeWriter.cpp b/lib/Bitcode/Writer/BitcodeWriter.cpp index 037854e26fa..535740b3fb5 100644 --- a/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -1054,11 +1054,6 @@ static void WriteInstruction(const Instruction &I, unsigned InstID, Vals.push_back(VE.getValueID(I.getOperand(i))); break; - case Instruction::Free: - Code = bitc::FUNC_CODE_INST_FREE; - PushValueAndType(I.getOperand(0), InstID, Vals, VE); - break; - case Instruction::Alloca: Code = bitc::FUNC_CODE_INST_ALLOCA; Vals.push_back(VE.getTypeID(I.getType())); diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp index d862e406031..f3a06221578 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp @@ -5486,26 +5486,6 @@ void SelectionDAGLowering::visitInlineAsm(CallSite CS) { DAG.setRoot(Chain); } -void SelectionDAGLowering::visitFree(FreeInst &I) { - TargetLowering::ArgListTy Args; - TargetLowering::ArgListEntry Entry; - Entry.Node = getValue(I.getOperand(0)); - Entry.Ty = TLI.getTargetData()->getIntPtrType(*DAG.getContext()); - Args.push_back(Entry); - EVT IntPtr = TLI.getPointerTy(); - bool isTailCall = PerformTailCallOpt && - isInTailCallPosition(&I, Attribute::None, TLI); - std::pair Result = - TLI.LowerCallTo(getRoot(), Type::getVoidTy(*DAG.getContext()), - false, false, false, false, - 0, CallingConv::C, isTailCall, - /*isReturnValueUsed=*/true, - DAG.getExternalSymbol("free", IntPtr), Args, DAG, - getCurDebugLoc()); - if (Result.second.getNode()) - DAG.setRoot(Result.second); -} - void SelectionDAGLowering::visitVAStart(CallInst &I) { DAG.setRoot(DAG.getNode(ISD::VASTART, getCurDebugLoc(), MVT::Other, getRoot(), diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuild.h b/lib/CodeGen/SelectionDAG/SelectionDAGBuild.h index 722b1d82551..74705514de6 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGBuild.h +++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuild.h @@ -44,7 +44,6 @@ class FPExtInst; class FPToSIInst; class FPToUIInst; class FPTruncInst; -class FreeInst; class Function; class GetElementPtrInst; class GCFunctionInfo; @@ -528,7 +527,6 @@ private: void visitGetElementPtr(User &I); void visitSelect(User &I); - void visitFree(FreeInst &I); void visitAlloca(AllocaInst &I); void visitLoad(LoadInst &I); void visitStore(StoreInst &I); diff --git a/lib/ExecutionEngine/Interpreter/Execution.cpp b/lib/ExecutionEngine/Interpreter/Execution.cpp index 151bd00de38..7ceb8e8c54b 100644 --- a/lib/ExecutionEngine/Interpreter/Execution.cpp +++ b/lib/ExecutionEngine/Interpreter/Execution.cpp @@ -749,14 +749,6 @@ void Interpreter::visitAllocaInst(AllocaInst &I) { ECStack.back().Allocas.add(Memory); } -void Interpreter::visitFreeInst(FreeInst &I) { - ExecutionContext &SF = ECStack.back(); - assert(isa(I.getOperand(0)->getType()) && "Freeing nonptr?"); - GenericValue Value = getOperandValue(I.getOperand(0), SF); - // TODO: Check to make sure memory is allocated - free(GVTOP(Value)); // Free memory -} - // getElementOffset - The workhorse for getelementptr. // GenericValue Interpreter::executeGEPOperation(Value *Ptr, gep_type_iterator I, diff --git a/lib/ExecutionEngine/Interpreter/Interpreter.h b/lib/ExecutionEngine/Interpreter/Interpreter.h index 43c18d08524..eaa8ec5c38b 100644 --- a/lib/ExecutionEngine/Interpreter/Interpreter.h +++ b/lib/ExecutionEngine/Interpreter/Interpreter.h @@ -140,7 +140,6 @@ public: void visitICmpInst(ICmpInst &I); void visitFCmpInst(FCmpInst &I); void visitAllocaInst(AllocaInst &I); - void visitFreeInst(FreeInst &I); void visitLoadInst(LoadInst &I); void visitStoreInst(StoreInst &I); void visitGetElementPtrInst(GetElementPtrInst &I); diff --git a/lib/Target/CBackend/CBackend.cpp b/lib/Target/CBackend/CBackend.cpp index 27ed5c3ea8e..fb61651b3dc 100644 --- a/lib/Target/CBackend/CBackend.cpp +++ b/lib/Target/CBackend/CBackend.cpp @@ -303,7 +303,6 @@ namespace { bool visitBuiltinCall(CallInst &I, Intrinsic::ID ID, bool &WroteCallee); void visitAllocaInst(AllocaInst &I); - void visitFreeInst (FreeInst &I); void visitLoadInst (LoadInst &I); void visitStoreInst (StoreInst &I); void visitGetElementPtrInst(GetElementPtrInst &I); @@ -3417,10 +3416,6 @@ void CWriter::visitAllocaInst(AllocaInst &I) { Out << ')'; } -void CWriter::visitFreeInst(FreeInst &I) { - llvm_unreachable("lowerallocations pass didn't work!"); -} - void CWriter::printGEPExpression(Value *Ptr, gep_type_iterator I, gep_type_iterator E, bool Static) { @@ -3685,7 +3680,6 @@ bool CTargetMachine::addPassesToEmitWholeFile(PassManager &PM, if (FileType != TargetMachine::AssemblyFile) return true; PM.add(createGCLoweringPass()); - PM.add(createLowerAllocationsPass()); PM.add(createLowerInvokePass()); PM.add(createCFGSimplificationPass()); // clean up after lower invoke. PM.add(new CBackendNameAllUsedStructsAndMergeFunctions()); diff --git a/lib/Target/CppBackend/CPPBackend.cpp b/lib/Target/CppBackend/CPPBackend.cpp index 45c2a7b1e33..9a6aa6366c5 100644 --- a/lib/Target/CppBackend/CPPBackend.cpp +++ b/lib/Target/CppBackend/CPPBackend.cpp @@ -1258,11 +1258,6 @@ namespace { Out << "\");"; break; } - case Instruction::Free: { - Out << "FreeInst* " << iName << " = new FreeInst(" - << getCppName(I->getOperand(0)) << ", " << bbname << ");"; - break; - } case Instruction::Alloca: { const AllocaInst* allocaI = cast(I); Out << "AllocaInst* " << iName << " = new AllocaInst(" diff --git a/lib/Target/MSIL/MSILWriter.cpp b/lib/Target/MSIL/MSILWriter.cpp index 5899ab3629c..f12ee78ccb4 100644 --- a/lib/Target/MSIL/MSILWriter.cpp +++ b/lib/Target/MSIL/MSILWriter.cpp @@ -1191,9 +1191,6 @@ void MSILWriter::printInstruction(const Instruction* Inst) { case Instruction::Alloca: printAllocaInstruction(cast(Inst)); break; - case Instruction::Free: - llvm_unreachable("LowerAllocationsPass used"); - break; case Instruction::Unreachable: printSimpleInstruction("ldstr", "\"Unreachable instruction\""); printSimpleInstruction("newobj", @@ -1699,7 +1696,6 @@ bool MSILTarget::addPassesToEmitWholeFile(PassManager &PM, if (FileType != TargetMachine::AssemblyFile) return true; MSILWriter* Writer = new MSILWriter(o); PM.add(createGCLoweringPass()); - PM.add(createLowerAllocationsPass()); // FIXME: Handle switch trougth native IL instruction "switch" PM.add(createLowerSwitchPass()); PM.add(createCFGSimplificationPass()); diff --git a/lib/Transforms/Scalar/DeadStoreElimination.cpp b/lib/Transforms/Scalar/DeadStoreElimination.cpp index f55d8b2accb..c10d236cda6 100644 --- a/lib/Transforms/Scalar/DeadStoreElimination.cpp +++ b/lib/Transforms/Scalar/DeadStoreElimination.cpp @@ -89,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(Inst) && !isa(Inst) && !isFreeCall(Inst)) + if (!isa(Inst) && !isFreeCall(Inst)) continue; // Don't molest volatile stores or do queries that will return "clobber". @@ -104,7 +104,7 @@ bool DSE::runOnBasicBlock(BasicBlock &BB) { if (InstDep.isNonLocal()) continue; // Handle frees whose dependencies are non-trivial. - if (isa(Inst) || isFreeCall(Inst)) { + if (isFreeCall(Inst)) { MadeChange |= handleFreeWithNonTrivialDependency(Inst, InstDep); continue; } @@ -176,8 +176,7 @@ bool DSE::handleFreeWithNonTrivialDependency(Instruction *F, MemDepResult Dep) { Value *DepPointer = Dependency->getPointerOperand()->getUnderlyingObject(); // Check for aliasing. - Value* FreeVal = isa(F) ? F->getOperand(0) : F->getOperand(1); - if (AA.alias(FreeVal, 1, DepPointer, 1) != + if (AA.alias(F->getOperand(1), 1, DepPointer, 1) != AliasAnalysis::MustAlias) return false; diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp index 7c0d22359fd..fa84bb5c493 100644 --- a/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/lib/Transforms/Scalar/InstructionCombining.cpp @@ -285,7 +285,6 @@ namespace { Instruction *visitPHINode(PHINode &PN); Instruction *visitGetElementPtrInst(GetElementPtrInst &GEP); Instruction *visitAllocaInst(AllocaInst &AI); - Instruction *visitFreeInst(FreeInst &FI); Instruction *visitFree(Instruction &FI); Instruction *visitLoadInst(LoadInst &LI); Instruction *visitStoreInst(StoreInst &SI); @@ -11328,56 +11327,6 @@ Instruction *InstCombiner::visitAllocaInst(AllocaInst &AI) { return 0; } -Instruction *InstCombiner::visitFreeInst(FreeInst &FI) { - Value *Op = FI.getOperand(0); - - // free undef -> unreachable. - if (isa(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(Op)) - return EraseInstFromFunction(FI); - - // Change free * (cast * X to *) into free * X - if (BitCastInst *CI = dyn_cast(Op)) { - FI.setOperand(0, CI->getOperand(0)); - return &FI; - } - - // Change free (gep X, 0,0,0,0) into free(X) - if (GetElementPtrInst *GEPI = dyn_cast(Op)) { - if (GEPI->hasAllZeroIndices()) { - Worklist.Add(GEPI); - FI.setOperand(0, GEPI->getOperand(0)); - return &FI; - } - } - - if (isMalloc(Op)) { - if (CallInst* CI = extractMallocCallFromBitCast(Op)) { - if (Op->hasOneUse() && CI->hasOneUse()) { - EraseInstFromFunction(FI); - EraseInstFromFunction(*CI); - return EraseInstFromFunction(*cast(Op)); - } - } else { - // Op is a call to malloc - if (Op->hasOneUse()) { - EraseInstFromFunction(FI); - return EraseInstFromFunction(*cast(Op)); - } - } - } - - return 0; -} - Instruction *InstCombiner::visitFree(Instruction &FI) { Value *Op = FI.getOperand(1); @@ -11394,9 +11343,8 @@ Instruction *InstCombiner::visitFree(Instruction &FI) { if (isa(Op)) return EraseInstFromFunction(FI); - // FIXME: Bring back free (gep X, 0,0,0,0) into free(X) transform - - if (isMalloc(Op)) { + // If we have a malloc call whose only use is a free call, delete both. + if (isMalloc(Op)) if (CallInst* CI = extractMallocCallFromBitCast(Op)) { if (Op->hasOneUse() && CI->hasOneUse()) { EraseInstFromFunction(FI); @@ -11410,7 +11358,6 @@ Instruction *InstCombiner::visitFree(Instruction &FI) { return EraseInstFromFunction(*cast(Op)); } } - } return 0; } diff --git a/lib/Transforms/Scalar/SCCP.cpp b/lib/Transforms/Scalar/SCCP.cpp index 1bb5f4ae7fd..4c561217f89 100644 --- a/lib/Transforms/Scalar/SCCP.cpp +++ b/lib/Transforms/Scalar/SCCP.cpp @@ -416,7 +416,6 @@ private: void visitAllocaInst (Instruction &I) { markOverdefined(&I); } void visitVANextInst (Instruction &I) { markOverdefined(&I); } void visitVAArgInst (Instruction &I) { markOverdefined(&I); } - void visitFreeInst (Instruction &I) { /*returns void*/ } void visitInstruction(Instruction &I) { // If a new instruction is added to LLVM that we don't handle... diff --git a/lib/Transforms/Utils/CMakeLists.txt b/lib/Transforms/Utils/CMakeLists.txt index f4394ea64d6..fbc61d70e69 100644 --- a/lib/Transforms/Utils/CMakeLists.txt +++ b/lib/Transforms/Utils/CMakeLists.txt @@ -13,7 +13,6 @@ add_llvm_library(LLVMTransformUtils LCSSA.cpp Local.cpp LoopSimplify.cpp - LowerAllocations.cpp LowerInvoke.cpp LowerSwitch.cpp Mem2Reg.cpp diff --git a/lib/Transforms/Utils/Local.cpp b/lib/Transforms/Utils/Local.cpp index 940f5a9ec46..6e18b66898d 100644 --- a/lib/Transforms/Utils/Local.cpp +++ b/lib/Transforms/Utils/Local.cpp @@ -60,9 +60,8 @@ 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(BBI) || isFreeCall(BBI) || - (isa(BBI) && BBI->mayWriteToMemory() && - !isa(BBI))) + if (isFreeCall(BBI) || (isa(BBI) && BBI->mayWriteToMemory() && + !isa(BBI))) return false; if (LoadInst *LI = dyn_cast(BBI)) { diff --git a/lib/Transforms/Utils/LowerAllocations.cpp b/lib/Transforms/Utils/LowerAllocations.cpp deleted file mode 100644 index 5f7bf4c7667..00000000000 --- a/lib/Transforms/Utils/LowerAllocations.cpp +++ /dev/null @@ -1,116 +0,0 @@ -//===- LowerAllocations.cpp - Reduce free insts to calls ------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// The LowerAllocations transformation is a target-dependent tranformation -// because it depends on the size of data types and alignment constraints. -// -//===----------------------------------------------------------------------===// - -#define DEBUG_TYPE "lowerallocs" -#include "llvm/Transforms/Scalar.h" -#include "llvm/Transforms/Utils/UnifyFunctionExitNodes.h" -#include "llvm/Module.h" -#include "llvm/DerivedTypes.h" -#include "llvm/Instructions.h" -#include "llvm/Constants.h" -#include "llvm/LLVMContext.h" -#include "llvm/Pass.h" -#include "llvm/ADT/Statistic.h" -#include "llvm/Target/TargetData.h" -using namespace llvm; - -STATISTIC(NumLowered, "Number of allocations lowered"); - -namespace { - /// LowerAllocations - Turn free instructions into @free calls. - /// - class LowerAllocations : public BasicBlockPass { - Constant *FreeFunc; // Functions in the module we are processing - // Initialized by doInitialization - public: - static char ID; // Pass ID, replacement for typeid - explicit LowerAllocations() - : BasicBlockPass(&ID), FreeFunc(0) {} - - virtual void getAnalysisUsage(AnalysisUsage &AU) const { - AU.addRequired(); - AU.setPreservesCFG(); - - // This is a cluster of orthogonal Transforms: - AU.addPreserved(); - AU.addPreservedID(PromoteMemoryToRegisterID); - AU.addPreservedID(LowerSwitchID); - AU.addPreservedID(LowerInvokePassID); - } - - /// doPassInitialization - For the lower allocations pass, this ensures that - /// a module contains a declaration for a free function. - /// - bool doInitialization(Module &M); - - virtual bool doInitialization(Function &F) { - return doInitialization(*F.getParent()); - } - - /// runOnBasicBlock - This method does the actual work of converting - /// instructions over, assuming that the pass has already been initialized. - /// - bool runOnBasicBlock(BasicBlock &BB); - }; -} - -char LowerAllocations::ID = 0; -static RegisterPass -X("lowerallocs", "Lower allocations from instructions to calls"); - -// Publically exposed interface to pass... -const PassInfo *const llvm::LowerAllocationsID = &X; -// createLowerAllocationsPass - Interface to this file... -Pass *llvm::createLowerAllocationsPass() { - return new LowerAllocations(); -} - - -// doInitialization - For the lower allocations pass, this ensures that a -// module contains a declaration for a free function. -// -// This function is always successful. -// -bool LowerAllocations::doInitialization(Module &M) { - const Type *BPTy = Type::getInt8PtrTy(M.getContext()); - FreeFunc = M.getOrInsertFunction("free" , Type::getVoidTy(M.getContext()), - BPTy, (Type *)0); - return true; -} - -// runOnBasicBlock - This method does the actual work of converting -// instructions over, assuming that the pass has already been initialized. -// -bool LowerAllocations::runOnBasicBlock(BasicBlock &BB) { - bool Changed = false; - assert(FreeFunc && "Pass not initialized!"); - - BasicBlock::InstListType &BBIL = BB.getInstList(); - - // 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(I)) { - // Insert a call to the free function... - CallInst::CreateFree(FI->getOperand(0), I); - - // Delete the old free instruction - I = --BBIL.erase(I); - Changed = true; - ++NumLowered; - } - } - - return Changed; -} - diff --git a/lib/Transforms/Utils/LowerInvoke.cpp b/lib/Transforms/Utils/LowerInvoke.cpp index abb74146c78..6e6e8d2287a 100644 --- a/lib/Transforms/Utils/LowerInvoke.cpp +++ b/lib/Transforms/Utils/LowerInvoke.cpp @@ -86,7 +86,6 @@ namespace { // This is a cluster of orthogonal Transforms AU.addPreservedID(PromoteMemoryToRegisterID); AU.addPreservedID(LowerSwitchID); - AU.addPreservedID(LowerAllocationsID); } private: diff --git a/lib/Transforms/Utils/LowerSwitch.cpp b/lib/Transforms/Utils/LowerSwitch.cpp index bc1779fd27a..8c18b591a49 100644 --- a/lib/Transforms/Utils/LowerSwitch.cpp +++ b/lib/Transforms/Utils/LowerSwitch.cpp @@ -43,7 +43,6 @@ namespace { AU.addPreserved(); AU.addPreservedID(PromoteMemoryToRegisterID); AU.addPreservedID(LowerInvokePassID); - AU.addPreservedID(LowerAllocationsID); } struct CaseRange { diff --git a/lib/Transforms/Utils/Mem2Reg.cpp b/lib/Transforms/Utils/Mem2Reg.cpp index baa7d9ebffc..941660436b4 100644 --- a/lib/Transforms/Utils/Mem2Reg.cpp +++ b/lib/Transforms/Utils/Mem2Reg.cpp @@ -44,7 +44,6 @@ namespace { AU.addPreserved(); AU.addPreservedID(LowerSwitchID); AU.addPreservedID(LowerInvokePassID); - AU.addPreservedID(LowerAllocationsID); } }; } // end of anonymous namespace diff --git a/lib/VMCore/Core.cpp b/lib/VMCore/Core.cpp index a28037d3f28..9a49d424753 100644 --- a/lib/VMCore/Core.cpp +++ b/lib/VMCore/Core.cpp @@ -1724,7 +1724,8 @@ LLVMValueRef LLVMBuildArrayAlloca(LLVMBuilderRef B, LLVMTypeRef Ty, } LLVMValueRef LLVMBuildFree(LLVMBuilderRef B, LLVMValueRef PointerVal) { - return wrap(unwrap(B)->CreateFree(unwrap(PointerVal))); + return wrap(unwrap(B)->Insert( + CallInst::CreateFree(unwrap(PointerVal), unwrap(B)->GetInsertBlock()))); } diff --git a/lib/VMCore/Instruction.cpp b/lib/VMCore/Instruction.cpp index 3839ddaf69f..391ba7bea5e 100644 --- a/lib/VMCore/Instruction.cpp +++ b/lib/VMCore/Instruction.cpp @@ -127,7 +127,6 @@ const char *Instruction::getOpcodeName(unsigned OpCode) { case Xor: return "xor"; // Memory instructions... - case Free: return "free"; case Alloca: return "alloca"; case Load: return "load"; case Store: return "store"; @@ -303,16 +302,43 @@ bool Instruction::isUsedOutsideOfBlock(const BasicBlock *BB) const { return false; } +// Code here matches isFreeCall from MallocHelper, which is not in VMCore. +static bool isFreeCall(const Value* I) { + const CallInst *CI = dyn_cast(I); + if (!CI) + return false; + + const Module* M = CI->getParent()->getParent()->getParent(); + Function *FreeFunc = M->getFunction("free"); + + if (CI->getOperand(0) != FreeFunc) + return false; + + // Check free prototype. + // FIXME: workaround for PR5130, this will be obsolete when a nobuiltin + // attribute will exist. + const FunctionType *FTy = FreeFunc->getFunctionType(); + if (FTy->getReturnType() != Type::getVoidTy(M->getContext())) + return false; + if (FTy->getNumParams() != 1) + return false; + if (FTy->param_begin()->get() != Type::getInt8PtrTy(M->getContext())) + return false; + + return true; +} + /// mayReadFromMemory - Return true if this instruction may read memory. /// bool Instruction::mayReadFromMemory() const { switch (getOpcode()) { default: return false; - case Instruction::Free: case Instruction::VAArg: case Instruction::Load: return true; case Instruction::Call: + if (isFreeCall(this)) + return true; return !cast(this)->doesNotAccessMemory(); case Instruction::Invoke: return !cast(this)->doesNotAccessMemory(); @@ -326,11 +352,12 @@ bool Instruction::mayReadFromMemory() const { bool Instruction::mayWriteToMemory() const { switch (getOpcode()) { default: return false; - case Instruction::Free: case Instruction::Store: case Instruction::VAArg: return true; case Instruction::Call: + if (isFreeCall(this)) + return true; return !cast(this)->onlyReadsMemory(); case Instruction::Invoke: return !cast(this)->onlyReadsMemory(); @@ -398,7 +425,19 @@ static bool isMalloc(const Value* I) { if (CI->getOperand(0) != MallocFunc) return false; - return true; + // Check malloc prototype. + // FIXME: workaround for PR5130, this will be obsolete when a nobuiltin + // attribute will exist. + const FunctionType *FTy = cast(MallocFunc)->getFunctionType(); + if (FTy->getNumParams() != 1) + return false; + if (IntegerType *ITy = dyn_cast(FTy->param_begin()->get())) { + if (ITy->getBitWidth() != 32 && ITy->getBitWidth() != 64) + return false; + return true; + } + + return false; } bool Instruction::isSafeToSpeculativelyExecute() const { @@ -444,7 +483,6 @@ bool Instruction::isSafeToSpeculativelyExecute() const { case Invoke: case PHI: case Store: - case Free: case Ret: case Br: case Switch: diff --git a/lib/VMCore/Instructions.cpp b/lib/VMCore/Instructions.cpp index c926547ad83..02d5af0120e 100644 --- a/lib/VMCore/Instructions.cpp +++ b/lib/VMCore/Instructions.cpp @@ -984,28 +984,6 @@ bool AllocaInst::isStaticAlloca() const { return Parent == &Parent->getParent()->front(); } -//===----------------------------------------------------------------------===// -// FreeInst Implementation -//===----------------------------------------------------------------------===// - -void FreeInst::AssertOK() { - assert(isa(getOperand(0)->getType()) && - "Can not free something of nonpointer type!"); -} - -FreeInst::FreeInst(Value *Ptr, Instruction *InsertBefore) - : UnaryInstruction(Type::getVoidTy(Ptr->getContext()), - Free, Ptr, InsertBefore) { - AssertOK(); -} - -FreeInst::FreeInst(Value *Ptr, BasicBlock *InsertAtEnd) - : UnaryInstruction(Type::getVoidTy(Ptr->getContext()), - Free, Ptr, InsertAtEnd) { - AssertOK(); -} - - //===----------------------------------------------------------------------===// // LoadInst Implementation //===----------------------------------------------------------------------===// @@ -3181,16 +3159,6 @@ AllocaInst *AllocaInst::clone() const { return New; } -FreeInst *FreeInst::clone() const { - FreeInst *New = new FreeInst(getOperand(0)); - New->SubclassOptionalData = SubclassOptionalData; - if (hasMetadata()) { - LLVMContext &Context = getContext(); - Context.pImpl->TheMetadata.ValueIsCloned(this, New); - } - return New; -} - LoadInst *LoadInst::clone() const { LoadInst *New = new LoadInst(getOperand(0), Twine(), isVolatile(),