Coverage Report

Created: 2025-07-23 06:18

/src/spirv-tools/source/opt/dominator_analysis.cpp
Line
Count
Source (jump to first uncovered line)
1
// Copyright (c) 2018 Google LLC
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
//     http://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14
15
#include "source/opt/dominator_analysis.h"
16
17
#include <unordered_set>
18
19
#include "source/opt/ir_context.h"
20
21
namespace spvtools {
22
namespace opt {
23
24
BasicBlock* DominatorAnalysisBase::CommonDominator(BasicBlock* b1,
25
45.1k
                                                   BasicBlock* b2) const {
26
45.1k
  if (!b1 || !b2) return nullptr;
27
28
45.1k
  std::unordered_set<BasicBlock*> seen;
29
45.1k
  BasicBlock* block = b1;
30
4.62M
  while (block && seen.insert(block).second) {
31
4.58M
    block = ImmediateDominator(block);
32
4.58M
  }
33
34
45.1k
  block = b2;
35
108k
  while (block && !seen.count(block)) {
36
63.4k
    block = ImmediateDominator(block);
37
63.4k
  }
38
39
45.1k
  return block;
40
45.1k
}
41
42
93.5k
bool DominatorAnalysisBase::Dominates(Instruction* a, Instruction* b) const {
43
93.5k
  if (!a || !b) {
44
0
    return false;
45
0
  }
46
47
93.5k
  if (a == b) {
48
0
    return true;
49
0
  }
50
51
93.5k
  BasicBlock* bb_a = a->context()->get_instr_block(a);
52
93.5k
  BasicBlock* bb_b = b->context()->get_instr_block(b);
53
54
93.5k
  if (bb_a != bb_b) {
55
84.7k
    return tree_.Dominates(bb_a, bb_b);
56
84.7k
  }
57
58
8.81k
  const Instruction* current = a;
59
8.81k
  const Instruction* other = b;
60
61
8.81k
  if (tree_.IsPostDominator()) {
62
0
    std::swap(current, other);
63
0
  }
64
65
  // We handle OpLabel instructions explicitly since they are not stored in the
66
  // instruction list.
67
8.81k
  if (current->opcode() == spv::Op::OpLabel) {
68
0
    return true;
69
0
  }
70
71
200k
  while ((current = current->NextNode())) {
72
197k
    if (current == other) {
73
5.54k
      return true;
74
5.54k
    }
75
197k
  }
76
77
3.27k
  return false;
78
8.81k
}
79
80
}  // namespace opt
81
}  // namespace spvtools