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

Method GetBlockDepth

source/val/function.cpp:317–371  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

315}
316
317int Function::GetBlockDepth(BasicBlock* bb) {
318 // Guard against nullptr.
319 if (!bb) {
320 return 0;
321 }
322 // Only calculate the depth if it's not already calculated.
323 // This function uses memoization to avoid duplicate CFG depth calculations.
324 if (block_depth_.find(bb) != block_depth_.end()) {
325 return block_depth_[bb];
326 }
327 // Avoid recursion. Something is wrong if the same block is encountered
328 // multiple times.
329 block_depth_[bb] = 0;
330
331 BasicBlock* bb_dom = bb->immediate_dominator();
332 if (!bb_dom || bb == bb_dom) {
333 // This block has no dominator, so it's at depth 0.
334 block_depth_[bb] = 0;
335 } else if (bb->is_type(kBlockTypeContinue)) {
336 // This rule must precede the rule for merge blocks in order to set up
337 // depths correctly. If a block is both a merge and continue then the merge
338 // is nested within the continue's loop (or the graph is incorrect).
339 // The depth of the continue block entry point is 1 + loop header depth.
340 Construct* continue_construct =
341 entry_block_to_construct_[std::make_pair(bb, ConstructType::kContinue)];
342 assert(continue_construct);
343 // Continue construct has only 1 corresponding construct (loop header).
344 Construct* loop_construct =
345 continue_construct->corresponding_constructs()[0];
346 assert(loop_construct);
347 BasicBlock* loop_header = loop_construct->entry_block();
348 // The continue target may be the loop itself (while 1).
349 // In such cases, the depth of the continue block is: 1 + depth of the
350 // loop's dominator block.
351 if (loop_header == bb) {
352 block_depth_[bb] = 1 + GetBlockDepth(bb_dom);
353 } else {
354 block_depth_[bb] = 1 + GetBlockDepth(loop_header);
355 }
356 } else if (bb->is_type(kBlockTypeMerge)) {
357 // If this is a merge block, its depth is equal to the block before
358 // branching.
359 BasicBlock* header = merge_block_header_[bb];
360 assert(header);
361 block_depth_[bb] = GetBlockDepth(header);
362 } else if (bb_dom->is_type(kBlockTypeSelection) ||
363 bb_dom->is_type(kBlockTypeLoop)) {
364 // The dominator of the given block is a header block. So, the nesting
365 // depth of this block is: 1 + nesting depth of the header.
366 block_depth_[bb] = 1 + GetBlockDepth(bb_dom);
367 } else {
368 block_depth_[bb] = GetBlockDepth(bb_dom);
369 }
370 return block_depth_[bb];
371}
372
373void Function::RegisterExecutionModelLimitation(spv::ExecutionModel model,
374 const std::string& message) {

Callers 1

PerformCfgChecksFunction · 0.80

Calls 4

immediate_dominatorMethod · 0.80
is_typeMethod · 0.80
entry_blockMethod · 0.80
endMethod · 0.45

Tested by

no test coverage detected