From 7bcc0e7fff17376c0760e1d37b2ca779c2440c25 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sat, 28 Feb 2004 05:22:00 +0000 Subject: [PATCH] Rename AddUsesToWorkList -> AddUsersToWorkList, as that is what it does. Create a new AddUsesToWorkList method optimize memmove/set/cpy of zero bytes to a noop. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@11941 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/Scalar/InstructionCombining.cpp | 73 +++++++++++++++++++------- 1 file changed, 54 insertions(+), 19 deletions(-) diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp index 3054e13dfa6..724243369b5 100644 --- a/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/lib/Transforms/Scalar/InstructionCombining.cpp @@ -35,6 +35,7 @@ #include "llvm/Transforms/Scalar.h" #include "llvm/Instructions.h" +#include "llvm/Intrinsics.h" #include "llvm/Pass.h" #include "llvm/Constants.h" #include "llvm/DerivedTypes.h" @@ -60,15 +61,25 @@ namespace { std::vector WorkList; TargetData *TD; - void AddUsesToWorkList(Instruction &I) { - // The instruction was simplified, add all users of the instruction to - // the work lists because they might get more simplified now... - // + /// AddUsersToWorkList - When an instruction is simplified, add all users of + /// the instruction to the work lists because they might get more simplified + /// now. + /// + void AddUsersToWorkList(Instruction &I) { for (Value::use_iterator UI = I.use_begin(), UE = I.use_end(); UI != UE; ++UI) WorkList.push_back(cast(*UI)); } + /// AddUsesToWorkList - When an instruction is simplified, add operands to + /// the work lists because they might get more simplified now. + /// + void AddUsesToWorkList(Instruction &I) { + for (unsigned i = 0, e = I.getNumOperands(); i != e; ++i) + if (Instruction *Op = dyn_cast(I.getOperand(i))) + WorkList.push_back(Op); + } + // removeFromWorkList - remove all instances of I from the worklist. void removeFromWorkList(Instruction *I); public: @@ -133,10 +144,24 @@ namespace { // modified. // Instruction *ReplaceInstUsesWith(Instruction &I, Value *V) { - AddUsesToWorkList(I); // Add all modified instrs to worklist + AddUsersToWorkList(I); // Add all modified instrs to worklist I.replaceAllUsesWith(V); return &I; } + + // EraseInstFromFunction - When dealing with an instruction that has side + // effects or produces a void value, we can't rely on DCE to delete the + // instruction. Instead, visit methods should return the value returned by + // this function. + Instruction *EraseInstFromFunction(Instruction &I) { + assert(I.use_empty() && "Cannot erase instruction that is used!"); + AddUsesToWorkList(I); + removeFromWorkList(&I); + I.getParent()->getInstList().erase(&I); + return 0; // Don't do anything with FI + } + + private: /// InsertOperandCastBefore - This inserts a cast of V to DestTy before the /// InsertBefore instruction. This is specialized a bit to avoid inserting @@ -1909,6 +1934,23 @@ Instruction *InstCombiner::visitCastInst(CastInst &CI) { // CallInst simplification // Instruction *InstCombiner::visitCallInst(CallInst &CI) { + // Intrinsics cannot occur in an invoke, so handle them here instead of in + // visitCallSite. + if (Function *F = CI.getCalledFunction()) + switch (F->getIntrinsicID()) { + case Intrinsic::memmove: + case Intrinsic::memcpy: + case Intrinsic::memset: + // memmove/cpy/set of zero bytes is a noop. + if (Constant *NumBytes = dyn_cast(CI.getOperand(3))) { + if (NumBytes->isNullValue()) + return EraseInstFromFunction(CI); + } + break; + default: + break; + } + return visitCallSite(&CI); } @@ -2074,7 +2116,7 @@ bool InstCombiner::transformConstExprCastCall(CallSite CS) { // Otherwise, it's a call, just insert cast right after the call instr InsertNewInstBefore(NC, *Caller); } - AddUsesToWorkList(*Caller); + AddUsersToWorkList(*Caller); } else { NV = Constant::getNullValue(Caller->getType()); } @@ -2158,7 +2200,7 @@ Instruction *InstCombiner::visitGetElementPtrInst(GetElementPtrInst &GEP) { assert(Sum && "Constant folding of longs failed!?"); GEP.setOperand(0, Src->getOperand(0)); GEP.setOperand(1, Sum); - AddUsesToWorkList(*Src); // Reduce use count of Src + AddUsersToWorkList(*Src); // Reduce use count of Src return &GEP; } else if (Src->getNumOperands() == 2) { // Replace: gep (gep %P, long B), long A, ... @@ -2289,11 +2331,8 @@ Instruction *InstCombiner::visitFreeInst(FreeInst &FI) { // If we have 'free null' delete the instruction. This can happen in stl code // when lots of inlining happens. - if (isa(Op)) { - FI.getParent()->getInstList().erase(&FI); - removeFromWorkList(&FI); - return 0; // Don't do anything with FI - } + if (isa(Op)) + return EraseInstFromFunction(FI); return 0; } @@ -2407,9 +2446,7 @@ bool InstCombiner::runOnFunction(Function &F) { if (isInstructionTriviallyDead(I)) { // Add operands to the worklist... if (I->getNumOperands() < 4) - for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) - if (Instruction *Op = dyn_cast(I->getOperand(i))) - WorkList.push_back(Op); + AddUsesToWorkList(*I); ++NumDeadInst; I->getParent()->getInstList().erase(I); @@ -2420,9 +2457,7 @@ bool InstCombiner::runOnFunction(Function &F) { // Instruction isn't dead, see if we can constant propagate it... if (Constant *C = ConstantFoldInstruction(I)) { // Add operands to the worklist... - for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) - if (Instruction *Op = dyn_cast(I->getOperand(i))) - WorkList.push_back(Op); + AddUsesToWorkList(*I); ReplaceInstUsesWith(*I, C); ++NumConstProp; @@ -2468,7 +2503,7 @@ bool InstCombiner::runOnFunction(Function &F) { if (Result) { WorkList.push_back(Result); - AddUsesToWorkList(*Result); + AddUsersToWorkList(*Result); } Changed = true; } -- 2.11.0