@@ -640,33 +640,94 @@ void BatchingSearcher::printName(llvm::raw_ostream &os) {
640640
641641// /
642642
643- IterativeDeepeningTimeSearcher::IterativeDeepeningTimeSearcher (
644- Searcher *baseSearcher)
645- : baseSearcher{baseSearcher} { };
643+ class TimeMetric final : public IterativeDeepeningSearcher::Metric {
644+ time::Point startTime;
645+ time::Span time{ time::seconds ( 1 ) };
646646
647- ExecutionState &IterativeDeepeningTimeSearcher::selectState () {
647+ public:
648+ void selectState () final { startTime = time::getWallTime (); }
649+ bool exceeds (const ExecutionState &state) const final {
650+ return time::getWallTime () - startTime > time;
651+ }
652+ void increaseLimit () final {
653+ time *= 2U ;
654+ klee_message (" increased time budget to %f seconds" , time.toSeconds ());
655+ }
656+ };
657+
658+ class MaxCyclesMetric final : public IterativeDeepeningSearcher::Metric {
659+ public:
660+ using ty = unsigned long long ;
661+
662+ private:
663+ ty maxCycles;
664+
665+ public:
666+ explicit MaxCyclesMetric (ty maxCycles) : maxCycles(maxCycles){};
667+ explicit MaxCyclesMetric () : MaxCyclesMetric(1ULL ){};
668+
669+ bool exceeds (const ExecutionState &state) const final {
670+ return state.isStuck (maxCycles);
671+ }
672+ void increaseLimit () final {
673+ maxCycles *= 2ULL ;
674+ klee_message (" increased max-cycles to %llu" , maxCycles);
675+ }
676+ };
677+
678+ IterativeDeepeningSearcher::IterativeDeepeningSearcher (
679+ Searcher *baseSearcher, TargetManagerSubscriber *tms,
680+ HaltExecution::Reason m)
681+ : baseSearcher{baseSearcher}, tms{tms} {
682+ switch (m) {
683+ case HaltExecution::Reason::MaxTime:
684+ metric = std::make_unique<TimeMetric>();
685+ return ;
686+ case HaltExecution::Reason::MaxCycles:
687+ metric = std::make_unique<MaxCyclesMetric>();
688+ return ;
689+ default :
690+ klee_error (" Illegal metric for iterative deepening searcher: %d" , m);
691+ }
692+ }
693+
694+ ExecutionState &IterativeDeepeningSearcher::selectState () {
648695 ExecutionState &res = baseSearcher->selectState ();
649- startTime = time::getWallTime ();
696+ metric-> selectState ();
650697 return res;
651698}
652699
653- void IterativeDeepeningTimeSearcher::update (
654- ExecutionState *current, const std::vector<ExecutionState *> &addedStates,
655- const std::vector<ExecutionState *> &removedStates) {
700+ void IterativeDeepeningSearcher::filter (const StatesVector &states,
701+ StatesVector &result) const {
702+ StatesVector states1 (states);
703+ std::sort (states1.begin (), states1.end ());
704+ std::set_difference (states1.begin (), states1.end (), pausedStates.begin (),
705+ pausedStates.end (), std::back_inserter (result));
706+ }
656707
657- const auto elapsed = time::getWallTime () - startTime;
708+ void IterativeDeepeningSearcher::update (
709+ const TargetHistoryTargetPairToStatesMap &added,
710+ const TargetHistoryTargetPairToStatesMap &removed) {
711+ if (!tms)
712+ return ;
713+ TargetHistoryTargetPairToStatesMap removedRefined (removed.size ());
714+ for (const auto &pair : removed) {
715+ StatesVector refined;
716+ IterativeDeepeningSearcher::filter (pair.second , refined);
717+ removedRefined.emplace (pair.first , std::move (refined));
718+ }
719+ tms->update (added, removedRefined);
720+ }
721+
722+ void IterativeDeepeningSearcher::update (ExecutionState *current,
723+ const StatesVector &addedStates,
724+ const StatesVector &removedStates) {
658725
659726 // update underlying searcher (filter paused states unknown to underlying
660727 // searcher)
661728 if (!removedStates.empty ()) {
662- std::vector<ExecutionState *> alt = removedStates;
663- for (const auto state : removedStates) {
664- auto it = pausedStates.find (state);
665- if (it != pausedStates.end ()) {
666- pausedStates.erase (it);
667- alt.erase (std::remove (alt.begin (), alt.end (), state), alt.end ());
668- }
669- }
729+ StatesVector alt;
730+ IterativeDeepeningSearcher::filter (removedStates, alt);
670731 baseSearcher->update (current, addedStates, alt);
671732 } else {
672733 baseSearcher->update (current, addedStates, removedStates);
@@ -676,27 +737,26 @@ void IterativeDeepeningTimeSearcher::update(
676737 if (current &&
677738 std::find (removedStates.begin (), removedStates.end (), current) ==
678739 removedStates.end () &&
679- elapsed > time ) {
740+ metric-> exceeds (*current) ) {
680741 pausedStates.insert (current);
681742 baseSearcher->update (nullptr , {}, {current});
682743 }
683744
684745 // no states left in underlying searcher: fill with paused states
685746 if (baseSearcher->empty ()) {
686- time *= 2U ;
687- klee_message (" increased time budget to %f\n " , time.toSeconds ());
688- std::vector<ExecutionState *> ps (pausedStates.begin (), pausedStates.end ());
689- baseSearcher->update (nullptr , ps, std::vector<ExecutionState *>());
747+ metric->increaseLimit ();
748+ StatesVector ps (pausedStates.begin (), pausedStates.end ());
749+ baseSearcher->update (nullptr , ps, {});
690750 pausedStates.clear ();
691751 }
692752}
693753
694- bool IterativeDeepeningTimeSearcher ::empty () {
754+ bool IterativeDeepeningSearcher ::empty () {
695755 return baseSearcher->empty () && pausedStates.empty ();
696756}
697757
698- void IterativeDeepeningTimeSearcher ::printName (llvm::raw_ostream &os) {
699- os << " IterativeDeepeningTimeSearcher \n " ;
758+ void IterativeDeepeningSearcher ::printName (llvm::raw_ostream &os) {
759+ os << " IterativeDeepeningSearcher \n " ;
700760}
701761
702762// /
0 commit comments