| 155 | } |
| 156 | |
| 157 | void GcnTokenListBuilder::processVertex(GcnCfgVertex vtx) |
| 158 | { |
| 159 | //LOG_DEBUG("process vertex %d", static_cast<size_t>(vtx)); |
| 160 | |
| 161 | // Check if we need to close some loop and/or if/else scopes |
| 162 | popScopes(vtx); |
| 163 | |
| 164 | // If CurBB is the target of one or more breaks, instantiate the blocks now |
| 165 | auto iter = m_blockScopes.find(vtx); |
| 166 | if (iter != m_blockScopes.end()) |
| 167 | { |
| 168 | const auto& branches = iter->second; |
| 169 | processBlockScopes(branches); |
| 170 | m_blockScopes.erase(vtx); |
| 171 | } |
| 172 | |
| 173 | // Update the loop information and start a new one if needed |
| 174 | processLoopScopes(vtx); |
| 175 | |
| 176 | // Create the token for this code block and add it to the list |
| 177 | auto codeToken = makeCode(vtx); |
| 178 | m_insertPtr = m_tokens->insertAfter(m_insertPtr, codeToken); |
| 179 | |
| 180 | // Process the successors of this block |
| 181 | // First, add the delayed node to the visit stack |
| 182 | m_visitStack.emplace_back(vtx, StackElement::Delayed); |
| 183 | |
| 184 | // Then, create the successor tokens for the block (direct branch, an if/else/end chain) |
| 185 | processCodeTerminator(codeToken, vtx); |
| 186 | // Enqueue successors on the visit stack |
| 187 | // (in reverse order so they are popped in the correct order) |
| 188 | auto& term = m_cfg[vtx].terminator; |
| 189 | for (int i = term.successors.size() - 1; i >= 0; --i) |
| 190 | { |
| 191 | enqueueSuccessor(vtx, term.successors[i]); |
| 192 | } |
| 193 | } |
| 194 | |
| 195 | void GcnTokenListBuilder::enqueueSuccessor(GcnCfgVertex vtx, GcnCfgVertex succ) |
| 196 | { |
nothing calls this directly
no test coverage detected