| 599 | } |
| 600 | |
| 601 | std::set<RDNode> RDAnalyzer::handleExternalCall(RDNode &Node, CallBase &CB) { |
| 602 | // 1. Checks whether a given RDNode is register or memory |
| 603 | std::set<RDNode> Result; |
| 604 | if (Node.isMemory()) { |
| 605 | if (isMemoryIntrinsic(CB)) |
| 606 | return handleMemoryIntrinsicCall(Node, CB); |
| 607 | |
| 608 | // In memory case (ex: ... = external call(..., target, ...)) |
| 609 | // If trace target is a parameter of external call and the parameter |
| 610 | // is known as the one whose direction is output, then stop tracing. |
| 611 | // If not, keep tracing. |
| 612 | |
| 613 | // 1-1-1. Collect parameters whose direction is output. |
| 614 | auto OutParamIndices = getOutParamIndices(CB); |
| 615 | |
| 616 | if (isTargetMethodInvocation(Node, CB)) { |
| 617 | auto NonOutParamIndices = getNonOutParamIndices(CB); |
| 618 | |
| 619 | std::set<RDNode> NextNodes = {Node}; |
| 620 | for (auto NonOutParamIndex : NonOutParamIndices) { |
| 621 | RDNode NextNode(NonOutParamIndex, CB, &Node); |
| 622 | NextNode.setFirstUse(CB, NonOutParamIndex); |
| 623 | NextNodes.insert(NextNode); |
| 624 | } |
| 625 | return NextNodes; |
| 626 | } |
| 627 | |
| 628 | // 1-1-2. Collect tracing target is in out parameters. |
| 629 | const auto &Target = Node.getTarget(); |
| 630 | bool SetFirstUse = false; |
| 631 | std::vector<size_t> MatchedParamIndices; |
| 632 | for (size_t S = 0, E = CB.getNumArgOperands(); S < E; ++S) { |
| 633 | auto *Arg = CB.getArgOperand(S); |
| 634 | assert(Arg && "Unexpected Program State"); |
| 635 | |
| 636 | if (isPropagated(Target, *Arg) == PROPTYPE_NONE) |
| 637 | continue; |
| 638 | |
| 639 | if (Target == *RDTarget::create(*Arg)) { |
| 640 | if (SetFirstUse) |
| 641 | Node.addFirstUse(CB, S); |
| 642 | else { |
| 643 | SetFirstUse = true; |
| 644 | Node.setFirstUse(CB, S); |
| 645 | } |
| 646 | } |
| 647 | |
| 648 | if (OutParamIndices.find(S) == OutParamIndices.end()) |
| 649 | continue; |
| 650 | |
| 651 | MatchedParamIndices.push_back(S); |
| 652 | } |
| 653 | |
| 654 | // 1-1-3. If tracing target is not an output parameter, go next. |
| 655 | if (MatchedParamIndices.empty()) { |
| 656 | return {Node}; |
| 657 | } |
| 658 |
nothing calls this directly
no test coverage detected