MCPcopy Create free account
hub / github.com/KhronosGroup/SPIRV-Tools / BuildControlFlowGraph

Function BuildControlFlowGraph

source/disassemble.cpp:235–302  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

233}
234
235std::unordered_map<uint32_t, uint32_t> BuildControlFlowGraph(
236 ControlFlowGraph& cfg) {
237 std::unordered_map<uint32_t, uint32_t> id_to_index;
238
239 for (size_t index = 0; index < cfg.blocks.size(); ++index) {
240 SingleBlock& block = cfg.blocks[index];
241
242 // For future use, build the ID->index map
243 assert(static_cast<spv::Op>(block.instructions[0].get()->opcode) ==
244 spv::Op::OpLabel);
245 const uint32_t id = block.instructions[0].get()->result_id;
246
247 id_to_index[id] = static_cast<uint32_t>(index);
248
249 // Look for a merge instruction first. The function of OpBranch depends on
250 // that.
251 if (block.instructions.size() >= 3) {
252 const spv_parsed_instruction_t* maybe_merge =
253 block.instructions[block.instructions.size() - 2].get();
254
255 switch (static_cast<spv::Op>(maybe_merge->opcode)) {
256 case spv::Op::OpLoopMerge:
257 block.successors.merge_block_id = GetOperand(maybe_merge, 0);
258 block.successors.continue_block_id = GetOperand(maybe_merge, 1);
259 break;
260
261 case spv::Op::OpSelectionMerge:
262 block.successors.merge_block_id = GetOperand(maybe_merge, 0);
263 break;
264
265 default:
266 break;
267 }
268 }
269
270 // Then look at the last instruction; it must be a branch
271 assert(block.instructions.size() >= 2);
272
273 const spv_parsed_instruction_t* branch = block.instructions.back().get();
274 switch (static_cast<spv::Op>(branch->opcode)) {
275 case spv::Op::OpBranch:
276 if (block.successors.merge_block_id != 0) {
277 block.successors.body_block_id = GetOperand(branch, 0);
278 } else {
279 block.successors.next_block_id = GetOperand(branch, 0);
280 }
281 break;
282
283 case spv::Op::OpBranchConditional:
284 block.successors.true_block_id = GetOperand(branch, 1);
285 block.successors.false_block_id = GetOperand(branch, 2);
286 break;
287
288 case spv::Op::OpSwitch:
289 for (uint32_t case_index = 1; case_index < branch->num_operands;
290 case_index += 2) {
291 block.successors.case_block_ids.push_back(
292 GetOperand(branch, case_index));

Callers 1

EmitCFGMethod · 0.85

Calls 5

GetOperandFunction · 0.85
getMethod · 0.80
backMethod · 0.80
sizeMethod · 0.45
push_backMethod · 0.45

Tested by

no test coverage detected