Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/Transforms/Vectorize/VPlanVerifier.cpp
Line
Count
Source (jump to first uncovered line)
1
//===-- VPlanVerifier.cpp -------------------------------------------------===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
///
9
/// \file
10
/// This file defines the class VPlanVerifier, which contains utility functions
11
/// to check the consistency and invariants of a VPlan.
12
///
13
//===----------------------------------------------------------------------===//
14
15
#include "VPlanVerifier.h"
16
#include "llvm/ADT/DepthFirstIterator.h"
17
18
#define DEBUG_TYPE "loop-vectorize"
19
20
using namespace llvm;
21
22
static cl::opt<bool> EnableHCFGVerifier("vplan-verify-hcfg", cl::init(false),
23
                                        cl::Hidden,
24
                                        cl::desc("Verify VPlan H-CFG."));
25
26
#ifndef NDEBUG
27
/// Utility function that checks whether \p VPBlockVec has duplicate
28
/// VPBlockBases.
29
static bool hasDuplicates(const SmallVectorImpl<VPBlockBase *> &VPBlockVec) {
30
  SmallDenseSet<const VPBlockBase *, 8> VPBlockSet;
31
  for (const auto *Block : VPBlockVec) {
32
    if (VPBlockSet.count(Block))
33
      return true;
34
    VPBlockSet.insert(Block);
35
  }
36
  return false;
37
}
38
#endif
39
40
/// Helper function that verifies the CFG invariants of the VPBlockBases within
41
/// \p Region. Checks in this function are generic for VPBlockBases. They are
42
/// not specific for VPBasicBlocks or VPRegionBlocks.
43
0
static void verifyBlocksInRegion(const VPRegionBlock *Region) {
44
0
  for (const VPBlockBase *VPB :
45
0
       make_range(df_iterator<const VPBlockBase *>::begin(Region->getEntry()),
46
0
                  df_iterator<const VPBlockBase *>::end(Region->getExit()))) {
47
0
    // Check block's parent.
48
0
    assert(VPB->getParent() == Region && "VPBlockBase has wrong parent");
49
0
50
0
    // Check block's condition bit.
51
0
    if (VPB->getNumSuccessors() > 1)
52
0
      assert(VPB->getCondBit() && "Missing condition bit!");
53
0
    else
54
0
      assert(!VPB->getCondBit() && "Unexpected condition bit!");
55
0
56
0
    // Check block's successors.
57
0
    const auto &Successors = VPB->getSuccessors();
58
0
    // There must be only one instance of a successor in block's successor list.
59
0
    // TODO: This won't work for switch statements.
60
0
    assert(!hasDuplicates(Successors) &&
61
0
           "Multiple instances of the same successor.");
62
0
63
0
    for (const VPBlockBase *Succ : Successors) {
64
0
      // There must be a bi-directional link between block and successor.
65
0
      const auto &SuccPreds = Succ->getPredecessors();
66
0
      assert(std::find(SuccPreds.begin(), SuccPreds.end(), VPB) !=
67
0
                 SuccPreds.end() &&
68
0
             "Missing predecessor link.");
69
0
      (void)SuccPreds;
70
0
    }
71
0
72
0
    // Check block's predecessors.
73
0
    const auto &Predecessors = VPB->getPredecessors();
74
0
    // There must be only one instance of a predecessor in block's predecessor
75
0
    // list.
76
0
    // TODO: This won't work for switch statements.
77
0
    assert(!hasDuplicates(Predecessors) &&
78
0
           "Multiple instances of the same predecessor.");
79
0
80
0
    for (const VPBlockBase *Pred : Predecessors) {
81
0
      // Block and predecessor must be inside the same region.
82
0
      assert(Pred->getParent() == VPB->getParent() &&
83
0
             "Predecessor is not in the same region.");
84
0
85
0
      // There must be a bi-directional link between block and predecessor.
86
0
      const auto &PredSuccs = Pred->getSuccessors();
87
0
      assert(std::find(PredSuccs.begin(), PredSuccs.end(), VPB) !=
88
0
                 PredSuccs.end() &&
89
0
             "Missing successor link.");
90
0
      (void)PredSuccs;
91
0
    }
92
0
  }
93
0
}
94
95
/// Verify the CFG invariants of VPRegionBlock \p Region and its nested
96
/// VPBlockBases. Do not recurse inside nested VPRegionBlocks.
97
0
static void verifyRegion(const VPRegionBlock *Region) {
98
0
  const VPBlockBase *Entry = Region->getEntry();
99
0
  const VPBlockBase *Exit = Region->getExit();
100
0
101
0
  // Entry and Exit shouldn't have any predecessor/successor, respectively.
102
0
  assert(!Entry->getNumPredecessors() && "Region entry has predecessors.");
103
0
  assert(!Exit->getNumSuccessors() && "Region exit has successors.");
104
0
  (void)Entry;
105
0
  (void)Exit;
106
0
107
0
  verifyBlocksInRegion(Region);
108
0
}
109
110
/// Verify the CFG invariants of VPRegionBlock \p Region and its nested
111
/// VPBlockBases. Recurse inside nested VPRegionBlocks.
112
0
static void verifyRegionRec(const VPRegionBlock *Region) {
113
0
  verifyRegion(Region);
114
0
115
0
  // Recurse inside nested regions.
116
0
  for (const VPBlockBase *VPB :
117
0
       make_range(df_iterator<const VPBlockBase *>::begin(Region->getEntry()),
118
0
                  df_iterator<const VPBlockBase *>::end(Region->getExit()))) {
119
0
    if (const auto *SubRegion = dyn_cast<VPRegionBlock>(VPB))
120
0
      verifyRegionRec(SubRegion);
121
0
  }
122
0
}
123
124
void VPlanVerifier::verifyHierarchicalCFG(
125
24
    const VPRegionBlock *TopRegion) const {
126
24
  if (!EnableHCFGVerifier)
127
24
    return;
128
0
129
0
  LLVM_DEBUG(dbgs() << "Verifying VPlan H-CFG.\n");
130
0
  assert(!TopRegion->getParent() && "VPlan Top Region should have no parent.");
131
0
  verifyRegionRec(TopRegion);
132
0
}