[llvm] a39c7ab - [NFCI][llvm-reduce] Cleanup Delta passes to use Oracle abstraction

Roman Lebedev via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 8 02:26:27 PDT 2020


Author: Roman Lebedev
Date: 2020-07-08T12:26:00+03:00
New Revision: a39c7ab9c355670510341191a802f3799265e9ef

URL: https://github.com/llvm/llvm-project/commit/a39c7ab9c355670510341191a802f3799265e9ef
DIFF: https://github.com/llvm/llvm-project/commit/a39c7ab9c355670510341191a802f3799265e9ef.diff

LOG: [NFCI][llvm-reduce] Cleanup Delta passes to use Oracle abstraction

Summary:
I think, this results in much more understandable/readable flow.
At least the original logic was perhaps the most hard thing for me to grasp when taking an initial look on the delta passes.

Reviewers: nickdesaulniers, dblaikie, diegotf, george.burgess.iv

Reviewed By: nickdesaulniers

Subscribers: llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D83287

Added: 
    

Modified: 
    llvm/tools/llvm-reduce/deltas/Delta.h
    llvm/tools/llvm-reduce/deltas/ReduceArguments.cpp
    llvm/tools/llvm-reduce/deltas/ReduceBasicBlocks.cpp
    llvm/tools/llvm-reduce/deltas/ReduceFunctions.cpp
    llvm/tools/llvm-reduce/deltas/ReduceGlobalVars.cpp
    llvm/tools/llvm-reduce/deltas/ReduceInstructions.cpp
    llvm/tools/llvm-reduce/deltas/ReduceMetadata.cpp
    llvm/tools/llvm-reduce/deltas/ReduceOperandBundles.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/tools/llvm-reduce/deltas/Delta.h b/llvm/tools/llvm-reduce/deltas/Delta.h
index dbb18e4bd07f..7da3c79c958e 100644
--- a/llvm/tools/llvm-reduce/deltas/Delta.h
+++ b/llvm/tools/llvm-reduce/deltas/Delta.h
@@ -16,9 +16,10 @@
 #define LLVM_TOOLS_LLVMREDUCE_LLVMREDUCE_DELTA_H
 
 #include "TestRunner.h"
-#include <vector>
-#include <utility>
+#include "llvm/ADT/ScopeExit.h"
 #include <functional>
+#include <utility>
+#include <vector>
 
 namespace llvm {
 
@@ -47,6 +48,39 @@ struct Chunk {
   }
 };
 
+/// Provides opaque interface for querying into ChunksToKeep without having to
+/// actually understand what is going on.
+class Oracle {
+  /// Out of all the features that we promised to be,
+  /// how many have we already processed? 1-based!
+  int Index = 1;
+
+  /// The actual workhorse, contains the knowledge whether or not
+  /// some particular feature should be preserved this time.
+  ArrayRef<Chunk> ChunksToKeep;
+
+public:
+  explicit Oracle(ArrayRef<Chunk> ChunksToKeep_)
+      : ChunksToKeep(ChunksToKeep_) {}
+
+  /// Should be called for each feature on which we are operating.
+  /// Name is self-explanatory - if returns true, then it should be preserved.
+  bool shouldKeep() {
+    if (ChunksToKeep.empty())
+      return false; // All further features are to be discarded.
+
+    // Does the current (front) chunk contain such a feature?
+    bool ShouldKeep = ChunksToKeep.front().contains(Index);
+    auto _ = make_scope_exit([&]() { ++Index; }); // Next time - next feature.
+
+    // Is this the last feature in the chunk?
+    if (ChunksToKeep.front().end == Index)
+      ChunksToKeep = ChunksToKeep.drop_front(); // Onto next chunk.
+
+    return ShouldKeep;
+  }
+};
+
 /// This function implements the Delta Debugging algorithm, it receives a
 /// number of Targets (e.g. Functions, Instructions, Basic Blocks, etc.) and
 /// splits them in half; these chunks of targets are then tested while ignoring

diff  --git a/llvm/tools/llvm-reduce/deltas/ReduceArguments.cpp b/llvm/tools/llvm-reduce/deltas/ReduceArguments.cpp
index b7d92049a67a..a119b40018b3 100644
--- a/llvm/tools/llvm-reduce/deltas/ReduceArguments.cpp
+++ b/llvm/tools/llvm-reduce/deltas/ReduceArguments.cpp
@@ -42,7 +42,8 @@ static void replaceFunctionCalls(Function &OldF, Function &NewF,
 /// accordingly. It also removes allocations of out-of-chunk arguments.
 static void extractArgumentsFromModule(std::vector<Chunk> ChunksToKeep,
                                        Module *Program) {
-  int I = 0, ArgCount = 0;
+  Oracle O(ChunksToKeep);
+
   std::set<Argument *> ArgsToKeep;
   std::vector<Function *> Funcs;
   // Get inside-chunk arguments, as well as their parent function
@@ -50,12 +51,8 @@ static void extractArgumentsFromModule(std::vector<Chunk> ChunksToKeep,
     if (!F.isDeclaration()) {
       Funcs.push_back(&F);
       for (auto &A : F.args())
-        if (I < (int)ChunksToKeep.size()) {
-          if (ChunksToKeep[I].contains(++ArgCount))
-            ArgsToKeep.insert(&A);
-          if (ChunksToKeep[I].end == ArgCount)
-            ++I;
-        }
+        if (O.shouldKeep())
+          ArgsToKeep.insert(&A);
     }
 
   for (auto *F : Funcs) {

diff  --git a/llvm/tools/llvm-reduce/deltas/ReduceBasicBlocks.cpp b/llvm/tools/llvm-reduce/deltas/ReduceBasicBlocks.cpp
index 03c3962d2fd9..002d81a67487 100644
--- a/llvm/tools/llvm-reduce/deltas/ReduceBasicBlocks.cpp
+++ b/llvm/tools/llvm-reduce/deltas/ReduceBasicBlocks.cpp
@@ -82,17 +82,14 @@ static void removeUninterestingBBsFromSwitch(SwitchInst &SwInst,
 /// accordingly. It also removes allocations of out-of-chunk arguments.
 static void extractBasicBlocksFromModule(std::vector<Chunk> ChunksToKeep,
                                          Module *Program) {
-  int I = 0, BBCount = 0;
+  Oracle O(ChunksToKeep);
+
   std::set<BasicBlock *> BBsToKeep;
 
   for (auto &F : *Program)
     for (auto &BB : F)
-      if (I < (int)ChunksToKeep.size()) {
-        if (ChunksToKeep[I].contains(++BBCount))
-          BBsToKeep.insert(&BB);
-        if (ChunksToKeep[I].end == BBCount)
-          ++I;
-      }
+      if (O.shouldKeep())
+        BBsToKeep.insert(&BB);
 
   std::vector<BasicBlock *> BBsToDelete;
   for (auto &F : *Program)

diff  --git a/llvm/tools/llvm-reduce/deltas/ReduceFunctions.cpp b/llvm/tools/llvm-reduce/deltas/ReduceFunctions.cpp
index 7652f0fda55f..b29df88261d9 100644
--- a/llvm/tools/llvm-reduce/deltas/ReduceFunctions.cpp
+++ b/llvm/tools/llvm-reduce/deltas/ReduceFunctions.cpp
@@ -24,16 +24,13 @@ using namespace llvm;
 /// that aren't inside any of the desired Chunks.
 static void extractFunctionsFromModule(const std::vector<Chunk> &ChunksToKeep,
                                        Module *Program) {
+  Oracle O(ChunksToKeep);
+
   // Get functions inside desired chunks
   std::set<Function *> FuncsToKeep;
-  int I = 0, FunctionCount = 0;
   for (auto &F : *Program)
-    if (I < (int)ChunksToKeep.size()) {
-      if (ChunksToKeep[I].contains(++FunctionCount))
-        FuncsToKeep.insert(&F);
-      if (FunctionCount == ChunksToKeep[I].end)
-        ++I;
-    }
+    if (O.shouldKeep())
+      FuncsToKeep.insert(&F);
 
   // Delete out-of-chunk functions, and replace their calls with undef
   std::vector<Function *> FuncsToRemove;

diff  --git a/llvm/tools/llvm-reduce/deltas/ReduceGlobalVars.cpp b/llvm/tools/llvm-reduce/deltas/ReduceGlobalVars.cpp
index 55d732cfec98..dc8df7395e1f 100644
--- a/llvm/tools/llvm-reduce/deltas/ReduceGlobalVars.cpp
+++ b/llvm/tools/llvm-reduce/deltas/ReduceGlobalVars.cpp
@@ -20,16 +20,13 @@ using namespace llvm;
 /// Removes all the Initialized GVs that aren't inside the desired Chunks.
 static void extractGVsFromModule(std::vector<Chunk> ChunksToKeep,
                                  Module *Program) {
+  Oracle O(ChunksToKeep);
+
   // Get GVs inside desired chunks
   std::set<GlobalVariable *> GVsToKeep;
-  int I = 0, GVCount = 0;
   for (auto &GV : Program->globals())
-    if (GV.hasInitializer() && I < (int)ChunksToKeep.size()) {
-      if (ChunksToKeep[I].contains(++GVCount))
-        GVsToKeep.insert(&GV);
-      if (GVCount == ChunksToKeep[I].end)
-        ++I;
-    }
+    if (GV.hasInitializer() && O.shouldKeep())
+      GVsToKeep.insert(&GV);
 
   // Delete out-of-chunk GVs and their uses
   std::vector<GlobalVariable *> ToRemove;

diff  --git a/llvm/tools/llvm-reduce/deltas/ReduceInstructions.cpp b/llvm/tools/llvm-reduce/deltas/ReduceInstructions.cpp
index b3497ad2dc02..18dec02b90ad 100644
--- a/llvm/tools/llvm-reduce/deltas/ReduceInstructions.cpp
+++ b/llvm/tools/llvm-reduce/deltas/ReduceInstructions.cpp
@@ -19,18 +19,15 @@ using namespace llvm;
 /// accordingly. It also removes allocations of out-of-chunk arguments.
 static void extractInstrFromModule(std::vector<Chunk> ChunksToKeep,
                                    Module *Program) {
-  int I = 0, InstCount = 0;
+  Oracle O(ChunksToKeep);
+
   std::set<Instruction *> InstToKeep;
 
   for (auto &F : *Program)
     for (auto &BB : F)
       for (auto &Inst : BB)
-        if (I < (int)ChunksToKeep.size()) {
-          if (ChunksToKeep[I].contains(++InstCount))
-            InstToKeep.insert(&Inst);
-          if (ChunksToKeep[I].end == InstCount)
-            ++I;
-        }
+        if (O.shouldKeep())
+          InstToKeep.insert(&Inst);
 
   std::vector<Instruction *> InstToDelete;
   for (auto &F : *Program)

diff  --git a/llvm/tools/llvm-reduce/deltas/ReduceMetadata.cpp b/llvm/tools/llvm-reduce/deltas/ReduceMetadata.cpp
index 4ea223546efa..4587295a00be 100644
--- a/llvm/tools/llvm-reduce/deltas/ReduceMetadata.cpp
+++ b/llvm/tools/llvm-reduce/deltas/ReduceMetadata.cpp
@@ -21,20 +21,15 @@ using namespace llvm;
 
 /// Adds all Unnamed Metadata Nodes that are inside desired Chunks to set
 template <class T>
-static void getChunkMetadataNodes(T &MDUser, int &I,
-                                  const std::vector<Chunk> &ChunksToKeep,
+static void getChunkMetadataNodes(T &MDUser, Oracle &O,
                                   std::set<MDNode *> &SeenNodes,
                                   std::set<MDNode *> &NodesToKeep) {
   SmallVector<std::pair<unsigned, MDNode *>, 4> MDs;
   MDUser.getAllMetadata(MDs);
   for (auto &MD : MDs) {
     SeenNodes.insert(MD.second);
-    if (I < (int)ChunksToKeep.size()) {
-      if (ChunksToKeep[I].contains(SeenNodes.size()))
-        NodesToKeep.insert(MD.second);
-      if (ChunksToKeep[I].end == (int)SeenNodes.size())
-        ++I;
-    }
+    if (O.shouldKeep())
+      NodesToKeep.insert(MD.second);
   }
 }
 
@@ -53,19 +48,20 @@ static void eraseMetadataIfOutsideChunk(T &MDUser,
 /// functions that aren't inside the desired Chunks.
 static void extractMetadataFromModule(const std::vector<Chunk> &ChunksToKeep,
                                       Module *Program) {
+  Oracle O(ChunksToKeep);
+
   std::set<MDNode *> SeenNodes;
   std::set<MDNode *> NodesToKeep;
-  int I = 0;
 
   // Add chunk MDNodes used by GVs, Functions, and Instructions to set
   for (auto &GV : Program->globals())
-    getChunkMetadataNodes(GV, I, ChunksToKeep, SeenNodes, NodesToKeep);
+    getChunkMetadataNodes(GV, O, SeenNodes, NodesToKeep);
 
   for (auto &F : *Program) {
-    getChunkMetadataNodes(F, I, ChunksToKeep, SeenNodes, NodesToKeep);
+    getChunkMetadataNodes(F, O, SeenNodes, NodesToKeep);
     for (auto &BB : F)
       for (auto &Inst : BB)
-        getChunkMetadataNodes(Inst, I, ChunksToKeep, SeenNodes, NodesToKeep);
+        getChunkMetadataNodes(Inst, O, SeenNodes, NodesToKeep);
   }
 
   // Once more, go over metadata nodes, but deleting the ones outside chunks
@@ -81,17 +77,10 @@ static void extractMetadataFromModule(const std::vector<Chunk> &ChunksToKeep,
 
 
   // Get out-of-chunk Named metadata nodes
-  unsigned MetadataCount = SeenNodes.size();
   std::vector<NamedMDNode *> NamedNodesToDelete;
-  for (auto &MD : Program->named_metadata()) {
-    if (I < (int)ChunksToKeep.size()) {
-      if (!ChunksToKeep[I].contains(++MetadataCount))
-        NamedNodesToDelete.push_back(&MD);
-      if (ChunksToKeep[I].end == (int)SeenNodes.size())
-        ++I;
-    } else
+  for (auto &MD : Program->named_metadata())
+    if (!O.shouldKeep())
       NamedNodesToDelete.push_back(&MD);
-  }
 
   for (auto *NN : NamedNodesToDelete) {
     for (int I = 0, E = NN->getNumOperands(); I != E; ++I)

diff  --git a/llvm/tools/llvm-reduce/deltas/ReduceOperandBundles.cpp b/llvm/tools/llvm-reduce/deltas/ReduceOperandBundles.cpp
index 23a1ae3909b1..3f1cb3740813 100644
--- a/llvm/tools/llvm-reduce/deltas/ReduceOperandBundles.cpp
+++ b/llvm/tools/llvm-reduce/deltas/ReduceOperandBundles.cpp
@@ -17,7 +17,6 @@
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/ScopeExit.h"
 #include "llvm/ADT/Sequence.h"
 #include "llvm/ADT/iterator_range.h"
 #include "llvm/IR/InstVisitor.h"
@@ -35,38 +34,6 @@ using namespace llvm;
 
 namespace {
 
-/// Provides opaque interface for querying into ChunksToKeep without having to
-/// actually understand what is going on.
-struct Oracle {
-  /// Out of all the features that we promised to be,
-  /// how many have we already processed? 1-based!
-  int Index = 1;
-
-  /// The actual workhorse, contains the knowledge whether or not
-  /// some particular feature should be preserved this time.
-  ArrayRef<Chunk> ChunksToKeep;
-
-public:
-  Oracle(ArrayRef<Chunk> ChunksToKeep_) : ChunksToKeep(ChunksToKeep_) {}
-
-  /// Should be called for each feature on which we are operating.
-  /// Name is self-explanatory - if returns true, then it should be preserved.
-  bool shouldKeep() {
-    if (ChunksToKeep.empty())
-      return false; // All further features are to be discarded.
-
-    // Does the current (front) chunk contain such a feature?
-    bool ShouldKeep = ChunksToKeep.front().contains(Index);
-    auto _ = make_scope_exit([&]() { ++Index; }); // Next time - next feature.
-
-    // Is this the last feature in the chunk?
-    if (ChunksToKeep.front().end == Index)
-      ChunksToKeep = ChunksToKeep.drop_front(); // Onto next chunk.
-
-    return ShouldKeep;
-  }
-};
-
 /// Given ChunksToKeep, produce a map of calls and indexes of operand bundles
 /// to be preserved for each call.
 class OperandBundleRemapper : public InstVisitor<OperandBundleRemapper> {


        


More information about the llvm-commits mailing list