@@ -195,7 +195,7 @@ weight_type TargetedSearcher::getWeight(ExecutionState *es) {
195195 return weight;
196196 }
197197 auto distRes = distanceCalculator.getDistance (*es, target->getBlock ());
198- weight = ulog2 (distRes.weight + es-> steppedMemoryInstructions + 1 ); // [0, 32)
198+ weight = ulog2 (distRes.weight + 1 ); // [0, 32)
199199 if (!distRes.isInsideFunction ) {
200200 weight += 32 ; // [32, 64)
201201 }
@@ -206,12 +206,12 @@ weight_type TargetedSearcher::getWeight(ExecutionState *es) {
206206
207207ExecutionState &GuidedSearcher::selectState () {
208208 unsigned size = historiesAndTargets.size ();
209- index = theRNG. getInt32 () % (size + 1 ) ;
209+ interleave ^= 1 ;
210210 ExecutionState *state = nullptr ;
211- if (index == size) {
211+ if (interleave || ! size) {
212212 state = &baseSearcher->selectState ();
213213 } else {
214- index = index % size;
214+ index = theRNG. getInt32 () % size;
215215 auto &historyTargetPair = historiesAndTargets[index];
216216 ref<const TargetsHistory> history = historyTargetPair.first ;
217217 ref<Target> target = historyTargetPair.second ;
@@ -776,3 +776,159 @@ void InterleavedSearcher::printName(llvm::raw_ostream &os) {
776776 searcher->printName (os);
777777 os << " </InterleavedSearcher>\n " ;
778778}
779+
780+ // /
781+
782+ BlockLevelSearcher::BlockLevelSearcher (RNG &rng) : theRNG{rng} {}
783+
784+ ExecutionState &BlockLevelSearcher::selectState () {
785+ unsigned rnd = 0 ;
786+ unsigned index = 0 ;
787+ unsigned mod = 10 ;
788+ unsigned border = 9 ;
789+
790+ auto kfi = data.begin ();
791+ index = theRNG.getInt32 () % data.size ();
792+ std::advance (kfi, index);
793+ auto &sizesTo = kfi->second ;
794+
795+ for (auto &sizesSize : sizesTo) {
796+ rnd = theRNG.getInt32 ();
797+ if (rnd % mod < border) {
798+ for (auto &size : sizesSize.second ) {
799+ rnd = theRNG.getInt32 ();
800+ if (rnd % mod < border) {
801+ auto lbi = size.second .begin ();
802+ index = theRNG.getInt32 () % size.second .size ();
803+ std::advance (lbi, index);
804+ auto &level = *lbi;
805+ for (auto &levelMultilevels : level.second ) {
806+ rnd = theRNG.getInt32 ();
807+ if (rnd % mod < border) {
808+ auto si = levelMultilevels.second .begin ();
809+ index = theRNG.getInt32 () % levelMultilevels.second .size ();
810+ std::advance (si, index);
811+ auto &state = *si;
812+ return *state;
813+ }
814+ }
815+ }
816+ }
817+ }
818+ }
819+
820+ return **(sizesTo.begin ()
821+ ->second .begin ()
822+ ->second .begin ()
823+ ->second .begin ()
824+ ->second .begin ());
825+ }
826+
827+ void BlockLevelSearcher::update (ExecutionState *current,
828+ const StateIterable &addedStates,
829+ const StateIterable &removedStates) {
830+ if (current && std::find (removedStates.begin (), removedStates.end (),
831+ current) == removedStates.end ()) {
832+ KFunction *kf = current->initPC ->parent ->parent ;
833+ auto &sizesTo = data[kf];
834+ auto &sizeTo = sizesTo[stateToSize[current]];
835+ auto &levelTo = sizeTo[stateToSizes[current]];
836+ auto &multilevelTo = levelTo[stateToLevel[current]];
837+ auto &states = multilevelTo[stateToMultilevel[current]];
838+ sizes.clear ();
839+ unsigned long long maxMultilevel = 0u ;
840+ for (auto &infoFrame : current->stack .infoStack ()) {
841+ sizes.push_back (infoFrame.level .size ());
842+ maxMultilevel = std::max (maxMultilevel, infoFrame.maxMultilevel );
843+ }
844+ for (auto &kfLevel : current->stack .multilevel ) {
845+ maxMultilevel = std::max (maxMultilevel, kfLevel.second );
846+ }
847+ if (sizes != stateToSizes[current] ||
848+ current->level .size () != stateToLevel[current].size () ||
849+ maxMultilevel != stateToMultilevel[current]) {
850+ states.erase (current);
851+ if (states.size () == 0 ) {
852+ multilevelTo.erase (stateToMultilevel[current]);
853+ }
854+ if (multilevelTo.size () == 0 ) {
855+ levelTo.erase (stateToLevel[current]);
856+ }
857+ if (levelTo.size () == 0 ) {
858+ sizeTo.erase (stateToSizes[current]);
859+ }
860+ if (sizeTo.size () == 0 ) {
861+ sizesTo.erase (stateToSize[current]);
862+ }
863+
864+ sizesTo[current->level .size ()][sizes][current->level ][maxMultilevel]
865+ .insert (current);
866+
867+ stateToLevel[current] = current->level ;
868+ stateToMultilevel[current] = maxMultilevel;
869+ stateToSizes[current] = sizes;
870+ stateToSize[current] = current->level .size ();
871+ }
872+ }
873+
874+ for (const auto state : addedStates) {
875+ KFunction *kf = state->initPC ->parent ->parent ;
876+ auto &sizesTo = data[kf];
877+
878+ sizes.clear ();
879+ unsigned long long maxMultilevel = 0u ;
880+ for (auto &infoFrame : state->stack .infoStack ()) {
881+ sizes.push_back (infoFrame.level .size ());
882+ maxMultilevel = std::max (maxMultilevel, infoFrame.maxMultilevel );
883+ }
884+ for (auto &kfLevel : state->stack .multilevel ) {
885+ maxMultilevel = std::max (maxMultilevel, kfLevel.second );
886+ }
887+
888+ sizesTo[state->level .size ()][sizes][state->level ][maxMultilevel].insert (
889+ state);
890+
891+ stateToLevel[state] = state->level ;
892+ stateToMultilevel[state] = maxMultilevel;
893+ stateToSize[state] = state->level .size ();
894+ stateToSizes[state] = sizes;
895+ }
896+
897+ // remove states
898+ for (const auto state : removedStates) {
899+ KFunction *kf = state->initPC ->parent ->parent ;
900+ auto &sizesTo = data[kf];
901+ auto &sizeTo = sizesTo[stateToSize[state]];
902+ auto &levelTo = sizeTo[stateToSizes[state]];
903+ auto &multilevelTo = levelTo[stateToLevel[state]];
904+ auto &states = multilevelTo[stateToMultilevel[state]];
905+
906+ states.erase (state);
907+ if (states.size () == 0 ) {
908+ multilevelTo.erase (stateToMultilevel[state]);
909+ }
910+ if (multilevelTo.size () == 0 ) {
911+ levelTo.erase (stateToLevel[state]);
912+ }
913+ if (levelTo.size () == 0 ) {
914+ sizeTo.erase (stateToSizes[state]);
915+ }
916+ if (sizeTo.size () == 0 ) {
917+ sizesTo.erase (stateToSize[state]);
918+ }
919+ if (sizesTo.size () == 0 ) {
920+ data.erase (kf);
921+ }
922+
923+ stateToLevel.erase (state);
924+ stateToMultilevel.erase (state);
925+ stateToSizes.erase (state);
926+ stateToSize.erase (state);
927+ }
928+ }
929+
930+ bool BlockLevelSearcher::empty () { return stateToLevel.empty (); }
931+
932+ void BlockLevelSearcher::printName (llvm::raw_ostream &os) {
933+ os << " BlockLevelSearcher\n " ;
934+ }
0 commit comments