| 101 | } |
| 102 | |
| 103 | std::set<RDNode> RDAnalyzer::traverseFunction(RDNode &Node, Function &F, |
| 104 | bool TraceCaller, |
| 105 | bool TraceCallee) { |
| 106 | auto &Location = Node.getLocation(); |
| 107 | std::set<RDNode> Prevs; |
| 108 | if (!TraceCallee && isa<CallBase>(&Location)) { |
| 109 | if (!Node.isVisit(Node.getTarget(), Location)) { |
| 110 | Node.visit(Node.getTarget(), Location); |
| 111 | Prevs = getPrevs(Node); |
| 112 | } |
| 113 | } else { |
| 114 | Prevs.insert(Node); |
| 115 | } |
| 116 | |
| 117 | std::set<RDNode> Result, Continue; |
| 118 | if (Prevs.size() == 0) { |
| 119 | Node.setIdx(-1); |
| 120 | Continue.insert(Node); |
| 121 | } |
| 122 | |
| 123 | for (const auto &Prev : Prevs) { |
| 124 | for (const auto &NextNode : trace(*const_cast<RDNode *>(&Prev))) { |
| 125 | if (NextNode.isRootDefinition()) { |
| 126 | mergeRDNode(Result, NextNode); |
| 127 | continue; |
| 128 | } |
| 129 | |
| 130 | auto &Target = NextNode.getTarget().getIR(); |
| 131 | |
| 132 | // NOTE: Alloca insts are considered as a candidate root definition |
| 133 | // since uninitialized variable declarations are emitted to IR like this. |
| 134 | if (isa<AllocaInst>(&Target)) { |
| 135 | const_cast<RDNode *>(&NextNode)->setIdx(-1); |
| 136 | mergeRDNode(Result, NextNode); |
| 137 | continue; |
| 138 | } |
| 139 | |
| 140 | // NOTE: Only global variable and argument can be continued outside |
| 141 | // of this function. |
| 142 | if (!isa<GlobalVariable>(&Target) && !isa<Argument>(&Target)) |
| 143 | continue; |
| 144 | |
| 145 | RDNode NewNode(NextNode); |
| 146 | NewNode.setStopTracing(false); |
| 147 | mergeRDNode(Continue, NewNode); |
| 148 | } |
| 149 | } |
| 150 | |
| 151 | if (TraceCaller) { |
| 152 | if (!Space.isEntryFunction(F)) { |
| 153 | while (Continue.size() > 0) { |
| 154 | auto Iter = Continue.begin(); |
| 155 | mergeRDNodes(Result, traceCaller(*const_cast<RDNode *>(&*Iter), F)); |
| 156 | Continue.erase(Iter); |
| 157 | } |
| 158 | } else { |
| 159 | while (Continue.size() > 0) { |
| 160 | auto Iter = Continue.begin(); |
nothing calls this directly
no test coverage detected