File indexing completed on 2026-05-10 08:43:05
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016 #ifndef LLVM_ADT_GENERICCONVERGENCEVERIFIER_H
0017 #define LLVM_ADT_GENERICCONVERGENCEVERIFIER_H
0018
0019 #include "llvm/ADT/GenericCycleInfo.h"
0020
0021 namespace llvm {
0022
0023 template <typename ContextT> class GenericConvergenceVerifier {
0024 public:
0025 using BlockT = typename ContextT::BlockT;
0026 using FunctionT = typename ContextT::FunctionT;
0027 using ValueRefT = typename ContextT::ValueRefT;
0028 using InstructionT = typename ContextT::InstructionT;
0029 using DominatorTreeT = typename ContextT::DominatorTreeT;
0030 using CycleInfoT = GenericCycleInfo<ContextT>;
0031 using CycleT = typename CycleInfoT::CycleT;
0032
0033 void initialize(raw_ostream *OS,
0034 function_ref<void(const Twine &Message)> FailureCB,
0035 const FunctionT &F) {
0036 clear();
0037 this->OS = OS;
0038 this->FailureCB = FailureCB;
0039 Context = ContextT(&F);
0040 }
0041
0042 void clear();
0043 void visit(const BlockT &BB);
0044 void visit(const InstructionT &I);
0045 void verify(const DominatorTreeT &DT);
0046
0047 bool sawTokens() const { return ConvergenceKind == ControlledConvergence; }
0048
0049 private:
0050 raw_ostream *OS;
0051 std::function<void(const Twine &Message)> FailureCB;
0052 DominatorTreeT *DT;
0053 CycleInfoT CI;
0054 ContextT Context;
0055
0056
0057 enum {
0058 ControlledConvergence,
0059 UncontrolledConvergence,
0060 NoConvergence
0061 } ConvergenceKind = NoConvergence;
0062
0063
0064
0065 enum ConvOpKind { CONV_ANCHOR, CONV_ENTRY, CONV_LOOP, CONV_NONE };
0066
0067
0068
0069 DenseMap<const InstructionT *, const InstructionT *> Tokens;
0070
0071 bool SeenFirstConvOp = false;
0072
0073 static bool isInsideConvergentFunction(const InstructionT &I);
0074 static bool isConvergent(const InstructionT &I);
0075 static ConvOpKind getConvOp(const InstructionT &I);
0076 void checkConvergenceTokenProduced(const InstructionT &I);
0077 const InstructionT *findAndCheckConvergenceTokenUsed(const InstructionT &I);
0078
0079 void reportFailure(const Twine &Message, ArrayRef<Printable> Values);
0080 };
0081
0082 }
0083
0084 #endif