Skip to content

Commit 4aacc60

Browse files
committed
Revert "[CycleAnalysis] Methods to verify cycles and their nesting. (#102300)"
This reverts commit b432afc. Reverted due to linker failures in expensive-checks.
1 parent 42067f2 commit 4aacc60

File tree

12 files changed

+61
-180
lines changed

12 files changed

+61
-180
lines changed

llvm/include/llvm/ADT/GenericCycleImpl.h

Lines changed: 54 additions & 141 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626
#include "llvm/ADT/DenseSet.h"
2727
#include "llvm/ADT/DepthFirstIterator.h"
2828
#include "llvm/ADT/GenericCycleInfo.h"
29-
#include "llvm/ADT/StringExtras.h"
3029

3130
#define DEBUG_TYPE "generic-cycle-impl"
3231

@@ -120,104 +119,6 @@ auto GenericCycle<ContextT>::getCyclePredecessor() const -> BlockT * {
120119
return Out;
121120
}
122121

123-
/// \brief Verify that this is actually a well-formed cycle in the CFG.
124-
template <typename ContextT> void GenericCycle<ContextT>::verifyCycle() const {
125-
#ifndef NDEBUG
126-
assert(!Blocks.empty() && "Cycle cannot be empty.");
127-
DenseSet<BlockT *> Blocks;
128-
for (BlockT *BB : blocks()) {
129-
assert(Blocks.insert(BB).second); // duplicates in block list?
130-
}
131-
assert(!Entries.empty() && "Cycle must have one or more entries.");
132-
133-
DenseSet<BlockT *> Entries;
134-
for (BlockT *Entry : entries()) {
135-
assert(Entries.insert(Entry).second); // duplicate entry?
136-
assert(contains(Entry));
137-
}
138-
139-
// Setup for using a depth-first iterator to visit every block in the cycle.
140-
SmallVector<BlockT *, 8> ExitBBs;
141-
getExitBlocks(ExitBBs);
142-
df_iterator_default_set<BlockT *> VisitSet;
143-
VisitSet.insert(ExitBBs.begin(), ExitBBs.end());
144-
145-
// Keep track of the BBs visited.
146-
SmallPtrSet<BlockT *, 8> VisitedBBs;
147-
148-
// Check the individual blocks.
149-
for (BlockT *BB : depth_first_ext(getHeader(), VisitSet)) {
150-
assert(llvm::any_of(llvm::children<BlockT *>(BB),
151-
[&](BlockT *B) { return contains(B); }) &&
152-
"Cycle block has no in-cycle successors!");
153-
154-
assert(llvm::any_of(llvm::inverse_children<BlockT *>(BB),
155-
[&](BlockT *B) { return contains(B); }) &&
156-
"Cycle block has no in-cycle predecessors!");
157-
158-
DenseSet<BlockT *> OutsideCyclePreds;
159-
for (BlockT *B : llvm::inverse_children<BlockT *>(BB))
160-
if (!contains(B))
161-
OutsideCyclePreds.insert(B);
162-
163-
if (Entries.contains(BB)) {
164-
assert(!OutsideCyclePreds.empty() && "Entry is unreachable!");
165-
} else if (!OutsideCyclePreds.empty()) {
166-
// A non-entry block shouldn't be reachable from outside the cycle,
167-
// though it is permitted if the predecessor is not itself actually
168-
// reachable.
169-
BlockT *EntryBB = &BB->getParent()->front();
170-
for (BlockT *CB : depth_first(EntryBB))
171-
assert(!OutsideCyclePreds.contains(CB) &&
172-
"Non-entry block reachable from outside!");
173-
}
174-
assert(BB != &getHeader()->getParent()->front() &&
175-
"Cycle contains function entry block!");
176-
177-
VisitedBBs.insert(BB);
178-
}
179-
180-
if (VisitedBBs.size() != getNumBlocks()) {
181-
dbgs() << "The following blocks are unreachable in the cycle:\n ";
182-
ListSeparator LS;
183-
for (auto *BB : Blocks) {
184-
if (!VisitedBBs.count(BB)) {
185-
dbgs() << LS;
186-
BB->printAsOperand(dbgs());
187-
}
188-
}
189-
dbgs() << "\n";
190-
llvm_unreachable("Unreachable block in cycle");
191-
}
192-
193-
verifyCycleNest();
194-
#endif
195-
}
196-
197-
/// \brief Verify the parent-child relations of this cycle.
198-
///
199-
/// Note that this does \em not check that cycle is really a cycle in the CFG.
200-
template <typename ContextT>
201-
void GenericCycle<ContextT>::verifyCycleNest() const {
202-
#ifndef NDEBUG
203-
// Check the subcycles.
204-
for (GenericCycle *Child : children()) {
205-
// Each block in each subcycle should be contained within this cycle.
206-
for (BlockT *BB : Child->blocks()) {
207-
assert(contains(BB) &&
208-
"Cycle does not contain all the blocks of a subcycle!");
209-
}
210-
assert(Child->Depth == Depth + 1);
211-
}
212-
213-
// Check the parent cycle pointer.
214-
if (ParentCycle) {
215-
assert(is_contained(ParentCycle->children(), this) &&
216-
"Cycle is not a subcycle of its parent!");
217-
}
218-
#endif
219-
}
220-
221122
/// \brief Helper class for computing cycle information.
222123
template <typename ContextT> class GenericCycleInfoCompute {
223124
using BlockT = typename ContextT::BlockT;
@@ -499,6 +400,8 @@ void GenericCycleInfo<ContextT>::compute(FunctionT &F) {
499400
LLVM_DEBUG(errs() << "Computing cycles for function: " << F.getName()
500401
<< "\n");
501402
Compute.run(&F.front());
403+
404+
assert(validateTree());
502405
}
503406

504407
template <typename ContextT>
@@ -511,7 +414,7 @@ void GenericCycleInfo<ContextT>::splitCriticalEdge(BlockT *Pred, BlockT *Succ,
511414
return;
512415

513416
addBlockToCycle(NewBlock, Cycle);
514-
verifyCycleNest();
417+
assert(validateTree());
515418
}
516419

517420
/// \brief Find the innermost cycle containing a given block.
@@ -565,63 +468,73 @@ unsigned GenericCycleInfo<ContextT>::getCycleDepth(const BlockT *Block) const {
565468
return Cycle->getDepth();
566469
}
567470

568-
/// \brief Verify the internal consistency of the cycle tree.
471+
#ifndef NDEBUG
472+
/// \brief Validate the internal consistency of the cycle tree.
569473
///
570474
/// Note that this does \em not check that cycles are really cycles in the CFG,
571475
/// or that the right set of cycles in the CFG were found.
572-
///
573-
/// Every natural loop has a corresponding cycle (possibly irreducible) with the
574-
/// same header, and every reducible cycle is a natural loop with the same
575-
/// header. We check this by comparing headers encountered in the two forests.
576476
template <typename ContextT>
577-
void GenericCycleInfo<ContextT>::verifyCycleNest(bool VerifyFull,
578-
LoopInfoT *LI) const {
579-
#ifndef NDEBUG
580-
DenseSet<BlockT *> LoopHeaders;
581-
DenseSet<BlockT *> CycleHeaders;
477+
bool GenericCycleInfo<ContextT>::validateTree() const {
478+
DenseSet<BlockT *> Blocks;
479+
DenseSet<BlockT *> Entries;
480+
481+
auto reportError = [](const char *File, int Line, const char *Cond) {
482+
errs() << File << ':' << Line
483+
<< ": GenericCycleInfo::validateTree: " << Cond << '\n';
484+
};
485+
#define check(cond) \
486+
do { \
487+
if (!(cond)) { \
488+
reportError(__FILE__, __LINE__, #cond); \
489+
return false; \
490+
} \
491+
} while (false)
582492

583-
if (LI) {
584-
for (LoopT *TopLoop : *LI) {
585-
for (LoopT *Loop : depth_first(TopLoop)) {
586-
LoopHeaders.insert(Loop->getHeader());
493+
for (const auto *TLC : toplevel_cycles()) {
494+
for (const CycleT *Cycle : depth_first(TLC)) {
495+
if (Cycle->ParentCycle)
496+
check(is_contained(Cycle->ParentCycle->children(), Cycle));
497+
498+
for (BlockT *Block : Cycle->Blocks) {
499+
auto MapIt = BlockMap.find(Block);
500+
check(MapIt != BlockMap.end());
501+
check(Cycle->contains(MapIt->second));
502+
check(Blocks.insert(Block).second); // duplicates in block list?
587503
}
588-
}
589-
}
504+
Blocks.clear();
590505

591-
for (CycleT *TopCycle : toplevel_cycles()) {
592-
for (CycleT *Cycle : depth_first(TopCycle)) {
593-
if (VerifyFull)
594-
Cycle->verifyCycle();
595-
else
596-
Cycle->verifyCycleNest();
597-
// Check the block map entries for blocks contained in this cycle.
598-
for (BlockT *BB : Cycle->blocks()) {
599-
auto MapIt = BlockMap.find(BB);
600-
assert(MapIt != BlockMap.end());
601-
assert(Cycle->contains(MapIt->second));
506+
check(!Cycle->Entries.empty());
507+
for (BlockT *Entry : Cycle->Entries) {
508+
check(Entries.insert(Entry).second); // duplicate entry?
509+
check(is_contained(Cycle->Blocks, Entry));
602510
}
603-
if (LI) {
604-
BlockT *Header = Cycle->getHeader();
605-
assert(CycleHeaders.insert(Header).second);
606-
if (Cycle->isReducible())
607-
assert(LoopHeaders.contains(Header));
511+
Entries.clear();
512+
513+
unsigned ChildDepth = 0;
514+
for (const CycleT *Child : Cycle->children()) {
515+
check(Child->Depth > Cycle->Depth);
516+
if (!ChildDepth) {
517+
ChildDepth = Child->Depth;
518+
} else {
519+
check(ChildDepth == Child->Depth);
520+
}
608521
}
609522
}
610523
}
611524

612-
if (LI) {
613-
for (BlockT *Header : LoopHeaders) {
614-
assert(CycleHeaders.contains(Header));
525+
for (const auto &Entry : BlockMap) {
526+
BlockT *Block = Entry.first;
527+
for (const CycleT *Cycle = Entry.second; Cycle;
528+
Cycle = Cycle->ParentCycle) {
529+
check(is_contained(Cycle->Blocks, Block));
615530
}
616531
}
617-
#endif
618-
}
619532

620-
/// \brief Verify that the entire cycle tree well-formed.
621-
template <typename ContextT>
622-
void GenericCycleInfo<ContextT>::verify(LoopInfoT *LI) const {
623-
verifyCycleNest(/*VerifyFull=*/true, LI);
533+
#undef check
534+
535+
return true;
624536
}
537+
#endif
625538

626539
/// \brief Print the cycle info.
627540
template <typename ContextT>

llvm/include/llvm/ADT/GenericCycleInfo.h

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -140,9 +140,6 @@ template <typename ContextT> class GenericCycle {
140140
/// it, otherwise return nullptr.
141141
BlockT *getCyclePredecessor() const;
142142

143-
void verifyCycle() const;
144-
void verifyCycleNest() const;
145-
146143
/// Iteration over child cycles.
147144
//@{
148145
using const_child_iterator_base =
@@ -231,8 +228,6 @@ template <typename ContextT> class GenericCycleInfo {
231228
using BlockT = typename ContextT::BlockT;
232229
using CycleT = GenericCycle<ContextT>;
233230
using FunctionT = typename ContextT::FunctionT;
234-
using LoopT = typename ContextT::LoopT;
235-
using LoopInfoT = typename ContextT::LoopInfoT;
236231
template <typename> friend class GenericCycle;
237232
template <typename> friend class GenericCycleInfoCompute;
238233

@@ -282,8 +277,9 @@ template <typename ContextT> class GenericCycleInfo {
282277

283278
/// Methods for debug and self-test.
284279
//@{
285-
void verifyCycleNest(bool VerifyFull = false, LoopInfoT *LI = nullptr) const;
286-
void verify(LoopInfoT *LI = nullptr) const;
280+
#ifndef NDEBUG
281+
bool validateTree() const;
282+
#endif
287283
void print(raw_ostream &Out) const;
288284
void dump() const { print(dbgs()); }
289285
Printable print(const CycleT *Cycle) { return Cycle->print(Context); }

llvm/include/llvm/ADT/GenericSSAContext.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -77,12 +77,6 @@ template <typename _FunctionT> class GenericSSAContext {
7777
// a given funciton.
7878
using DominatorTreeT = DominatorTreeBase<BlockT, false>;
7979

80-
// A LoopT is a natural loop in the CFG.
81-
using LoopT = typename SSATraits::LoopT;
82-
83-
// A LoopInfoT contains a forest of natural loops in the CFG.
84-
using LoopInfoT = typename SSATraits::LoopInfoT;
85-
8680
GenericSSAContext() = default;
8781
GenericSSAContext(const FunctionT *F) : F(F) {}
8882

llvm/include/llvm/Analysis/CycleAnalysis.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,17 +59,15 @@ class CycleAnalysis : public AnalysisInfoMixin<CycleAnalysis> {
5959
// TODO: verify analysis?
6060
};
6161

62+
/// Printer pass for the \c DominatorTree.
6263
class CycleInfoPrinterPass : public PassInfoMixin<CycleInfoPrinterPass> {
6364
raw_ostream &OS;
6465

6566
public:
6667
explicit CycleInfoPrinterPass(raw_ostream &OS);
67-
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
68-
static bool isRequired() { return true; }
69-
};
7068

71-
struct CycleInfoVerifierPass : public PassInfoMixin<CycleInfoVerifierPass> {
7269
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
70+
7371
static bool isRequired() { return true; }
7472
};
7573

llvm/include/llvm/CodeGen/MachineSSAContext.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,6 @@
2222
namespace llvm {
2323
class MachineInstr;
2424
class MachineFunction;
25-
class MachineLoop;
26-
class MachineLoopInfo;
2725
class Register;
2826

2927
inline unsigned succ_size(const MachineBasicBlock *BB) {
@@ -41,8 +39,6 @@ template <> struct GenericSSATraits<MachineFunction> {
4139
using ValueRefT = Register;
4240
using ConstValueRefT = Register;
4341
using UseT = MachineOperand;
44-
using LoopT = MachineLoop;
45-
using LoopInfoT = MachineLoopInfo;
4642
};
4743

4844
using MachineSSAContext = GenericSSAContext<MachineFunction>;

llvm/include/llvm/IR/SSAContext.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,6 @@
2121
namespace llvm {
2222
class BasicBlock;
2323
class Function;
24-
class Loop;
25-
class LoopInfo;
2624
class Instruction;
2725
class Value;
2826

@@ -37,8 +35,6 @@ template <> struct GenericSSATraits<Function> {
3735
using ValueRefT = Value *;
3836
using ConstValueRefT = const Value *;
3937
using UseT = Use;
40-
using LoopT = Loop;
41-
using LoopInfoT = LoopInfo;
4238
};
4339

4440
using SSAContext = GenericSSAContext<Function>;

llvm/lib/Analysis/CycleAnalysis.cpp

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88

99
#include "llvm/Analysis/CycleAnalysis.h"
1010
#include "llvm/ADT/GenericCycleImpl.h"
11-
#include "llvm/Analysis/LoopInfo.h"
1211
#include "llvm/IR/CFG.h" // for successors found by ADL in GenericCycleImpl.h
1312
#include "llvm/InitializePasses.h"
1413

@@ -36,14 +35,6 @@ PreservedAnalyses CycleInfoPrinterPass::run(Function &F,
3635
return PreservedAnalyses::all();
3736
}
3837

39-
PreservedAnalyses CycleInfoVerifierPass::run(Function &F,
40-
FunctionAnalysisManager &AM) {
41-
CycleInfo &CI = AM.getResult<CycleAnalysis>(F);
42-
LoopInfo &LI = AM.getResult<LoopAnalysis>(F);
43-
CI.verify(&LI);
44-
return PreservedAnalyses::all();
45-
}
46-
4738
//===----------------------------------------------------------------------===//
4839
// CycleInfoWrapperPass Implementation
4940
//===----------------------------------------------------------------------===//

llvm/lib/CodeGen/MachineCycleAnalysis.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88

99
#include "llvm/CodeGen/MachineCycleAnalysis.h"
1010
#include "llvm/ADT/GenericCycleImpl.h"
11-
#include "llvm/CodeGen/MachineLoopInfo.h"
1211
#include "llvm/CodeGen/MachineRegisterInfo.h"
1312
#include "llvm/CodeGen/MachineSSAContext.h"
1413
#include "llvm/CodeGen/TargetInstrInfo.h"

llvm/lib/IR/CycleInfo.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88

99
#include "llvm/IR/CycleInfo.h"
1010
#include "llvm/ADT/GenericCycleImpl.h"
11-
#include "llvm/Analysis/LoopInfo.h"
1211
#include "llvm/IR/CFG.h"
1312

1413
using namespace llvm;

llvm/lib/Passes/PassRegistry.def

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -475,7 +475,6 @@ FUNCTION_PASS("typepromotion", TypePromotionPass(TM))
475475
FUNCTION_PASS("unify-loop-exits", UnifyLoopExitsPass())
476476
FUNCTION_PASS("vector-combine", VectorCombinePass())
477477
FUNCTION_PASS("verify", VerifierPass())
478-
FUNCTION_PASS("verify<cycles>", CycleInfoVerifierPass())
479478
FUNCTION_PASS("verify<domtree>", DominatorTreeVerifierPass())
480479
FUNCTION_PASS("verify<loops>", LoopVerifierPass())
481480
FUNCTION_PASS("verify<memoryssa>", MemorySSAVerifierPass())

llvm/test/Analysis/CycleInfo/basic.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
; RUN: opt < %s -disable-output -passes='verify<cycles>,print<cycles>' 2>&1 | FileCheck %s -check-prefix=CHECK
1+
; RUN: opt < %s -disable-output -passes='print<cycles>' 2>&1 | FileCheck %s -check-prefix=CHECK
22

33
define void @empty() {
44
; CHECK-LABEL: CycleInfo for function: empty

0 commit comments

Comments
 (0)