From 6d0111f6c7d69b9028826351564ca52e5a5949d7 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sun, 11 Oct 2009 23:17:43 +0000 Subject: [PATCH] populate instcombine's initial worklist more carefully, causing it to visit instructions from the start of the function to the end of the function in the first path. This greatly speeds up some pathological cases (e.g. PR5150). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@83814 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../Scalar/InstructionCombining.cpp | 27 ++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp index 0c790f63150..b608186338e 100644 --- a/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/lib/Transforms/Scalar/InstructionCombining.cpp @@ -101,6 +101,20 @@ namespace { Add(I); } + /// AddInitialGroup - Add the specified batch of stuff in reverse order. + /// which should only be done when the worklist is empty and when the group + /// has no duplicates. + void AddInitialGroup(Instruction *const *List, unsigned NumEntries) { + assert(Worklist.empty() && "Worklist must be empty to add initial group"); + Worklist.reserve(NumEntries+16); + DEBUG(errs() << "IC: ADDING: " << NumEntries << " instrs to worklist\n"); + for (; NumEntries; --NumEntries) { + Instruction *I = List[NumEntries-1]; + WorklistMap.insert(std::make_pair(I, Worklist.size())); + Worklist.push_back(I); + } + } + // Remove - remove I from the worklist if it exists. void Remove(Instruction *I) { DenseMap::iterator It = WorklistMap.find(I); @@ -12663,6 +12677,9 @@ static void AddReachableCodeToWorklist(BasicBlock *BB, const TargetData *TD) { SmallVector Worklist; Worklist.push_back(BB); + + std::vector InstrsForInstCombineWorklist; + InstrsForInstCombineWorklist.reserve(128); while (!Worklist.empty()) { BB = Worklist.back(); @@ -12709,7 +12726,7 @@ static void AddReachableCodeToWorklist(BasicBlock *BB, DBI_Prev = 0; } - IC.Worklist.Add(Inst); + InstrsForInstCombineWorklist.push_back(Inst); } // Recursively visit successors. If this is a branch or switch on a @@ -12741,6 +12758,14 @@ static void AddReachableCodeToWorklist(BasicBlock *BB, for (unsigned i = 0, e = TI->getNumSuccessors(); i != e; ++i) Worklist.push_back(TI->getSuccessor(i)); } + + // Once we've found all of the instructions to add to instcombine's worklist, + // add them in reverse order. This way instcombine will visit from the top + // of the function down. This jives well with the way that it adds all uses + // of instructions to the worklist after doing a transformation, thus avoiding + // some N^2 behavior in pathological cases. + IC.Worklist.AddInitialGroup(&InstrsForInstCombineWorklist[0], + InstrsForInstCombineWorklist.size()); } bool InstCombiner::DoOneIteration(Function &F, unsigned Iteration) {