aboutsummaryrefslogtreecommitdiff
path: root/lib/Transforms
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Transforms')
-rw-r--r--lib/Transforms/IPO/CMakeLists.txt1
-rw-r--r--lib/Transforms/IPO/GlobalOpt.cpp5
-rw-r--r--lib/Transforms/IPO/IPO.cpp2
-rw-r--r--lib/Transforms/IPO/RaiseAllocations.cpp173
-rw-r--r--lib/Transforms/Scalar/DeadStoreElimination.cpp14
-rw-r--r--lib/Transforms/Scalar/InstructionCombining.cpp40
-rw-r--r--lib/Transforms/Scalar/SCCP.cpp5
-rw-r--r--lib/Transforms/Utils/Local.cpp3
-rw-r--r--lib/Transforms/Utils/LowerAllocations.cpp6
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);