Explorar el Código

Change std::vector to llvm::SmallSetVector for speed boost in DCE::runOnFunction (#2911)

Profiling this code showed significant wasted cycles removing potentially duplicated instructions from the center of the WorkList vector.

This PR moves to using an llvm::SmallSetVector to avoid unnecessary duplication and increase performance. A SmallSetVector is also used by the LLVM project although the surrounding code is slightly different.

On a sample shader this change showed between a 1.5% to 2.5% reduction in total compile time.

Co-authored-by: Nico May <[email protected]>
Nico May hace 5 años
padre
commit
096309971f
Se han modificado 1 ficheros con 5 adiciones y 9 borrados
  1. 5 9
      lib/Transforms/Scalar/DCE.cpp

+ 5 - 9
lib/Transforms/Scalar/DCE.cpp

@@ -17,6 +17,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "llvm/Transforms/Scalar.h"
+#include "llvm/ADT/SetVector.h"
 #include "llvm/ADT/Statistic.h"
 #include "llvm/IR/InstIterator.h"
 #include "llvm/IR/Instruction.h"
@@ -100,9 +101,9 @@ bool DCE::runOnFunction(Function &F) {
   TargetLibraryInfo *TLI = TLIP ? &TLIP->getTLI() : nullptr;
 
   // Start out with all of the instructions in the worklist...
-  std::vector<Instruction*> WorkList;
+  SmallSetVector<Instruction*, 16> WorkList;
   for (inst_iterator i = inst_begin(F), e = inst_end(F); i != e; ++i)
-    WorkList.push_back(&*i);
+    WorkList.insert(&*i);
 
   // Loop over the worklist finding instructions that are dead.  If they are
   // dead make them drop all of their uses, making other instructions
@@ -110,8 +111,7 @@ bool DCE::runOnFunction(Function &F) {
   //
   bool MadeChange = false;
   while (!WorkList.empty()) {
-    Instruction *I = WorkList.back();
-    WorkList.pop_back();
+    Instruction *I = WorkList.pop_back_val();
 
     if (isInstructionTriviallyDead(I, TLI)) { // If the instruction is dead.
       // Loop over all of the values that the instruction uses, if there are
@@ -120,15 +120,11 @@ bool DCE::runOnFunction(Function &F) {
       //
       for (User::op_iterator OI = I->op_begin(), E = I->op_end(); OI != E; ++OI)
         if (Instruction *Used = dyn_cast<Instruction>(*OI))
-          WorkList.push_back(Used);
+          WorkList.insert(Used);
 
       // Remove the instruction.
       I->eraseFromParent();
 
-      // Remove the instruction from the worklist if it still exists in it.
-      WorkList.erase(std::remove(WorkList.begin(), WorkList.end(), I),
-                     WorkList.end());
-
       MadeChange = true;
       ++DCEEliminated;
     }