From 1368e659d7f5f5b1f87268a9a4c8265b29879320 Mon Sep 17 00:00:00 2001 From: Juergen Ributzka Date: Sat, 8 Feb 2014 00:20:45 +0000 Subject: [PATCH] [Constant Hoisting] Don't update the use list while traversing it - DOH! This fix first traverses the whole use list of the constant expression and keeps track of the instructions that need to be updated. Then perform the fixup afterwards. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@201008 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/Scalar/ConstantHoisting.cpp | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/lib/Transforms/Scalar/ConstantHoisting.cpp b/lib/Transforms/Scalar/ConstantHoisting.cpp index c4cf85f9526..28a31a97025 100644 --- a/lib/Transforms/Scalar/ConstantHoisting.cpp +++ b/lib/Transforms/Scalar/ConstantHoisting.cpp @@ -350,14 +350,19 @@ void ConstantHoisting::EmitBaseConstants(Function &F, User *U, } assert(isa(U) && "Expected a ConstantExpr."); ConstantExpr *CE = cast(U); + SmallVector, 8> WorkList; + DEBUG(dbgs() << "Visit ConstantExpr " << *CE << '\n'); for (Value::use_iterator UU = CE->use_begin(), E = CE->use_end(); UU != E; ++UU) { + DEBUG(dbgs() << "Check user "; UU->print(dbgs()); dbgs() << '\n'); // We only handel instructions here and won't walk down a ConstantExpr chain // to replace all ConstExpr with instructions. if (Instruction *I = dyn_cast(*UU)) { // Only update constant expressions in the current function. - if (I->getParent()->getParent() != &F) + if (I->getParent()->getParent() != &F) { + DEBUG(dbgs() << "Not in the same function - skip.\n"); continue; + } Instruction *Mat = Base; Instruction *InsertBefore = getMatInsertPt(I, DT); @@ -380,12 +385,18 @@ void ConstantHoisting::EmitBaseConstants(Function &F, User *U, // Use the same debug location as the instruction we are about to update. ICE->setDebugLoc(I->getDebugLoc()); - DEBUG(dbgs() << "Create instruction: " << *ICE << '\n'); - DEBUG(dbgs() << "Update: " << *I << '\n'); - I->replaceUsesOfWith(CE, ICE); - DEBUG(dbgs() << "To: " << *I << '\n'); + WorkList.push_back(std::make_pair(I, ICE)); + } else { + DEBUG(dbgs() << "Not an instruction - skip.\n"); } } + SmallVectorImpl >::iterator I, E; + for (I = WorkList.begin(), E = WorkList.end(); I != E; ++I) { + DEBUG(dbgs() << "Create instruction: " << *I->second << '\n'); + DEBUG(dbgs() << "Update: " << *I->first << '\n'); + I->first->replaceUsesOfWith(CE, I->second); + DEBUG(dbgs() << "To: " << *I->first << '\n'); + } } /// \brief Hoist and hide the base constant behind a bitcast and emit