Skip to content

Commit cf5e25e

Browse files
committed
[fix]
1 parent d97a6b6 commit cf5e25e

File tree

4 files changed

+74
-96
lines changed

4 files changed

+74
-96
lines changed

include/klee/Module/KModule.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,9 @@ struct KFunction : public KCallable {
187187
/// Unique index for KFunction and KInstruction inside KModule
188188
/// from 0 to [KFunction + KInstruction]
189189
[[nodiscard]] inline unsigned getGlobalIndex() const { return globalIndex; }
190+
191+
bool operator<(const KFunction &rhs) const { return id < rhs.id; }
192+
bool operator<(const KFunction *rhs) const { return id < rhs->id; }
190193
};
191194

192195
struct KBlockCompare {

lib/Core/ExecutionState.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -443,7 +443,7 @@ void ExecutionState::increaseLevel() {
443443
KFunction *kf = prevPC->parent->parent;
444444
KModule *kmodule = kf->parent;
445445

446-
if (prevPC->inst->isTerminator()) {
446+
if (prevPC->inst->isTerminator() && kmodule->inMainModule(*kf->function)) {
447447
auto srcLevel = stack.infoStack().back().multilevel[srcbb].second;
448448
stack.infoStack().back().multilevel.replace({srcbb, srcLevel + 1});
449449
stack.infoStack().back().maxMultilevel =

lib/Core/Searcher.cpp

Lines changed: 38 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -824,17 +824,37 @@ ExecutionState &BlockLevelSearcher::selectState() {
824824
->second.begin());
825825
}
826826

827+
void BlockLevelSearcher::clear(ExecutionState &state) {
828+
KFunction *kf = state.initPC->parent->parent;
829+
BlockLevel &bl = stateToBlockLevel[&state];
830+
auto &sizeTo = data[kf];
831+
auto &sizesTo = sizeTo[bl.sizeOfLevel];
832+
auto &levelTo = sizesTo[bl.sizesOfFrameLevels];
833+
auto &multilevelTo = levelTo[bl.level];
834+
auto &states = multilevelTo[bl.maxMultilevel];
835+
836+
states.erase(&state);
837+
if (states.size() == 0) {
838+
multilevelTo.erase(bl.maxMultilevel);
839+
}
840+
if (multilevelTo.size() == 0) {
841+
levelTo.erase(bl.level);
842+
}
843+
if (levelTo.size() == 0) {
844+
sizesTo.erase(bl.sizesOfFrameLevels);
845+
}
846+
if (sizesTo.size() == 0) {
847+
sizeTo.erase(bl.sizeOfLevel);
848+
}
849+
}
850+
827851
void BlockLevelSearcher::update(ExecutionState *current,
828852
const StateIterable &addedStates,
829853
const StateIterable &removedStates) {
830854
if (current && std::find(removedStates.begin(), removedStates.end(),
831855
current) == removedStates.end()) {
832856
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]];
857+
BlockLevel &bl = stateToBlockLevel[current];
838858
sizes.clear();
839859
unsigned long long maxMultilevel = 0u;
840860
for (auto &infoFrame : current->stack.infoStack()) {
@@ -844,36 +864,21 @@ void BlockLevelSearcher::update(ExecutionState *current,
844864
for (auto &kfLevel : current->stack.multilevel) {
845865
maxMultilevel = std::max(maxMultilevel, kfLevel.second);
846866
}
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-
}
867+
if (sizes != bl.sizesOfFrameLevels ||
868+
current->level.size() != bl.sizeOfLevel ||
869+
maxMultilevel != bl.maxMultilevel) {
870+
clear(*current);
863871

864-
sizesTo[current->level.size()][sizes][current->level][maxMultilevel]
872+
data[kf][current->level.size()][sizes][current->level][maxMultilevel]
865873
.insert(current);
866874

867-
stateToLevel[current] = current->level;
868-
stateToMultilevel[current] = maxMultilevel;
869-
stateToSizes[current] = sizes;
870-
stateToSize[current] = current->level.size();
875+
stateToBlockLevel[current] = BlockLevel(kf, current->level.size(), sizes,
876+
current->level, maxMultilevel);
871877
}
872878
}
873879

874880
for (const auto state : addedStates) {
875881
KFunction *kf = state->initPC->parent->parent;
876-
auto &sizesTo = data[kf];
877882

878883
sizes.clear();
879884
unsigned long long maxMultilevel = 0u;
@@ -885,49 +890,21 @@ void BlockLevelSearcher::update(ExecutionState *current,
885890
maxMultilevel = std::max(maxMultilevel, kfLevel.second);
886891
}
887892

888-
sizesTo[state->level.size()][sizes][state->level][maxMultilevel].insert(
893+
data[kf][state->level.size()][sizes][state->level][maxMultilevel].insert(
889894
state);
890895

891-
stateToLevel[state] = state->level;
892-
stateToMultilevel[state] = maxMultilevel;
893-
stateToSize[state] = state->level.size();
894-
stateToSizes[state] = sizes;
896+
stateToBlockLevel[state] =
897+
BlockLevel(kf, state->level.size(), sizes, state->level, maxMultilevel);
895898
}
896899

897900
// remove states
898901
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);
902+
clear(*state);
903+
stateToBlockLevel.erase(state);
927904
}
928905
}
929906

930-
bool BlockLevelSearcher::empty() { return stateToLevel.empty(); }
907+
bool BlockLevelSearcher::empty() { return stateToBlockLevel.empty(); }
931908

932909
void BlockLevelSearcher::printName(llvm::raw_ostream &os) {
933910
os << "BlockLevelSearcher\n";

lib/Core/Searcher.h

Lines changed: 32 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -366,21 +366,14 @@ class InterleavedSearcher final : public Searcher {
366366
};
367367

368368
class BlockLevelSearcher final : public Searcher {
369+
private:
369370
struct KBlockSetsCompare {
370371
bool operator()(const std::set<KBlock *, KBlockCompare> &a,
371372
const std::set<KBlock *, KBlockCompare> &b) const {
372373
return a.size() > b.size() || (a.size() == b.size() && a > b);
373374
}
374375
};
375376

376-
struct MultilevelCompare {
377-
bool operator()(
378-
const std::map<KBlock *, unsigned long long, KBlockCompare> &a,
379-
const std::map<KBlock *, unsigned long long, KBlockCompare> &b) const {
380-
return a < b;
381-
}
382-
};
383-
384377
struct VectorsCompare {
385378
bool operator()(const std::vector<unsigned> &a,
386379
const std::vector<unsigned> &b) const {
@@ -394,35 +387,40 @@ class BlockLevelSearcher final : public Searcher {
394387
}
395388
};
396389

397-
using MultilevelsToStates =
398-
std::map<unsigned long long,
399-
std::set<ExecutionState *, ExecutionStateIDCompare>,
400-
std::less<unsigned long long>>;
401-
402-
using LevelToMultilevelsToStates =
403-
std::map<std::set<KBlock *, KBlockCompare>, MultilevelsToStates,
404-
KBlockSetsCompare>;
405-
406-
using SizesToLevelToMultilevelsToStates =
407-
std::map<std::vector<unsigned>, LevelToMultilevelsToStates,
408-
VectorsCompare>;
409-
using SizeToSizesToLevelToMultilevelsToStates =
410-
std::map<unsigned, SizesToLevelToMultilevelsToStates,
411-
std::greater<unsigned>>;
412-
413-
using FunctionToSizeToSizesToLevelToMultilevelsToStates =
414-
std::map<KFunction *, SizeToSizesToLevelToMultilevelsToStates,
415-
KFunctionCompare>;
416-
417-
FunctionToSizeToSizesToLevelToMultilevelsToStates data;
418-
std::unordered_map<ExecutionState *, std::set<KBlock *, KBlockCompare>>
419-
stateToLevel;
420-
std::unordered_map<ExecutionState *, unsigned long long> stateToMultilevel;
421-
std::unordered_map<ExecutionState *, std::vector<unsigned>> stateToSizes;
422-
std::unordered_map<ExecutionState *, unsigned> stateToSize;
390+
struct BlockLevel {
391+
KFunction *kf;
392+
unsigned sizeOfLevel;
393+
std::vector<unsigned> sizesOfFrameLevels;
394+
std::set<KBlock *, KBlockCompare> level;
395+
unsigned long long maxMultilevel;
396+
BlockLevel(KFunction *kf, unsigned sizeOfLevel,
397+
const std::vector<unsigned> &sizesOfFrameLevels,
398+
const std::set<KBlock *, KBlockCompare> &level,
399+
unsigned long long maxMultilevel)
400+
: kf(kf), sizeOfLevel(sizeOfLevel),
401+
sizesOfFrameLevels(sizesOfFrameLevels), level(level),
402+
maxMultilevel(maxMultilevel) {}
403+
BlockLevel() : kf(nullptr), sizeOfLevel(0), maxMultilevel(0){};
404+
};
405+
406+
using states_ty = std::set<ExecutionState *, ExecutionStateIDCompare>;
407+
using kblocks_ty = std::set<KBlock *, KBlockCompare>;
408+
409+
using ForthLayer =
410+
std::map<unsigned long long, states_ty, std::less<unsigned long long>>;
411+
using ThirdLayer = std::map<kblocks_ty, ForthLayer, KBlockSetsCompare>;
412+
using SecondLayer =
413+
std::map<std::vector<unsigned>, ThirdLayer, VectorsCompare>;
414+
using FirstLayer = std::map<unsigned, SecondLayer, std::greater<unsigned>>;
415+
using Data = std::map<KFunction *, FirstLayer, KFunctionCompare>;
416+
417+
Data data;
418+
std::unordered_map<ExecutionState *, BlockLevel> stateToBlockLevel;
423419
std::vector<unsigned> sizes;
424420
RNG &theRNG;
425421

422+
void clear(ExecutionState &state);
423+
426424
public:
427425
explicit BlockLevelSearcher(RNG &rng);
428426
ExecutionState &selectState() override;

0 commit comments

Comments
 (0)