about summary refs log tree commit diff homepage
path: root/lib/Core/Searcher.h
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Core/Searcher.h')
-rw-r--r--lib/Core/Searcher.h279
1 files changed, 279 insertions, 0 deletions
diff --git a/lib/Core/Searcher.h b/lib/Core/Searcher.h
new file mode 100644
index 00000000..455a7679
--- /dev/null
+++ b/lib/Core/Searcher.h
@@ -0,0 +1,279 @@
+//===-- Searcher.h ----------------------------------------------*- C++ -*-===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef KLEE_SEARCHER_H
+#define KLEE_SEARCHER_H
+
+#include <vector>
+#include <set>
+#include <map>
+#include <queue>
+
+// FIXME: Move out of header, use llvm streams.
+#include <ostream>
+
+namespace llvm {
+  class BasicBlock;
+  class Function;
+  class Instruction;
+}
+
+namespace klee {
+  template<class T> class DiscretePDF;
+  class ExecutionState;
+  class Executor;
+
+  class Searcher {
+  public:
+    virtual ~Searcher();
+
+    virtual ExecutionState &selectState() = 0;
+
+    virtual void update(ExecutionState *current,
+                        const std::set<ExecutionState*> &addedStates,
+                        const std::set<ExecutionState*> &removedStates) = 0;
+
+    virtual bool empty() = 0;
+
+    // prints name of searcher as a klee_message()
+    // TODO: could probably make prettier or more flexible
+    virtual void printName(std::ostream &os) { 
+      os << "<unnamed searcher>\n";
+    }
+
+    // pgbovine - to be called when a searcher gets activated and
+    // deactivated, say, by a higher-level searcher; most searchers
+    // don't need this functionality, so don't have to override.
+    virtual void activate() {};
+    virtual void deactivate() {};
+
+    // utility functions
+
+    void addState(ExecutionState *es, ExecutionState *current = 0) {
+      std::set<ExecutionState*> tmp;
+      tmp.insert(es);
+      update(current, tmp, std::set<ExecutionState*>());
+    }
+
+    void removeState(ExecutionState *es, ExecutionState *current = 0) {
+      std::set<ExecutionState*> tmp;
+      tmp.insert(es);
+      update(current, std::set<ExecutionState*>(), tmp);
+    }
+  };
+
+  class DFSSearcher : public Searcher {
+    std::vector<ExecutionState*> states;
+
+  public:
+    ExecutionState &selectState();
+    void update(ExecutionState *current,
+                const std::set<ExecutionState*> &addedStates,
+                const std::set<ExecutionState*> &removedStates);
+    bool empty() { return states.empty(); }
+    void printName(std::ostream &os) {
+      os << "DFSSearcher\n";
+    }
+  };
+
+  class RandomSearcher : public Searcher {
+    std::vector<ExecutionState*> states;
+
+  public:
+    ExecutionState &selectState();
+    void update(ExecutionState *current,
+                const std::set<ExecutionState*> &addedStates,
+                const std::set<ExecutionState*> &removedStates);
+    bool empty() { return states.empty(); }
+    void printName(std::ostream &os) {
+      os << "RandomSearcher\n";
+    }
+  };
+
+  class WeightedRandomSearcher : public Searcher {
+  public:
+    enum WeightType {
+      Depth,
+      QueryCost,
+      InstCount,
+      CPInstCount,
+      MinDistToUncovered,
+      CoveringNew
+    };
+
+  private:
+    Executor &executor;
+    DiscretePDF<ExecutionState*> *states;
+    WeightType type;
+    bool updateWeights;
+    
+    double getWeight(ExecutionState*);
+
+  public:
+    WeightedRandomSearcher(Executor &executor, WeightType type);
+    ~WeightedRandomSearcher();
+
+    ExecutionState &selectState();
+    void update(ExecutionState *current,
+                const std::set<ExecutionState*> &addedStates,
+                const std::set<ExecutionState*> &removedStates);
+    bool empty();
+    void printName(std::ostream &os) {
+      os << "WeightedRandomSearcher::";
+      switch(type) {
+      case Depth              : os << "Depth\n"; return;
+      case QueryCost          : os << "QueryCost\n"; return;
+      case InstCount          : os << "InstCount\n"; return;
+      case CPInstCount        : os << "CPInstCount\n"; return;
+      case MinDistToUncovered : os << "MinDistToUncovered\n"; return;
+      case CoveringNew        : os << "CoveringNew\n"; return;
+      default                 : os << "<unknown type>\n"; return;
+      }
+    }
+  };
+
+  class RandomPathSearcher : public Searcher {
+    Executor &executor;
+
+  public:
+    RandomPathSearcher(Executor &_executor);
+    ~RandomPathSearcher();
+
+    ExecutionState &selectState();
+    void update(ExecutionState *current,
+                const std::set<ExecutionState*> &addedStates,
+                const std::set<ExecutionState*> &removedStates);
+    bool empty();
+    void printName(std::ostream &os) {
+      os << "RandomPathSearcher\n";
+    }
+  };
+
+  class MergingSearcher : public Searcher {
+    Executor &executor;
+    std::set<ExecutionState*> statesAtMerge;
+    Searcher *baseSearcher;
+    llvm::Function *mergeFunction;
+
+  private:
+    llvm::Instruction *getMergePoint(ExecutionState &es);
+
+  public:
+    MergingSearcher(Executor &executor, Searcher *baseSearcher);
+    ~MergingSearcher();
+
+    ExecutionState &selectState();
+    void update(ExecutionState *current,
+                const std::set<ExecutionState*> &addedStates,
+                const std::set<ExecutionState*> &removedStates);
+    bool empty() { return baseSearcher->empty() && statesAtMerge.empty(); }
+    void printName(std::ostream &os) {
+      os << "MergingSearcher\n";
+    }
+  };
+
+  class BumpMergingSearcher : public Searcher {
+    Executor &executor;
+    std::map<llvm::Instruction*, ExecutionState*> statesAtMerge;
+    Searcher *baseSearcher;
+    llvm::Function *mergeFunction;
+
+  private:
+    llvm::Instruction *getMergePoint(ExecutionState &es);
+
+  public:
+    BumpMergingSearcher(Executor &executor, Searcher *baseSearcher);
+    ~BumpMergingSearcher();
+
+    ExecutionState &selectState();
+    void update(ExecutionState *current,
+                const std::set<ExecutionState*> &addedStates,
+                const std::set<ExecutionState*> &removedStates);
+    bool empty() { return baseSearcher->empty() && statesAtMerge.empty(); }
+    void printName(std::ostream &os) {
+      os << "BumpMergingSearcher\n";
+    }
+  };
+
+  class BatchingSearcher : public Searcher {
+    Searcher *baseSearcher;
+    double timeBudget;
+    unsigned instructionBudget;
+
+    ExecutionState *lastState;
+    double lastStartTime;
+    unsigned lastStartInstructions;
+
+  public:
+    BatchingSearcher(Searcher *baseSearcher, 
+                     double _timeBudget,
+                     unsigned _instructionBudget);
+    ~BatchingSearcher();
+
+    ExecutionState &selectState();
+    void update(ExecutionState *current,
+                const std::set<ExecutionState*> &addedStates,
+                const std::set<ExecutionState*> &removedStates);
+    bool empty() { return baseSearcher->empty(); }
+    void printName(std::ostream &os) {
+      os << "<BatchingSearcher> timeBudget: " << timeBudget
+         << ", instructionBudget: " << instructionBudget
+         << ", baseSearcher:\n";
+      baseSearcher->printName(os);
+      os << "</BatchingSearcher>\n";
+    }
+  };
+
+  class IterativeDeepeningTimeSearcher : public Searcher {
+    Searcher *baseSearcher;
+    double time, startTime;
+    std::set<ExecutionState*> pausedStates;
+
+  public:
+    IterativeDeepeningTimeSearcher(Searcher *baseSearcher);
+    ~IterativeDeepeningTimeSearcher();
+
+    ExecutionState &selectState();
+    void update(ExecutionState *current,
+                const std::set<ExecutionState*> &addedStates,
+                const std::set<ExecutionState*> &removedStates);
+    bool empty() { return baseSearcher->empty() && pausedStates.empty(); }
+    void printName(std::ostream &os) {
+      os << "IterativeDeepeningTimeSearcher\n";
+    }
+  };
+
+  class InterleavedSearcher : public Searcher {
+    typedef std::vector<Searcher*> searchers_ty;
+
+    searchers_ty searchers;
+    unsigned index;
+
+  public:
+    explicit InterleavedSearcher(const searchers_ty &_searchers);
+    ~InterleavedSearcher();
+
+    ExecutionState &selectState();
+    void update(ExecutionState *current,
+                const std::set<ExecutionState*> &addedStates,
+                const std::set<ExecutionState*> &removedStates);
+    bool empty() { return searchers[0]->empty(); }
+    void printName(std::ostream &os) {
+      os << "<InterleavedSearcher> containing "
+         << searchers.size() << " searchers:\n";
+      for (searchers_ty::iterator it = searchers.begin(), ie = searchers.end();
+           it != ie; ++it)
+        (*it)->printName(os);
+      os << "</InterleavedSearcher>\n";
+    }
+  };
+
+}
+
+#endif