Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:43:05

0001 //===- GenericConvergenceVerifier.h ---------------------------*- C++ -*---===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 ///
0009 /// \file
0010 ///
0011 /// A verifier for the static rules of convergence control tokens that works
0012 /// with both LLVM IR and MIR.
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   /// Whether the current function has convergencectrl operand bundles.
0057   enum {
0058     ControlledConvergence,
0059     UncontrolledConvergence,
0060     NoConvergence
0061   } ConvergenceKind = NoConvergence;
0062 
0063   /// The control token operation performed by a convergence control Intrinsic
0064   /// in LLVM IR, or by a CONVERGENCECTRL* instruction in MIR
0065   enum ConvOpKind { CONV_ANCHOR, CONV_ENTRY, CONV_LOOP, CONV_NONE };
0066 
0067   // Cache token uses found so far. Note that we track the unique definitions
0068   // and not the token values.
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 } // end namespace llvm
0083 
0084 #endif // LLVM_ADT_GENERICCONVERGENCEVERIFIER_H