| 249 | } |
| 250 | |
| 251 | std::set<RDNode> RDAnalyzer::trace(RDNode &Node) { |
| 252 | if (Node.isStopTracing()) |
| 253 | return {Node}; |
| 254 | |
| 255 | if (Cache.has(Node)) { |
| 256 | auto CachedNodes = Cache.get(Node); |
| 257 | for (const auto &CachedNode : CachedNodes) { |
| 258 | const_cast<RDNode *>(&CachedNode)->copyVisit(Node); |
| 259 | if (CachedNode.getFirstUses().size() == 0) { |
| 260 | const_cast<RDNode *>(&CachedNode)->setFirstUses(Node.getFirstUses()); |
| 261 | } |
| 262 | } |
| 263 | |
| 264 | return CachedNodes; |
| 265 | } |
| 266 | |
| 267 | if (Node.isRootDefinition()) { |
| 268 | auto *CB = dyn_cast_or_null<CallBase>(&Node.getLocation()); |
| 269 | auto Idx = Node.getIdx(); |
| 270 | if (CB && Idx >= 0) |
| 271 | Node.setFirstUse(*CB, Idx); |
| 272 | return {Node}; |
| 273 | } |
| 274 | |
| 275 | auto &Location = Node.getLocation(); |
| 276 | if (Node.isVisit(Node.getTarget(), Location)) { |
| 277 | return {}; |
| 278 | } |
| 279 | |
| 280 | if (Timeout != 0 && static_cast<unsigned>(time(NULL) - Start) > Timeout) { |
| 281 | Node.timeout(); |
| 282 | return {Node}; |
| 283 | } |
| 284 | |
| 285 | RDNode NewNode = Node; |
| 286 | NewNode.clearFirstUses(); |
| 287 | NewNode.visit(Node.getTarget(), Location); |
| 288 | |
| 289 | std::set<RDNode> Result; |
| 290 | for (const auto &NextNode : next(NewNode)) |
| 291 | mergeRDNodes(Result, pass(*const_cast<RDNode *>(&NextNode))); |
| 292 | |
| 293 | // If there is timeout result, entire result is not cached. |
| 294 | for (auto &Node : Result) |
| 295 | if (Node.isTimeout()) |
| 296 | return Result; |
| 297 | |
| 298 | if (Result.size() > 0) { |
| 299 | // Build cache. |
| 300 | Cache.cache(NewNode, Result); |
| 301 | |
| 302 | // Prepare result. Use first use if found node has not first use. |
| 303 | // This logic should be done after build cache, because built cache |
| 304 | // at this point can not use first uses that were found previously. |
| 305 | for (auto &FoundNode : Result) { |
| 306 | auto &FNFUs = FoundNode.getFirstUses(); |
| 307 | |
| 308 | if ((FNFUs.size() > 0) && (FNFUs.find(RDArgIndex()) == FNFUs.end())) |
nothing calls this directly
no test coverage detected