Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/IR/ConvergenceVerifier.cpp
35233 views
1
//===- ConvergenceVerifier.cpp - Verify convergence control -----*- C++ -*-===//
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
#include "llvm/IR/ConvergenceVerifier.h"
10
#include "llvm/IR/Dominators.h"
11
#include "llvm/IR/GenericConvergenceVerifierImpl.h"
12
#include "llvm/IR/Instructions.h"
13
#include "llvm/IR/SSAContext.h"
14
15
using namespace llvm;
16
17
template <>
18
auto GenericConvergenceVerifier<SSAContext>::getConvOp(const Instruction &I)
19
-> ConvOpKind {
20
const auto *CB = dyn_cast<CallBase>(&I);
21
if (!CB)
22
return CONV_NONE;
23
switch (CB->getIntrinsicID()) {
24
default:
25
return CONV_NONE;
26
case Intrinsic::experimental_convergence_anchor:
27
return CONV_ANCHOR;
28
case Intrinsic::experimental_convergence_entry:
29
return CONV_ENTRY;
30
case Intrinsic::experimental_convergence_loop:
31
return CONV_LOOP;
32
}
33
}
34
35
template <>
36
void GenericConvergenceVerifier<SSAContext>::checkConvergenceTokenProduced(
37
const Instruction &I) {
38
return;
39
}
40
41
template <>
42
const Instruction *
43
GenericConvergenceVerifier<SSAContext>::findAndCheckConvergenceTokenUsed(
44
const Instruction &I) {
45
auto *CB = dyn_cast<CallBase>(&I);
46
if (!CB)
47
return nullptr;
48
49
unsigned Count =
50
CB->countOperandBundlesOfType(LLVMContext::OB_convergencectrl);
51
CheckOrNull(Count <= 1,
52
"The 'convergencectrl' bundle can occur at most once on a call",
53
{Context.print(CB)});
54
if (!Count)
55
return nullptr;
56
57
auto Bundle = CB->getOperandBundle(LLVMContext::OB_convergencectrl);
58
CheckOrNull(Bundle->Inputs.size() == 1 &&
59
Bundle->Inputs[0]->getType()->isTokenTy(),
60
"The 'convergencectrl' bundle requires exactly one token use.",
61
{Context.print(CB)});
62
auto *Token = Bundle->Inputs[0].get();
63
auto *Def = dyn_cast<Instruction>(Token);
64
65
CheckOrNull(Def && getConvOp(*Def) != CONV_NONE,
66
"Convergence control tokens can only be produced by calls to the "
67
"convergence control intrinsics.",
68
{Context.print(Token), Context.print(&I)});
69
70
if (Def)
71
Tokens[&I] = Def;
72
73
return Def;
74
}
75
76
template <>
77
bool GenericConvergenceVerifier<SSAContext>::isInsideConvergentFunction(
78
const Instruction &I) {
79
auto *F = I.getFunction();
80
return F->isConvergent();
81
}
82
83
template <>
84
bool GenericConvergenceVerifier<SSAContext>::isConvergent(
85
const Instruction &I) {
86
if (auto *CB = dyn_cast<CallBase>(&I)) {
87
return CB->isConvergent();
88
}
89
return false;
90
}
91
92
template class llvm::GenericConvergenceVerifier<SSAContext>;
93
94