@@ -56,18 +56,23 @@ DistanceResult DistanceCalculator::getDistance(const ExecutionState &state,
5656DistanceResult DistanceCalculator::getDistance (KBlock *kb, TargetKind kind,
5757 KBlock *target) {
5858 SpeculativeState specState (kb, kind);
59- if (distanceResultCache.count (target) == 0 ||
60- distanceResultCache.at (target).count (specState) == 0 ) {
59+ auto it1 = distanceResultCache.find (target);
60+ if (it1 == distanceResultCache.end ()) {
61+ SpeculativeStateToDistanceResultMap m;
62+ it1 = distanceResultCache.emplace (target, std::move (m)).first ;
63+ }
64+ auto &m = it1->second ;
65+ auto it2 = m.find (specState);
66+ if (it2 == m.end ()) {
6167 auto result = computeDistance (kb, kind, target);
62- distanceResultCache[target][specState] = result;
68+ m.emplace (specState, result);
69+ return result;
6370 }
64- return distanceResultCache. at (target). at (specState) ;
71+ return it2-> second ;
6572}
6673
6774DistanceResult DistanceCalculator::computeDistance (KBlock *kb, TargetKind kind,
6875 KBlock *target) const {
69- const auto &distanceToTargetFunction =
70- codeGraphInfo.getBackwardDistance (target->parent );
7176 weight_type weight = 0 ;
7277 WeightResult res = Miss;
7378 bool isInsideFunction = true ;
@@ -77,7 +82,7 @@ DistanceResult DistanceCalculator::computeDistance(KBlock *kb, TargetKind kind,
7782 break ;
7883
7984 case PreTarget:
80- res = tryGetPreTargetWeight (kb, weight, distanceToTargetFunction, target);
85+ res = tryGetPreTargetWeight (kb, weight, target);
8186 isInsideFunction = false ;
8287 break ;
8388
@@ -102,26 +107,21 @@ DistanceResult DistanceCalculator::getDistance(
102107 auto sfi = frames.rbegin (), sfe = frames.rend ();
103108 bool strictlyAfterKB =
104109 sfi != sfe && sfi->kf ->parent ->inMainModule (*sfi->kf ->function );
105- for (; sfi != sfe; sfi++) {
110+ for (; sfi != sfe; sfi++, sfNum++ ) {
106111 unsigned callWeight;
107112 if (distanceInCallGraph (sfi->kf , kb, callWeight, distanceToTargetFunction,
108113 target, strictlyAfterKB && sfNum != 0 )) {
109- callWeight *= 2 ;
110- callWeight += sfNum;
114+ callWeight = 2 * callWeight + sfNum;
111115
112116 if (callWeight < UINT_MAX) {
113117 minCallWeight = callWeight;
114118 minSfNum = sfNum;
119+ break ;
115120 }
116121 }
117122
118- if (sfi->caller ) {
123+ if (sfi->caller )
119124 kb = sfi->caller ->parent ;
120- }
121- sfNum++;
122-
123- if (minCallWeight < UINT_MAX)
124- break ;
125125 }
126126
127127 TargetKind kind = NoneTarget;
@@ -138,71 +138,38 @@ DistanceResult DistanceCalculator::getDistance(
138138
139139bool DistanceCalculator::distanceInCallGraph (
140140 KFunction *kf, KBlock *origKB, unsigned int &distance,
141- const std::unordered_map<KFunction *, unsigned int >
142- &distanceToTargetFunction,
143- KBlock *target, bool strictlyAfterKB) const {
144- distance = UINT_MAX;
145- const std::unordered_map<KBlock *, unsigned > &dist =
146- codeGraphInfo.getDistance (origKB);
147- KBlock *targetBB = target;
148- KFunction *targetF = targetBB->parent ;
149-
150- if (kf == targetF && dist.count (targetBB) != 0 ) {
141+ const FunctionDistanceMap &distanceToTargetFunction, KBlock *targetKB,
142+ bool strictlyAfterKB) const {
143+ auto &dist = codeGraphInfo.getDistance (origKB->basicBlock );
144+ if (kf == targetKB->parent && dist.count (targetKB->basicBlock )) {
151145 distance = 0 ;
152146 return true ;
153147 }
154148
155- if (!strictlyAfterKB)
156- return distanceInCallGraph (kf, origKB, distance, distanceToTargetFunction,
157- target);
158- auto min_distance = UINT_MAX;
159149 distance = UINT_MAX;
160- for (auto bb : successors (origKB->basicBlock )) {
161- auto kb = kf->blockMap [bb];
162- distanceInCallGraph (kf, kb, distance, distanceToTargetFunction, target);
163- if (distance < min_distance)
164- min_distance = distance;
165- }
166- distance = min_distance;
167- return distance != UINT_MAX;
168- }
169-
170- bool DistanceCalculator::distanceInCallGraph (
171- KFunction *kf, KBlock *kb, unsigned int &distance,
172- const std::unordered_map<KFunction *, unsigned int >
173- &distanceToTargetFunction,
174- KBlock *target) const {
175- distance = UINT_MAX;
176- const std::unordered_map<KBlock *, unsigned > &dist =
177- codeGraphInfo.getDistance (kb);
178-
179- for (auto &kCallBlock : kf->kCallBlocks ) {
180- if (dist.count (kCallBlock ) == 0 )
150+ bool cannotReachItself = strictlyAfterKB && !codeGraphInfo.hasCycle (origKB);
151+ for (auto kCallBlock : kf->kCallBlocks ) {
152+ if (!dist.count (kCallBlock ->basicBlock ) ||
153+ (cannotReachItself && origKB == kCallBlock ))
181154 continue ;
182- for (auto &calledFunction : kCallBlock ->calledFunctions ) {
183- KFunction *calledKFunction = kf->parent ->functionMap [calledFunction];
184- if (distanceToTargetFunction.count (calledKFunction) != 0 &&
185- distance > distanceToTargetFunction.at (calledKFunction) + 1 ) {
186- distance = distanceToTargetFunction.at (calledKFunction) + 1 ;
187- }
155+ for (auto calledFunction : kCallBlock ->calledFunctions ) {
156+ auto it = distanceToTargetFunction.find (calledFunction);
157+ if (it != distanceToTargetFunction.end () && distance > it->second + 1 )
158+ distance = it->second + 1 ;
188159 }
189160 }
190161 return distance != UINT_MAX;
191162}
192163
193- WeightResult
194- DistanceCalculator::tryGetLocalWeight (KBlock *kb, weight_type &weight,
195- const std::vector<KBlock *> &localTargets,
196- KBlock *target) const {
197- KBlock *currentKB = kb;
198- const std::unordered_map<KBlock *, unsigned > &dist =
199- codeGraphInfo.getDistance (currentKB);
164+ WeightResult DistanceCalculator::tryGetLocalWeight (
165+ KBlock *kb, weight_type &weight,
166+ const std::vector<KBlock *> &localTargets) const {
167+ const auto &dist = codeGraphInfo.getDistance (kb);
200168 weight = UINT_MAX;
201- for (auto &end : localTargets) {
202- if (dist.count (end) > 0 ) {
203- unsigned int w = dist.at (end);
204- weight = std::min (w, weight);
205- }
169+ for (auto end : localTargets) {
170+ auto it = dist.find (end->basicBlock );
171+ if (it != dist.end ())
172+ weight = std::min (it->second , weight);
206173 }
207174
208175 if (weight == UINT_MAX)
@@ -214,27 +181,26 @@ DistanceCalculator::tryGetLocalWeight(KBlock *kb, weight_type &weight,
214181 return Continue;
215182}
216183
217- WeightResult DistanceCalculator::tryGetPreTargetWeight (
218- KBlock *kb, weight_type &weight,
219- const std::unordered_map<KFunction *, unsigned int >
220- &distanceToTargetFunction,
221- KBlock * target) const {
184+ WeightResult DistanceCalculator::tryGetPreTargetWeight (KBlock *kb,
185+ weight_type &weight,
186+ KBlock *target) const {
187+ auto &distanceToTargetFunction =
188+ codeGraphInfo. getBackwardDistance ( target-> parent );
222189 KFunction *currentKF = kb->parent ;
223190 std::vector<KBlock *> localTargets;
224- for (auto &kCallBlock : currentKF->kCallBlocks ) {
225- for (auto &calledFunction : kCallBlock ->calledFunctions ) {
226- KFunction *calledKFunction =
227- currentKF->parent ->functionMap [calledFunction];
228- if (distanceToTargetFunction.count (calledKFunction) > 0 ) {
191+ for (auto kCallBlock : currentKF->kCallBlocks ) {
192+ for (auto calledFunction : kCallBlock ->calledFunctions ) {
193+ if (distanceToTargetFunction.count (calledFunction)) {
229194 localTargets.push_back (kCallBlock );
195+ break ;
230196 }
231197 }
232198 }
233199
234200 if (localTargets.empty ())
235201 return Miss;
236202
237- WeightResult res = tryGetLocalWeight (kb, weight, localTargets, target );
203+ WeightResult res = tryGetLocalWeight (kb, weight, localTargets);
238204 return res == Done ? Continue : res;
239205}
240206
@@ -247,14 +213,14 @@ WeightResult DistanceCalculator::tryGetPostTargetWeight(KBlock *kb,
247213 if (localTargets.empty ())
248214 return Miss;
249215
250- WeightResult res = tryGetLocalWeight (kb, weight, localTargets, target );
216+ WeightResult res = tryGetLocalWeight (kb, weight, localTargets);
251217 return res == Done ? Continue : res;
252218}
253219
254220WeightResult DistanceCalculator::tryGetTargetWeight (KBlock *kb,
255221 weight_type &weight,
256222 KBlock *target) const {
257223 std::vector<KBlock *> localTargets = {target};
258- WeightResult res = tryGetLocalWeight (kb, weight, localTargets, target );
224+ WeightResult res = tryGetLocalWeight (kb, weight, localTargets);
259225 return res;
260226}
0 commit comments