xref: /freebsd-src/contrib/llvm-project/llvm/lib/IR/ConvergenceVerifier.cpp (revision 5f757f3ff9144b609b3c433dfd370cc6bdc191ad)
1*5f757f3fSDimitry Andric //===- ConvergenceVerifier.cpp - Verify convergence control -----*- C++ -*-===//
2*5f757f3fSDimitry Andric //
3*5f757f3fSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*5f757f3fSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*5f757f3fSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*5f757f3fSDimitry Andric //
7*5f757f3fSDimitry Andric //===----------------------------------------------------------------------===//
8*5f757f3fSDimitry Andric 
9*5f757f3fSDimitry Andric #include "llvm/IR/ConvergenceVerifier.h"
10*5f757f3fSDimitry Andric #include "llvm/IR/Dominators.h"
11*5f757f3fSDimitry Andric #include "llvm/IR/GenericConvergenceVerifierImpl.h"
12*5f757f3fSDimitry Andric #include "llvm/IR/Instructions.h"
13*5f757f3fSDimitry Andric #include "llvm/IR/SSAContext.h"
14*5f757f3fSDimitry Andric 
15*5f757f3fSDimitry Andric using namespace llvm;
16*5f757f3fSDimitry Andric 
17*5f757f3fSDimitry Andric template <>
18*5f757f3fSDimitry Andric const Instruction *
19*5f757f3fSDimitry Andric GenericConvergenceVerifier<SSAContext>::findAndCheckConvergenceTokenUsed(
20*5f757f3fSDimitry Andric     const Instruction &I) {
21*5f757f3fSDimitry Andric   auto *CB = dyn_cast<CallBase>(&I);
22*5f757f3fSDimitry Andric   if (!CB)
23*5f757f3fSDimitry Andric     return nullptr;
24*5f757f3fSDimitry Andric 
25*5f757f3fSDimitry Andric   unsigned Count =
26*5f757f3fSDimitry Andric       CB->countOperandBundlesOfType(LLVMContext::OB_convergencectrl);
27*5f757f3fSDimitry Andric   CheckOrNull(Count <= 1,
28*5f757f3fSDimitry Andric               "The 'convergencectrl' bundle can occur at most once on a call",
29*5f757f3fSDimitry Andric               {Context.print(CB)});
30*5f757f3fSDimitry Andric   if (!Count)
31*5f757f3fSDimitry Andric     return nullptr;
32*5f757f3fSDimitry Andric 
33*5f757f3fSDimitry Andric   auto Bundle = CB->getOperandBundle(LLVMContext::OB_convergencectrl);
34*5f757f3fSDimitry Andric   CheckOrNull(Bundle->Inputs.size() == 1 &&
35*5f757f3fSDimitry Andric                   Bundle->Inputs[0]->getType()->isTokenTy(),
36*5f757f3fSDimitry Andric               "The 'convergencectrl' bundle requires exactly one token use.",
37*5f757f3fSDimitry Andric               {Context.print(CB)});
38*5f757f3fSDimitry Andric   auto *Token = Bundle->Inputs[0].get();
39*5f757f3fSDimitry Andric   auto *Def = dyn_cast<Instruction>(Token);
40*5f757f3fSDimitry Andric 
41*5f757f3fSDimitry Andric   CheckOrNull(
42*5f757f3fSDimitry Andric       Def && isConvergenceControlIntrinsic(SSAContext::getIntrinsicID(*Def)),
43*5f757f3fSDimitry Andric       "Convergence control tokens can only be produced by calls to the "
44*5f757f3fSDimitry Andric       "convergence control intrinsics.",
45*5f757f3fSDimitry Andric       {Context.print(Token), Context.print(&I)});
46*5f757f3fSDimitry Andric 
47*5f757f3fSDimitry Andric   if (Def)
48*5f757f3fSDimitry Andric     Tokens[&I] = Def;
49*5f757f3fSDimitry Andric 
50*5f757f3fSDimitry Andric   return Def;
51*5f757f3fSDimitry Andric }
52*5f757f3fSDimitry Andric 
53*5f757f3fSDimitry Andric template <>
54*5f757f3fSDimitry Andric bool GenericConvergenceVerifier<SSAContext>::isInsideConvergentFunction(
55*5f757f3fSDimitry Andric     const InstructionT &I) {
56*5f757f3fSDimitry Andric   auto *F = I.getFunction();
57*5f757f3fSDimitry Andric   return F->isConvergent();
58*5f757f3fSDimitry Andric }
59*5f757f3fSDimitry Andric 
60*5f757f3fSDimitry Andric template <>
61*5f757f3fSDimitry Andric bool GenericConvergenceVerifier<SSAContext>::isConvergent(
62*5f757f3fSDimitry Andric     const InstructionT &I) {
63*5f757f3fSDimitry Andric   if (auto *CB = dyn_cast<CallBase>(&I)) {
64*5f757f3fSDimitry Andric     return CB->isConvergent();
65*5f757f3fSDimitry Andric   }
66*5f757f3fSDimitry Andric   return false;
67*5f757f3fSDimitry Andric }
68*5f757f3fSDimitry Andric 
69*5f757f3fSDimitry Andric template class llvm::GenericConvergenceVerifier<SSAContext>;
70